diff mbox series

[OpenWrt-Devel] build: improve ccache support

Message ID 20200601153226.15229-1-roman@advem.lv
State Changes Requested
Delegated to: Petr Štetiar
Headers show
Series [OpenWrt-Devel] build: improve ccache support | expand

Commit Message

Roman Yeryomin June 1, 2020, 3:32 p.m. UTC
Set CCACHE_DIR to $(TOPDIR)/.ccache and CCACHE_BASEDIR to $(TOPDIR).
This allows to do clean and dirclean. Cache hit rate for test build
after dirclean is ~65%.
If CCACHE is enabled stats are printed out at the end of building process.

Signed-off-by: Roman Yeryomin <roman@advem.lv>
---
 .gitignore            | 1 +
 Makefile              | 3 +++
 include/host-build.mk | 4 +++-
 include/package.mk    | 4 +++-
 include/toplevel.mk   | 1 +
 rules.mk              | 3 +++
 6 files changed, 14 insertions(+), 2 deletions(-)

Comments

Michael Jones June 1, 2020, 5:11 p.m. UTC | #1
On Mon, Jun 1, 2020 at 10:33 AM Roman Yeryomin <roman@advem.lv> wrote:

> Set CCACHE_DIR to $(TOPDIR)/.ccache and CCACHE_BASEDIR to $(TOPDIR).
> This allows to do clean and dirclean. Cache hit rate for test build
> after dirclean is ~65%.
> If CCACHE is enabled stats are printed out at the end of building process.
>
> Signed-off-by: Roman Yeryomin <roman@advem.lv>
>

This certainly looks like an improvement.

However, there is an important usage case that this change doesn't address.

Frequently when I am working on OpenWRT related things, I have many
different workspaces all tied to the same git repository hosted externally.
The reason for this is to allow multiple builds to live and run
independently.

Having the CCACHE_DIR be located *inside* the repository doesn't share the
cache between multiple workspaces.

So can the CCACHE_DIR be made configurable at build time based on the
.config file? Perhaps it can default to this, and only be set to the value
in .config if provided? For my purposes, I would always set the CCACHE_DIR
to a path that all of my workspaces use.
Felix Fietkau June 1, 2020, 6:22 p.m. UTC | #2
On 2020-06-01 19:11, Michael Jones wrote:
> 
> 
> On Mon, Jun 1, 2020 at 10:33 AM Roman Yeryomin <roman@advem.lv
> <mailto:roman@advem.lv>> wrote:
> 
>     Set CCACHE_DIR to $(TOPDIR)/.ccache and CCACHE_BASEDIR to $(TOPDIR).
>     This allows to do clean and dirclean. Cache hit rate for test build
>     after dirclean is ~65%.
>     If CCACHE is enabled stats are printed out at the end of building
>     process.
> 
>     Signed-off-by: Roman Yeryomin <roman@advem.lv <mailto:roman@advem.lv>>
> 
> 
> This certainly looks like an improvement.
> 
> However, there is an important usage case that this change doesn't address.
> 
> Frequently when I am working on OpenWRT related things, I have many
> different workspaces all tied to the same git repository hosted
> externally. The reason for this is to allow multiple builds to live and
> run independently.
> 
> Having the CCACHE_DIR be located *inside* the repository doesn't share
> the cache between multiple workspaces.
> 
> So can the CCACHE_DIR be made configurable at build time based on the
> .config file? Perhaps it can default to this, and only be set to the
> value in .config if provided? For my purposes, I would always set the
> CCACHE_DIR to a path that all of my workspaces use.
I don't think there's a need for that config option. You could simply
add a .ccache symlink in your source dir and point it to your shared
cache. I do the same with dl on my trees.

- Felix
Michael Jones June 1, 2020, 6:34 p.m. UTC | #3
On Mon, Jun 1, 2020 at 1:22 PM Felix Fietkau <nbd@nbd.name> wrote:

> On 2020-06-01 19:11, Michael Jones wrote:
> >
> >
> > On Mon, Jun 1, 2020 at 10:33 AM Roman Yeryomin <roman@advem.lv
> > <mailto:roman@advem.lv>> wrote:
> >
> >     Set CCACHE_DIR to $(TOPDIR)/.ccache and CCACHE_BASEDIR to $(TOPDIR).
> >     This allows to do clean and dirclean. Cache hit rate for test build
> >     after dirclean is ~65%.
> >     If CCACHE is enabled stats are printed out at the end of building
> >     process.
> >
> >     Signed-off-by: Roman Yeryomin <roman@advem.lv <mailto:roman@advem.lv
> >>
> >
> >
> > This certainly looks like an improvement.
> >
> > However, there is an important usage case that this change doesn't
> address.
> >
> > Frequently when I am working on OpenWRT related things, I have many
> > different workspaces all tied to the same git repository hosted
> > externally. The reason for this is to allow multiple builds to live and
> > run independently.
> >
> > Having the CCACHE_DIR be located *inside* the repository doesn't share
> > the cache between multiple workspaces.
> >
> > So can the CCACHE_DIR be made configurable at build time based on the
> > .config file? Perhaps it can default to this, and only be set to the
> > value in .config if provided? For my purposes, I would always set the
> > CCACHE_DIR to a path that all of my workspaces use.
> I don't think there's a need for that config option. You could simply
> add a .ccache symlink in your source dir and point it to your shared
> cache. I do the same with dl on my trees.
>
> - Felix
>

