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