CCache: Difference between revisions
imported>Milahu use sandbox-paths |
Not related to NixOS, read https://ccache.dev/manual/4.8.2.html#_cache_statistics and run ccache -vs |
||
(7 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
CCache is useful for [[Packaging]] large packages with [[Incremental builds]]. | |||
With CCache, recompile time can be reduced from many hours to a few minutes. | |||
== | == NixOS == | ||
On NixOS, the <code>programs.ccache</code> module can be used to partially enable CCache. | |||
<syntaxhighlight lang="nix"> | |||
programs.ccache.enable = true; | |||
</syntaxhighlight> | |||
However, without specifying <code>programs.ccache.packageNames</code> the CCache wrapper is not configured. The wrapper configuration can be added to your Nix overlays. | |||
<syntaxhighlight lang="nix"> | |||
nixpkgs.overlays = [ | |||
(self: super: { | |||
ccacheWrapper = super.ccacheWrapper.override { | |||
extraConfig = '' | |||
export CCACHE_COMPRESS=1 | |||
export CCACHE_DIR="${config.programs.ccache.cacheDir}" | |||
export CCACHE_UMASK=007 | |||
if [ ! -d "$CCACHE_DIR" ]; then | |||
echo "=====" | |||
echo "Directory '$CCACHE_DIR' does not exist" | |||
echo "Please create it with:" | |||
echo " sudo mkdir -m0770 '$CCACHE_DIR'" | |||
echo " sudo chown root:nixbld '$CCACHE_DIR'" | |||
echo "=====" | |||
exit 1 | |||
fi | |||
if [ ! -w "$CCACHE_DIR" ]; then | |||
echo "=====" | |||
echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)" | |||
echo "Please verify its access permissions" | |||
echo "=====" | |||
exit 1 | |||
fi | |||
''; | |||
}; | |||
}) | |||
]; | |||
</syntaxhighlight> | |||
The CCache directory also needs to be added to the builder sandboxes. | |||
<syntaxhighlight lang="nix"> | |||
nix.settings.extra-sandbox-paths = [ config.programs.ccache.cacheDir ]; | |||
</syntaxhighlight> | |||
Run <code>sudo nixos-rebuild switch</code> to enable these options before attempting to use CCache for a derivation. | |||
=== Derivation CCache === | |||
Packages can built with CCache by overriding <code>stdenv</code> in the derivation. | |||
<syntaxhighlight lang="nix"> | |||
nixpkgs.overlays = [ | |||
(self: super: { | |||
ffmpeg = super.ffmpeg.override { stdenv = super.ccacheStdenv; }; | |||
}) | |||
]; | |||
</syntaxhighlight> | |||
Some packages do not use <code>stdenv</code> directly. You may need to plumb it through other dependencies first. | |||
Note, that if the package is a top-level package, you may instead add it to the <code>programs.ccache.packageNames</code> list. | |||
<syntaxhighlight lang="nix"> | |||
programs.ccache.packageNames = [ "ffmpeg" ]; | |||
</syntaxhighlight> | |||
=== System CCache === | |||
todo | |||
=== Monitor CCache === | |||
The NixOS module creates a script that can be used to monitor the CCache directory without sudo. | |||
<pre> | <pre> | ||
nix-ccache --show-stats | |||
</pre> | </pre> | ||
== Non-NixOS == | |||
Create the cache folder: | |||
<pre> | <pre> | ||
Line 31: | Line 95: | ||
</pre> | </pre> | ||
Add the path to the derivation sandbox by adding <code>extra-sandbox-paths</code> to <code>nix.conf</code> | |||
to | |||
<pre> | <pre> | ||
extra-sandbox-paths = /nix/var/cache/ccache | |||
</pre> | |||
Then configure the CCache wrapper script. | |||
<syntaxhighlight lang="nix"> | |||
</ | nixpkgs.overlays = [ | ||
(self: super: { | |||
ccacheWrapper = super.ccacheWrapper.override { | |||
extraConfig = '' | |||
export CCACHE_COMPRESS=1 | |||
export CCACHE_DIR="/nix/var/cache/ccache" | |||
export CCACHE_UMASK=007 | |||
if [ ! -d "$CCACHE_DIR" ]; then | |||
echo "=====" | |||
echo "Directory '$CCACHE_DIR' does not exist" | |||
echo "Please create it with:" | |||
echo " sudo mkdir -m0770 '$CCACHE_DIR'" | |||
echo " sudo chown root:nixbld '$CCACHE_DIR'" | |||
echo "=====" | |||
exit 1 | |||
fi | |||
if [ ! -w "$CCACHE_DIR" ]; then | |||
echo "=====" | |||
echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)" | |||
echo "Please verify its access permissions" | |||
echo "=====" | |||
exit 1 | |||
fi | |||
''; | |||
}; | |||
}) | |||
]; | |||
</syntaxhighlight> | |||
=== Derivation CCache === | |||
Packages can built with CCache by overriding <code>stdenv</code> in the derivation. | |||
<syntaxhighlight lang="nix"> | |||
nixpkgs.overlays = [ | |||
(self: super: { | |||
ffmpeg = super.ffmpeg.override { stdenv = super.ccacheStdenv; }; | |||
}) | |||
]; | |||
</syntaxhighlight> | |||
Some packages do not use <code>stdenv</code> directly. You may need to plumb it through other dependencies first. | |||
=== Monitor CCache status === | |||
== | |||
<pre> | <pre> | ||
Line 69: | Line 153: | ||
# watch ccache stats | # watch ccache stats | ||
sudo watch ccache --dir /nix/var/cache/ccache --show-stats | sudo watch ccache --dir /nix/var/cache/ccache --show-stats | ||
</pre> | </pre> | ||
== | == Sloppiness == | ||
By default, <code>stdenv</code> inserts <code>-frandom-seed</code> C compiler flag with a value that changes whenever the derivation hash has changed. | |||
Consequently, this behavior completely defeats any usage of <code>ccacheWrapper</code> | |||
To counterpart this behavior, add the following line to the ccache config (typically <code>/var/cache/ccache/ccache.conf</code>): | |||
<pre> | |||
sloppiness = random_seed | |||
</pre> | |||
Be warned that this configuration option might affect reproducibility of builds, and could lead to cache poisoning. | |||
See [https://github.com/NixOS/nixpkgs/issues/109033 issue 109033] for more details. | |||
== See also == | |||
* https://leanprover.github.io/lean4/doc/make/nix.html | * https://leanprover.github.io/lean4/doc/make/nix.html | ||
* [https://nixos.org/manual/nix/stable/command-ref/conf-file.html sandbox-paths in nix.conf] | * [https://nixos.org/manual/nix/stable/command-ref/conf-file.html sandbox-paths in nix.conf] | ||
[[Category: Development]] |
Latest revision as of 16:02, 18 June 2024
CCache is useful for Packaging large packages with Incremental builds.
With CCache, recompile time can be reduced from many hours to a few minutes.
NixOS
On NixOS, the programs.ccache
module can be used to partially enable CCache.
programs.ccache.enable = true;
However, without specifying programs.ccache.packageNames
the CCache wrapper is not configured. The wrapper configuration can be added to your Nix overlays.
nixpkgs.overlays = [
(self: super: {
ccacheWrapper = super.ccacheWrapper.override {
extraConfig = ''
export CCACHE_COMPRESS=1
export CCACHE_DIR="${config.programs.ccache.cacheDir}"
export CCACHE_UMASK=007
if [ ! -d "$CCACHE_DIR" ]; then
echo "====="
echo "Directory '$CCACHE_DIR' does not exist"
echo "Please create it with:"
echo " sudo mkdir -m0770 '$CCACHE_DIR'"
echo " sudo chown root:nixbld '$CCACHE_DIR'"
echo "====="
exit 1
fi
if [ ! -w "$CCACHE_DIR" ]; then
echo "====="
echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)"
echo "Please verify its access permissions"
echo "====="
exit 1
fi
'';
};
})
];
The CCache directory also needs to be added to the builder sandboxes.
nix.settings.extra-sandbox-paths = [ config.programs.ccache.cacheDir ];
Run sudo nixos-rebuild switch
to enable these options before attempting to use CCache for a derivation.
Derivation CCache
Packages can built with CCache by overriding stdenv
in the derivation.
nixpkgs.overlays = [
(self: super: {
ffmpeg = super.ffmpeg.override { stdenv = super.ccacheStdenv; };
})
];
Some packages do not use stdenv
directly. You may need to plumb it through other dependencies first.
Note, that if the package is a top-level package, you may instead add it to the programs.ccache.packageNames
list.
programs.ccache.packageNames = [ "ffmpeg" ];
System CCache
todo
Monitor CCache
The NixOS module creates a script that can be used to monitor the CCache directory without sudo.
nix-ccache --show-stats
Non-NixOS
Create the cache folder:
sudo mkdir -m0770 -p /nix/var/cache/ccache # Linux sudo chown --reference=/nix/store /nix/var/cache/ccache # macOS workaround for chown --reference nix-shell -p coreutils --run 'sudo chown --reference=/nix/store /nix/var/cache/ccache'
Add the path to the derivation sandbox by adding extra-sandbox-paths
to nix.conf
extra-sandbox-paths = /nix/var/cache/ccache
Then configure the CCache wrapper script.
nixpkgs.overlays = [
(self: super: {
ccacheWrapper = super.ccacheWrapper.override {
extraConfig = ''
export CCACHE_COMPRESS=1
export CCACHE_DIR="/nix/var/cache/ccache"
export CCACHE_UMASK=007
if [ ! -d "$CCACHE_DIR" ]; then
echo "====="
echo "Directory '$CCACHE_DIR' does not exist"
echo "Please create it with:"
echo " sudo mkdir -m0770 '$CCACHE_DIR'"
echo " sudo chown root:nixbld '$CCACHE_DIR'"
echo "====="
exit 1
fi
if [ ! -w "$CCACHE_DIR" ]; then
echo "====="
echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)"
echo "Please verify its access permissions"
echo "====="
exit 1
fi
'';
};
})
];
Derivation CCache
Packages can built with CCache by overriding stdenv
in the derivation.
nixpkgs.overlays = [
(self: super: {
ffmpeg = super.ffmpeg.override { stdenv = super.ccacheStdenv; };
})
];
Some packages do not use stdenv
directly. You may need to plumb it through other dependencies first.
Monitor CCache status
# watch ccache size sudo watch du -sh /nix/var/cache/ccache # watch ccache stats sudo watch ccache --dir /nix/var/cache/ccache --show-stats
Sloppiness
By default, stdenv
inserts -frandom-seed
C compiler flag with a value that changes whenever the derivation hash has changed.
Consequently, this behavior completely defeats any usage of ccacheWrapper
To counterpart this behavior, add the following line to the ccache config (typically /var/cache/ccache/ccache.conf
):
sloppiness = random_seed
Be warned that this configuration option might affect reproducibility of builds, and could lead to cache poisoning. See issue 109033 for more details.