I disagree.

Having build behavior change based on a symlink is undesirable.

If it were a config option, it becomes a documented feature that is easily
discoverable in the menu config.

Additionally, having the ccache directory be a configuration option allows
it to persist across clones of the git repository, if the .config file is
stored in git. A symlink would need to be manually re-configured on each
clone.
Roman Yeryomin June 2, 2020, 12:21 p.m. UTC | #4
On 2020-06-01 21:34, Michael Jones wrote:
> On Mon, Jun 1, 2020 at 1:22 PM Felix Fietkau <nbd@nbd.name> wrote:
> 
>> On 2020-06-01 19:11, Michael Jones wrote:
>> >
>> >
>> > On Mon, Jun 1, 2020 at 10:33 AM Roman Yeryomin <roman@advem.lv
>> > <mailto:roman@advem.lv>> wrote:
>> >
>> >     Set CCACHE_DIR to $(TOPDIR)/.ccache and CCACHE_BASEDIR to $(TOPDIR).
>> >     This allows to do clean and dirclean. Cache hit rate for test build
>> >     after dirclean is ~65%.
>> >     If CCACHE is enabled stats are printed out at the end of building
>> >     process.
>> >
>> >     Signed-off-by: Roman Yeryomin <roman@advem.lv <mailto:roman@advem.lv
>> >>
>> >
>> >
>> > This certainly looks like an improvement.
>> >
>> > However, there is an important usage case that this change doesn't
>> address.
>> >
>> > Frequently when I am working on OpenWRT related things, I have many
>> > different workspaces all tied to the same git repository hosted
>> > externally. The reason for this is to allow multiple builds to live and
>> > run independently.
>> >
>> > Having the CCACHE_DIR be located *inside* the repository doesn't share
>> > the cache between multiple workspaces.
>> >
>> > So can the CCACHE_DIR be made configurable at build time based on the
>> > .config file? Perhaps it can default to this, and only be set to the
>> > value in .config if provided? For my purposes, I would always set the
>> > CCACHE_DIR to a path that all of my workspaces use.
>> I don't think there's a need for that config option. You could simply
>> add a .ccache symlink in your source dir and point it to your shared
>> cache. I do the same with dl on my trees.
>> 
>> - Felix
>> 
> 
> I disagree.
> 
> Having build behavior change based on a symlink is undesirable.
> 
> If it were a config option, it becomes a documented feature that is 
> easily
> discoverable in the menu config.
> 
> Additionally, having the ccache directory be a configuration option 
> allows
> it to persist across clones of the git repository, if the .config file 
> is
> stored in git. A symlink would need to be manually re-configured on 
> each
> clone.

I agree with Felix. Having one ccache directory for multiple repos 
doesn't make much sense to me as most probably they are for different 
platforms. And even if they are for same platform there are more chances 
for ccache corruption and deleting it will affect all those repos. So it 
still can be done with symlink but IMO should be done manually to make 
sure you know what you are doing.
Also BASEDIR should be changed too, probably, if we want to go that way.

Regards,
Roman
Michael Jones June 4, 2020, 7:29 p.m. UTC | #5
> I agree with Felix. Having one ccache directory for multiple repos
> doesn't make much sense to me as most probably they are for different
> platforms. And even if they are for same platform there are more chances
> for ccache corruption and deleting it will affect all those repos. So it
> still can be done with symlink but IMO should be done manually to make
> sure you know what you are doing.
> Also BASEDIR should be changed too, probably, if we want to go that way.
>
>
I am already using a shared ccache directory for multiple builds in my
continuous integration system. I'm accomplishing this by patching the build
system to change the directory for the ccache directory.

If it were a .config option, your use-case would be directly supported, as
well as my use-case, without as much custom patching.

I imagine that there are plenty of other organizations which would use the
.config based functionality to customize things to their liking.

