diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 629c8c1bc5bb..405dc3823d52 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -71,6 +71,7 @@ ./programs/bcc.nix ./programs/blcr.nix ./programs/browserpass.nix + ./programs/ccache.nix ./programs/cdemu.nix ./programs/chromium.nix ./programs/command-not-found/command-not-found.nix diff --git a/nixos/modules/programs/ccache.nix b/nixos/modules/programs/ccache.nix new file mode 100644 index 000000000000..874774c72b47 --- /dev/null +++ b/nixos/modules/programs/ccache.nix @@ -0,0 +1,83 @@ +{ config, pkgs, lib, ... }: + +with lib; +let + cfg = config.programs.ccache; +in { + options.programs.ccache = { + # host configuration + enable = mkEnableOption "CCache"; + cacheDir = mkOption { + type = types.path; + description = "CCache directory"; + default = "/var/cache/ccache"; + }; + # target configuration + packageNames = mkOption { + type = types.listOf types.str; + description = "Nix top-level packages to be compiled using CCache"; + default = []; + example = [ "wxGTK30" "qt48" "ffmpeg_3_3" "libav_all" ]; + }; + }; + + config = mkMerge [ + # host configuration + (mkIf cfg.enable { + systemd.tmpfiles.rules = [ "d ${cfg.cacheDir} 0770 root nixbld -" ]; + + # "nix-ccache --show-stats" and "nix-ccache --clear" + security.wrappers.nix-ccache = { + group = "nixbld"; + setgid = true; + source = pkgs.writeScript "nix-ccache.pl" '' + #!${pkgs.perl}/bin/perl + + %ENV=( CCACHE_DIR => '${cfg.cacheDir}' ); + sub untaint { + my $v = shift; + return '-C' if $v eq '-C' || $v eq '--clear'; + return '-V' if $v eq '-V' || $v eq '--version'; + return '-s' if $v eq '-s' || $v eq '--show-stats'; + return '-z' if $v eq '-z' || $v eq '--zero-stats'; + exec('${pkgs.ccache}/bin/ccache', '-h'); + } + exec('${pkgs.ccache}/bin/ccache', map { untaint $_ } @ARGV); + ''; + }; + }) + + # target configuration + (mkIf (cfg.packageNames != []) { + nixpkgs.overlays = [ + (self: super: genAttrs cfg.packageNames (pn: super.${pn}.override { stdenv = builtins.trace "with ccache: ${pn}" self.ccacheStdenv; })) + + (self: super: { + ccacheWrapper = super.ccacheWrapper.override { + extraConfig = '' + export CCACHE_COMPRESS=1 + export CCACHE_DIR="${cfg.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 + ''; + }; + }) + ]; + }) + ]; +} \ No newline at end of file