Jump to content

CCache: Difference between revisions

Not related to NixOS, read https://ccache.dev/manual/4.8.2.html#_cache_statistics and run ccache -vs
imported>Fufexan
(Capitalize, add category)
(Not related to NixOS, read https://ccache.dev/manual/4.8.2.html#_cache_statistics and run ccache -vs)
 
(5 intermediate revisions by 4 users not shown)
Line 3: Line 3:
With CCache, recompile time can be reduced from many hours to a few minutes.
With CCache, recompile time can be reduced from many hours to a few minutes.


== Add CCache to sandbox ==
== NixOS ==
On NixOS, the <code>programs.ccache</code> module can be used to partially enable CCache.


Add to <code>/etc/nixos/configuration.nix</code>
<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">
<syntaxhighlight lang="nix">
nix.extraOptions = ''
nixpkgs.overlays = [
   extra-sandbox-paths = /nix/var/cache/ccache
   (self: super: {
'';
    ffmpeg = super.ffmpeg.override { stdenv = super.ccacheStdenv; };
  })
];
</syntaxhighlight>
</syntaxhighlight>


TODO: use <code>nix.sandboxPaths</code>? [https://github.com/NixOS/nixpkgs/issues/153343]
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


Run <code>sudo nixos-rebuild switch</code>
=== Monitor CCache ===


Now <code>/etc/nix/nix.conf</code> should have <code>sandbox-paths = /nix/var/cache/ccache</code>
The NixOS module creates a script that can be used to monitor the CCache directory without sudo.


Ceate the cache folder
<pre>
nix-ccache --show-stats
</pre>
 
== Non-NixOS ==
 
Create the cache folder:


<pre>
<pre>
Line 31: Line 95:
</pre>
</pre>


== Derivation CCache ==
Add the path to the derivation sandbox by adding <code>extra-sandbox-paths</code> to <code>nix.conf</code>


To enable CCache only for one derivation, patch the <code>default.nix</code> file
<pre>
extra-sandbox-paths = /nix/var/cache/ccache
</pre>
 
Then configure the CCache wrapper script.


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ stdenv
nixpkgs.overlays = [
, ccacheStdenv
  (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>


#stdenv.mkDerivation {
=== Derivation CCache ===
ccacheStdenv.mkDerivation {
Packages can built with CCache by overriding <code>stdenv</code> in the derivation.


  preConfigure = ''
<syntaxhighlight lang="nix">
    export CCACHE_DIR=/nix/var/cache/ccache
nixpkgs.overlays = [
    export CCACHE_UMASK=007
   (self: super: {
   ''
    ffmpeg = super.ffmpeg.override { stdenv = super.ccacheStdenv; };
 
  })
# ...
];
</syntaxhighlight>
</syntaxhighlight>


Add <code>ccacheStdenv</code> to dependencies.
Some packages do not use <code>stdenv</code> directly. You may need to plumb it through other dependencies first.


Run <code>nix-build</code>.
=== Monitor CCache status ===
 
== System CCache ==
 
todo
 
== Monitor CCache status ==


<pre>
<pre>
Line 67: Line 153:


# watch ccache stats
# watch ccache stats
sudo watch ccache --dir /nix/var/cache/ccache --show-stats --verbose
sudo watch ccache --dir /nix/var/cache/ccache --show-stats
</pre>
</pre>


== Uncacheable ==
== 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>


TODO: why are some compilations "uncacheable" according to <code>ccache --show-stats</code>
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 ==
== See also ==
2

edits