If ccache is corrupted there are much larger problems than slowing down
other builds.
Roman Yeryomin June 12, 2020, 7 p.m. UTC | #6
On 2020-06-04 22:29, Michael Jones wrote:
>> I agree with Felix. Having one ccache directory for multiple repos
>> doesn't make much sense to me as most probably they are for different
>> platforms. And even if they are for same platform there are more 
>> chances
>> for ccache corruption and deleting it will affect all those repos. So 
>> it
>> still can be done with symlink but IMO should be done manually to make
>> sure you know what you are doing.
>> Also BASEDIR should be changed too, probably, if we want to go that 
>> way.
>> 
>> 
> I am already using a shared ccache directory for multiple builds in my
> continuous integration system. I'm accomplishing this by patching the 
> build
> system to change the directory for the ccache directory.
> 
> If it were a .config option, your use-case would be directly supported, 
> as
> well as my use-case, without as much custom patching.
> 
> I imagine that there are plenty of other organizations which would use 
> the
> .config based functionality to customize things to their liking.
> 
> If ccache is corrupted there are much larger problems than slowing down
> other builds.

Please see v2

Regards,
Roman
diff mbox series

Patch

diff --git a/.gitignore b/.gitignore
index 6549af83be..b6bfe1a525 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,4 @@  TAGS*~
 git-src
 .project
 .cproject
+.ccache
diff --git a/Makefile b/Makefile
index 32c050bb48..dfeaf83e2c 100644
--- a/Makefile
+++ b/Makefile
@@ -119,6 +119,9 @@  world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-
 	$(_SINGLE)$(SUBMAKE) -r package/index
 	$(_SINGLE)$(SUBMAKE) -r json_overview_image_info
 	$(_SINGLE)$(SUBMAKE) -r checksum
+ifneq ($(CONFIG_CCACHE),)
+	$(STAGING_DIR_HOST)/bin/ccache -s
+endif
 
 .PHONY: clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean
 
diff --git a/include/host-build.mk b/include/host-build.mk
index 9fc14241c6..4adac0883e 100644
--- a/include/host-build.mk
+++ b/include/host-build.mk
@@ -132,7 +132,9 @@  define Host/Exports/Default
   $(1) : export STAGING_PREFIX=$$(HOST_BUILD_PREFIX)
   $(1) : export PKG_CONFIG_PATH=$$(STAGING_DIR_HOST)/lib/pkgconfig:$$(HOST_BUILD_PREFIX)/lib/pkgconfig
   $(1) : export PKG_CONFIG_LIBDIR=$$(HOST_BUILD_PREFIX)/lib/pkgconfig
-  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_DIR:=$(STAGING_DIR_HOST)/ccache)
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_BASEDIR:=$(TOPDIR))
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_DIR:=$(TOPDIR)/.ccache)
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_COMPILERCHECK:=%compiler% -dumpmachine; %compiler% -dumpversion)
   $(if $(HOST_CONFIG_SITE),$(1) : export CONFIG_SITE:=$(HOST_CONFIG_SITE))
   $(if $(IS_PACKAGE_BUILD),$(1) : export PATH=$$(TARGET_PATH_PKG))
 endef
diff --git a/include/package.mk b/include/package.mk
index 0575692742..eee5bbbf80 100644
--- a/include/package.mk
+++ b/include/package.mk
@@ -173,7 +173,9 @@  define Build/Exports/Default
   $(1) : export CONFIG_SITE:=$$(CONFIG_SITE)
   $(1) : export PKG_CONFIG_PATH:=$$(PKG_CONFIG_PATH)
   $(1) : export PKG_CONFIG_LIBDIR:=$$(PKG_CONFIG_PATH)
-  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_DIR:=$(STAGING_DIR)/ccache)
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_BASEDIR:=$(TOPDIR))
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_DIR:=$(TOPDIR)/.ccache)
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_COMPILERCHECK:=%compiler% -dumpmachine; %compiler% -dumpversion)
 endef
 Build/Exports=$(Build/Exports/Default)
 
diff --git a/include/toplevel.mk b/include/toplevel.mk
index 5cf93ce7ef..f4a9dccd5e 100644
--- a/include/toplevel.mk
+++ b/include/toplevel.mk
@@ -253,6 +253,7 @@  help:
 
 distclean:
 	rm -rf bin build_dir .config* dl feeds key-build* logs package/feeds package/openwrt-packages staging_dir tmp
+	rm -rf $(TOPDIR)/.ccache
 	@$(_SINGLE)$(SUBMAKE) -C scripts/config clean
 
 ifeq ($(findstring v,$(DEBUG)),)
diff --git a/rules.mk b/rules.mk
index 66ddea2883..fb2f6bf57f 100644
--- a/rules.mk
+++ b/rules.mk
@@ -298,6 +298,9 @@  ifneq ($(CONFIG_CCACHE),)
   TARGET_CXX:= ccache_cxx
   HOSTCC:= ccache $(HOSTCC)
   HOSTCXX:= ccache $(HOSTCXX)
+  export CCACHE_BASEDIR:=$(TOPDIR)
+  export CCACHE_DIR:=$(TOPDIR)/.ccache
+  export CCACHE_COMPILERCHECK:=%compiler% -dumpmachine; %compiler% -dumpversion
 endif
 
 TARGET_CONFIGURE_OPTS = \