1{ config, pkgs, lib, ... }:
2
3with lib;
4let
5 cfg = config.programs.ccache;
6in {
7 options.programs.ccache = {
8 # host configuration
9 enable = mkEnableOption "CCache";
10 cacheDir = mkOption {
11 type = types.path;
12 description = "CCache directory";
13 default = "/var/cache/ccache";
14 };
15 # target configuration
16 packageNames = mkOption {
17 type = types.listOf types.str;
18 description = "Nix top-level packages to be compiled using CCache";
19 default = [];
20 example = [ "wxGTK30" "qt48" "ffmpeg_3_3" "libav_all" ];
21 };
22 };
23
24 config = mkMerge [
25 # host configuration
26 (mkIf cfg.enable {
27 systemd.tmpfiles.rules = [ "d ${cfg.cacheDir} 0770 root nixbld -" ];
28
29 # "nix-ccache --show-stats" and "nix-ccache --clear"
30 security.wrappers.nix-ccache = {
31 group = "nixbld";
32 setgid = true;
33 source = pkgs.writeScript "nix-ccache.pl" ''
34 #!${pkgs.perl}/bin/perl
35
36 %ENV=( CCACHE_DIR => '${cfg.cacheDir}' );
37 sub untaint {
38 my $v = shift;
39 return '-C' if $v eq '-C' || $v eq '--clear';
40 return '-V' if $v eq '-V' || $v eq '--version';
41 return '-s' if $v eq '-s' || $v eq '--show-stats';
42 return '-z' if $v eq '-z' || $v eq '--zero-stats';
43 exec('${pkgs.ccache}/bin/ccache', '-h');
44 }
45 exec('${pkgs.ccache}/bin/ccache', map { untaint $_ } @ARGV);
46 '';
47 };
48 })
49
50 # target configuration
51 (mkIf (cfg.packageNames != []) {
52 nixpkgs.overlays = [
53 (self: super: genAttrs cfg.packageNames (pn: super.${pn}.override { stdenv = builtins.trace "with ccache: ${pn}" self.ccacheStdenv; }))
54
55 (self: super: {
56 ccacheWrapper = super.ccacheWrapper.override {
57 extraConfig = ''
58 export CCACHE_COMPRESS=1
59 export CCACHE_DIR="${cfg.cacheDir}"
60 export CCACHE_UMASK=007
61 if [ ! -d "$CCACHE_DIR" ]; then
62 echo "====="
63 echo "Directory '$CCACHE_DIR' does not exist"
64 echo "Please create it with:"
65 echo " sudo mkdir -m0770 '$CCACHE_DIR'"
66 echo " sudo chown root:nixbld '$CCACHE_DIR'"
67 echo "====="
68 exit 1
69 fi
70 if [ ! -w "$CCACHE_DIR" ]; then
71 echo "====="
72 echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)"
73 echo "Please verify its access permissions"
74 echo "====="
75 exit 1
76 fi
77 '';
78 };
79 })
80 ];
81 })
82 ];
83}