From 8817f6cc8d3c8aee2390eeac1b24906c47e4d866 Mon Sep 17 00:00:00 2001 From: TheK0tYaRa Date: Thu, 26 Mar 2026 04:53:48 +0200 Subject: [PATCH] split sccache --- custom/override.nix | 372 ++---------------------------------------- custom/sccache.nix | 387 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 400 insertions(+), 359 deletions(-) create mode 100644 custom/sccache.nix diff --git a/custom/override.nix b/custom/override.nix index fd06c2d..4d8ecf2 100644 --- a/custom/override.nix +++ b/custom/override.nix @@ -1,28 +1,17 @@ final: prev: let winePkg = final.wineWow64Packages.full; - sandboxSccacheDir = "/var/cache/sccache/nix-builds/packages"; - # Toggle this to switch between shared socketed sccache and per-build daemon mode. - # Shared socketed mode still fails for sandboxed package builds; keep disabled. - useSocketedSccache = false; - sharedSccacheServerUds = "/run/sccache/server.sock"; - effectiveSccacheServerUds = if useSocketedSccache then sharedSccacheServerUds else null; - sccacheRuntimeModeSetup = '' - unset SCCACHE_NO_DAEMON - ${final.lib.optionalString (effectiveSccacheServerUds != null) '' - export SCCACHE_SERVER_UDS=${final.lib.escapeShellArg effectiveSccacheServerUds} - unset SCCACHE_IDLE_TIMEOUT - ''} - ${final.lib.optionalString (effectiveSccacheServerUds == null) '' - unset SCCACHE_SERVER_UDS - export SCCACHE_IDLE_TIMEOUT=0 - ''} - ''; - sharedSccacheConfig = final.writeText "sccache.conf" '' - [cache.disk] - dir = "${sandboxSccacheDir}" - size = "100G" - ''; + sccacheLib = import ./sccache.nix { inherit final prev; }; + inherit (sccacheLib) + sandboxSccacheDir + sharedSccacheConfig + sccacheRuntimeModeSetup + mkSccacheLauncher + mkBuildSccacheAttrs + mkCmakeSccacheAttrs + mkCmakeSccacheWithLlvmTargetAttrs + mkSccacheExtraConfig + ; versionBumpAttrs = oldVersion: version: attrs: if final.lib.versionOlder oldVersion version then attrs else { }; @@ -94,344 +83,9 @@ let fi done ''; - mkSccacheLauncher = - { - name, - sccacheDir ? null, - sccacheServerUds ? effectiveSccacheServerUds, - sccacheCacheSize ? "100G", - noDaemon ? false, - bypassIfCmakeLauncher ? false, - passthroughWrappedCompiler ? false, - extraSetup ? "", - }: - let - sccacheConfig = final.writeText "${name}-config" '' - [cache.disk] - dir = "${if sccacheDir != null then sccacheDir else sandboxSccacheDir}" - size = "${sccacheCacheSize}" - ''; - effectiveSccacheConfig = - if sccacheDir == null && sccacheCacheSize == "100G" then sharedSccacheConfig else sccacheConfig; - in - final.writeShellScriptBin name '' - is_cmake_derivation() { - case " ''${nativeBuildInputs:-} ''${propagatedNativeBuildInputs:-} " in - *"/cmake-"*) return 0 ;; - esac - - [ -n "''${cmakeFlags:-}" ] || [ -n "''${cmakeDir:-}" ] || [ -n "''${cmakeBuildType:-}" ] - } - - is_cmake_probe_invocation() { - local arg response_file - for arg in "$@"; do - case "$arg" in - *CMakeFiles/*CompilerId*|*CMakeFiles/CMakeTmp/*|*CMakeScratch/*) - return 0 - ;; - @*) - response_file="''${arg#@}" - if [ -f "$response_file" ] && grep -Eq 'CMakeFiles/.+CompilerId|CMakeFiles/CMakeTmp|CMakeScratch' "$response_file"; then - return 0 - fi - ;; - esac - done - - return 1 - } - - has_cmake_compiler_launcher() { - [ -n "''${CMAKE_C_COMPILER_LAUNCHER:-}" ] \ - || [ -n "''${CMAKE_CXX_COMPILER_LAUNCHER:-}" ] \ - || [ -n "''${CMAKE_Fortran_COMPILER_LAUNCHER:-}" ] \ - || [ -n "''${CMAKE_CUDA_COMPILER_LAUNCHER:-}" ] \ - || [ -n "''${CMAKE_HIP_COMPILER_LAUNCHER:-}" ] \ - || [ -n "''${CMAKE_OBJC_COMPILER_LAUNCHER:-}" ] \ - || [ -n "''${CMAKE_OBJCXX_COMPILER_LAUNCHER:-}" ] - } - - export SCCACHE_CONF=${final.lib.escapeShellArg effectiveSccacheConfig} - mkdir -p ${final.lib.escapeShellArg sandboxSccacheDir} - unset SCCACHE_START_SERVER - ${final.lib.optionalString noDaemon '' - export SCCACHE_NO_DAEMON=1 - unset SCCACHE_SERVER_UDS - ''} - ${final.lib.optionalString (!noDaemon && sccacheServerUds != null) '' - export SCCACHE_SERVER_UDS=${final.lib.escapeShellArg sccacheServerUds} - ''} - ${final.lib.optionalString (!noDaemon && sccacheServerUds == null) '' - unset SCCACHE_SERVER_UDS - unset SCCACHE_NO_DAEMON - ''} - ${extraSetup} - if [ "$#" -eq 0 ]; then - exit 0 - fi - if [ "''${1#-}" != "$1" ]; then - exec ${final.sccache}/bin/sccache "$@" - fi - - compiler="$1" - shift - - if [ "''${SCCACHE_WRAPPED_COMPILER_PASSTHROUGH:-}" = 1 ] \ - || { [ ${if bypassIfCmakeLauncher then "1" else "0"} -eq 1 ] && has_cmake_compiler_launcher; } \ - || { - is_cmake_derivation && is_cmake_probe_invocation "$@" - }; then - exec "$compiler" "$@" - fi - - ${final.lib.optionalString passthroughWrappedCompiler '' - export SCCACHE_WRAPPED_COMPILER_PASSTHROUGH=1 - ''} - exec ${final.sccache}/bin/sccache "$compiler" "$@" - ''; - buildSccacheLauncher = mkSccacheLauncher { - name = "build-sccache"; - }; - mkBuildSccacheAttrs = old: { - nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ buildSccacheLauncher ]; - - preConfigure = (old.preConfigure or "") + '' - - mkdir -p ${final.lib.escapeShellArg sandboxSccacheDir} - ${sccacheRuntimeModeSetup} - ''; - - postBuild = (old.postBuild or "") + '' - - ${buildSccacheLauncher}/bin/build-sccache --show-stats --stats-format text || true - ''; - }; - mkCmakeSccacheAttrs = - old: - let - sccacheLauncher = mkSccacheLauncher { - name = "cmake-sccache"; - passthroughWrappedCompiler = true; - }; - in - { - cmakeFlags = (old.cmakeFlags or [ ]) ++ [ - "-DCMAKE_C_COMPILER_LAUNCHER=${sccacheLauncher}/bin/cmake-sccache" - "-DCMAKE_CXX_COMPILER_LAUNCHER=${sccacheLauncher}/bin/cmake-sccache" - ]; - - nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ sccacheLauncher ]; - - preConfigure = (old.preConfigure or "") + '' - mkdir -p ${final.lib.escapeShellArg sandboxSccacheDir} - export SCCACHE_WRAPPED_COMPILER_PASSTHROUGH=1 - ${sccacheRuntimeModeSetup} - ''; - - postConfigure = (old.postConfigure or "") + '' - unset SCCACHE_WRAPPED_COMPILER_PASSTHROUGH - ''; - - postBuild = (old.postBuild or "") + '' - - ${sccacheLauncher}/bin/cmake-sccache --show-stats --stats-format text || true - ''; - }; - mkCmakeSccacheWithLlvmTargetAttrs = - llvmTarget: old: - let - base = mkCmakeSccacheAttrs old; - targetFlag = "-DLLVM_TARGETS_TO_BUILD=${llvmTarget}"; - hasTargetFlag = flag: final.lib.hasPrefix "-DLLVM_TARGETS_TO_BUILD=" flag; - replacedFlags = map (flag: if hasTargetFlag flag then targetFlag else flag) ( - base.cmakeFlags or [ ] - ); - withTargetFlag = - replacedFlags ++ final.lib.optional (!(final.lib.any hasTargetFlag replacedFlags)) targetFlag; - in - base - // { - cmakeFlags = withTargetFlag; - }; - mkSccacheExtraConfig = - { - sccacheDir ? sandboxSccacheDir, - extraConfig ? "", - }: - '' - mkdir -p ${final.lib.escapeShellArg sccacheDir} - export SCCACHE_CONF=${final.lib.escapeShellArg ( - final.writeText "sccache-stdenv.conf" '' - [cache.disk] - dir = "${sccacheDir}" - size = "100G" - '' - )} - ${sccacheRuntimeModeSetup} - ${extraConfig} - ''; - mkWrappedCcForSccache = - { - cc, - extraConfig ? "", - }: - let - wrappedCompiler = final.sccache.links { - inherit extraConfig; - unwrappedCC = cc.cc; - }; - overrideArgs = cc.override.__functionArgs or { }; - in - if overrideArgs ? cc then - cc.override { cc = wrappedCompiler; } - else if overrideArgs ? llvm then - cc.override { llvm = wrappedCompiler; } - else - throw "mkWrappedCcForSccache: unsupported compiler wrapper override interface"; - mkSccacheStdenv = - { - stdenv, - sccacheDir ? "/var/cache/sccache/nix-builds/packages", - extraConfig ? "", - }: - final.overrideCC stdenv (mkWrappedCcForSccache { - inherit (stdenv) cc; - extraConfig = mkSccacheExtraConfig { - inherit extraConfig sccacheDir; - }; - }); in -{ - sccache = modify prev.sccache (old: { - postPatch = (old.postPatch or "") + '' - substituteInPlace src/compiler/gcc.rs \ - --replace-fail \ - ' take_arg!("-isystem", PathBuf, CanBeSeparated, PreprocessorArgumentPath),' \ - ' take_arg!("-isystem", PathBuf, CanBeSeparated, PreprocessorArgumentPath), - take_arg!("-cxx-isystem", PathBuf, CanBeSeparated, PreprocessorArgumentPath),' - ''; - env = (old.env or { }) // { - RUSTC_WRAPPER = "${prev.sccache}/bin/sccache"; - SCCACHE_CONF = sharedSccacheConfig; - }; - preBuild = (old.preBuild or "") + '' - mkdir -p ${final.lib.escapeShellArg sandboxSccacheDir} - ''; - passthru = (old.passthru or { }) // { - links = - { - unwrappedCC, - extraConfig ? "", - }: - let - sccacheLauncher = mkSccacheLauncher { - name = "wrapped-sccache"; - bypassIfCmakeLauncher = true; - extraSetup = extraConfig; - }; - in - final.stdenv.mkDerivation { - pname = "sccache-links"; - inherit (old) version; - passthru = { - isClang = unwrappedCC.isClang or false; - isGNU = unwrappedCC.isGNU or false; - isSccache = true; - dev = unwrappedCC.dev or null; - lib = unwrappedCC.lib or (final.lib.getLib unwrappedCC); - } - // final.lib.optionalAttrs (unwrappedCC ? rsrc) { - inherit (unwrappedCC) rsrc; - }; - dev = unwrappedCC.dev or null; - lib = unwrappedCC.lib or (final.lib.getLib unwrappedCC); - rsrc = unwrappedCC.rsrc or null; - nativeBuildInputs = [ final.makeWrapper ]; - buildCommand = - let - targetPrefix = - if unwrappedCC.isClang or false then - "" - else - (final.lib.optionalString ( - unwrappedCC ? targetConfig && unwrappedCC.targetConfig != null && unwrappedCC.targetConfig != "" - ) "${unwrappedCC.targetConfig}-"); - in - '' - mkdir -p $out/bin - mkdir -p $out/nix-support - - wrap() { - local cname="${targetPrefix}$1" - if [ -x "${unwrappedCC}/bin/$cname" ]; then - makeWrapper ${sccacheLauncher}/bin/wrapped-sccache $out/bin/$cname \ - --add-flags ${unwrappedCC}/bin/$cname - fi - } - - wrap cc - wrap c++ - wrap gcc - wrap g++ - wrap clang - wrap clang++ - - for executable in $(ls ${unwrappedCC}/bin); do - if [ ! -x "$out/bin/$executable" ]; then - ln -s ${unwrappedCC}/bin/$executable $out/bin/$executable - fi - done - for file in $(ls ${unwrappedCC} | grep -vw bin); do - ln -s ${unwrappedCC}/$file $out/$file - done - - printf '%s\n' "${unwrappedCC}" > $out/nix-support/orig-cc - ''; - meta = final.lib.optionalAttrs (unwrappedCC.meta ? mainProgram) { - inherit (unwrappedCC.meta) mainProgram; - }; - }; - }; - }); - sccacheWrapper = - final.lib.makeOverridable - ( - { - extraConfig ? "", - cc, - }: - mkWrappedCcForSccache { - inherit cc extraConfig; - } - ) - { - extraConfig = ""; - inherit (final.stdenv) cc; - }; - sccacheStdenv = final.lib.lowPrio ( - final.lib.makeOverridable - ( - { - stdenv, - ... - }@extraArgs: - final.overrideCC stdenv ( - final.buildPackages.sccacheWrapper.override ( - { - inherit (stdenv) cc; - } - // final.lib.optionalAttrs (builtins.hasAttr "extraConfig" extraArgs) { - extraConfig = extraArgs.extraConfig; - } - ) - ) - ) - { - inherit (final) stdenv; - } - ); - sccache-config = sharedSccacheConfig; +sccacheLib.overlay +// { intel-sycl = modify prev.intel-sycl ( syFinal: syPrev: let diff --git a/custom/sccache.nix b/custom/sccache.nix new file mode 100644 index 0000000..0124099 --- /dev/null +++ b/custom/sccache.nix @@ -0,0 +1,387 @@ +{ final, prev }: +let + sandboxSccacheDir = "/var/cache/sccache/nix-builds/packages"; + useSocketedSccache = false; # fuckin broken + sharedSccacheServerUds = "/run/sccache/server.sock"; + effectiveSccacheServerUds = if useSocketedSccache then sharedSccacheServerUds else null; + sccacheRuntimeModeSetup = '' + unset SCCACHE_NO_DAEMON + ${final.lib.optionalString (effectiveSccacheServerUds != null) '' + export SCCACHE_SERVER_UDS=${final.lib.escapeShellArg effectiveSccacheServerUds} + unset SCCACHE_IDLE_TIMEOUT + ''} + ${final.lib.optionalString (effectiveSccacheServerUds == null) '' + unset SCCACHE_SERVER_UDS + export SCCACHE_IDLE_TIMEOUT=0 + ''} + ''; + sharedSccacheConfig = final.writeText "sccache.conf" '' + [cache.disk] + dir = "${sandboxSccacheDir}" + size = "100G" + ''; + modify = + target: f: + if target ? overridePythonAttrs then + target.overridePythonAttrs f + else if target ? overrideAttrs then + target.overrideAttrs f + else if target ? overrideScope then + target.overrideScope f + else + throw "modify: target does not support overridePythonAttrs, overrideAttrs, or overrideScope"; + mkSccacheLauncher = + { + name, + sccacheDir ? null, + sccacheServerUds ? effectiveSccacheServerUds, + sccacheCacheSize ? "100G", + noDaemon ? false, + bypassIfCmakeLauncher ? false, + passthroughWrappedCompiler ? false, + extraSetup ? "", + }: + let + sccacheConfig = final.writeText "${name}-config" '' + [cache.disk] + dir = "${if sccacheDir != null then sccacheDir else sandboxSccacheDir}" + size = "${sccacheCacheSize}" + ''; + effectiveSccacheConfig = + if sccacheDir == null && sccacheCacheSize == "100G" then sharedSccacheConfig else sccacheConfig; + in + final.writeShellScriptBin name '' + is_cmake_derivation() { + case " ''${nativeBuildInputs:-} ''${propagatedNativeBuildInputs:-} " in + *"/cmake-"*) return 0 ;; + esac + + [ -n "''${cmakeFlags:-}" ] || [ -n "''${cmakeDir:-}" ] || [ -n "''${cmakeBuildType:-}" ] + } + + is_cmake_probe_invocation() { + local arg response_file + for arg in "$@"; do + case "$arg" in + *CMakeFiles/*CompilerId*|*CMakeFiles/CMakeTmp/*|*CMakeScratch/*) + return 0 + ;; + @*) + response_file="''${arg#@}" + if [ -f "$response_file" ] && grep -Eq 'CMakeFiles/.+CompilerId|CMakeFiles/CMakeTmp|CMakeScratch' "$response_file"; then + return 0 + fi + ;; + esac + done + + return 1 + } + + has_cmake_compiler_launcher() { + [ -n "''${CMAKE_C_COMPILER_LAUNCHER:-}" ] \ + || [ -n "''${CMAKE_CXX_COMPILER_LAUNCHER:-}" ] \ + || [ -n "''${CMAKE_Fortran_COMPILER_LAUNCHER:-}" ] \ + || [ -n "''${CMAKE_CUDA_COMPILER_LAUNCHER:-}" ] \ + || [ -n "''${CMAKE_HIP_COMPILER_LAUNCHER:-}" ] \ + || [ -n "''${CMAKE_OBJC_COMPILER_LAUNCHER:-}" ] \ + || [ -n "''${CMAKE_OBJCXX_COMPILER_LAUNCHER:-}" ] + } + + export SCCACHE_CONF=${final.lib.escapeShellArg effectiveSccacheConfig} + mkdir -p ${final.lib.escapeShellArg sandboxSccacheDir} + unset SCCACHE_START_SERVER + ${final.lib.optionalString noDaemon '' + export SCCACHE_NO_DAEMON=1 + unset SCCACHE_SERVER_UDS + ''} + ${final.lib.optionalString (!noDaemon && sccacheServerUds != null) '' + export SCCACHE_SERVER_UDS=${final.lib.escapeShellArg sccacheServerUds} + ''} + ${final.lib.optionalString (!noDaemon && sccacheServerUds == null) '' + unset SCCACHE_SERVER_UDS + unset SCCACHE_NO_DAEMON + ''} + ${extraSetup} + if [ "$#" -eq 0 ]; then + exit 0 + fi + if [ "''${1#-}" != "$1" ]; then + exec ${final.sccache}/bin/sccache "$@" + fi + + compiler="$1" + shift + + if [ "''${SCCACHE_WRAPPED_COMPILER_PASSTHROUGH:-}" = 1 ] \ + || { [ ${if bypassIfCmakeLauncher then "1" else "0"} -eq 1 ] && has_cmake_compiler_launcher; } \ + || { + is_cmake_derivation && is_cmake_probe_invocation "$@" + }; then + exec "$compiler" "$@" + fi + + ${final.lib.optionalString passthroughWrappedCompiler '' + export SCCACHE_WRAPPED_COMPILER_PASSTHROUGH=1 + ''} + exec ${final.sccache}/bin/sccache "$compiler" "$@" + ''; + buildSccacheLauncher = mkSccacheLauncher { + name = "build-sccache"; + }; + mkBuildSccacheAttrs = old: { + nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ buildSccacheLauncher ]; + + preConfigure = (old.preConfigure or "") + '' + + mkdir -p ${final.lib.escapeShellArg sandboxSccacheDir} + ${sccacheRuntimeModeSetup} + ''; + + postBuild = (old.postBuild or "") + '' + + ${buildSccacheLauncher}/bin/build-sccache --show-stats --stats-format text || true + ''; + }; + mkCmakeSccacheAttrs = + old: + let + sccacheLauncher = mkSccacheLauncher { + name = "cmake-sccache"; + passthroughWrappedCompiler = true; + }; + in + { + cmakeFlags = (old.cmakeFlags or [ ]) ++ [ + "-DCMAKE_C_COMPILER_LAUNCHER=${sccacheLauncher}/bin/cmake-sccache" + "-DCMAKE_CXX_COMPILER_LAUNCHER=${sccacheLauncher}/bin/cmake-sccache" + ]; + + nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ sccacheLauncher ]; + + preConfigure = (old.preConfigure or "") + '' + mkdir -p ${final.lib.escapeShellArg sandboxSccacheDir} + export SCCACHE_WRAPPED_COMPILER_PASSTHROUGH=1 + ${sccacheRuntimeModeSetup} + ''; + + postConfigure = (old.postConfigure or "") + '' + unset SCCACHE_WRAPPED_COMPILER_PASSTHROUGH + ''; + + postBuild = (old.postBuild or "") + '' + + ${sccacheLauncher}/bin/cmake-sccache --show-stats --stats-format text || true + ''; + }; + mkCmakeSccacheWithLlvmTargetAttrs = + llvmTarget: old: + let + base = mkCmakeSccacheAttrs old; + targetFlag = "-DLLVM_TARGETS_TO_BUILD=${llvmTarget}"; + hasTargetFlag = flag: final.lib.hasPrefix "-DLLVM_TARGETS_TO_BUILD=" flag; + replacedFlags = map (flag: if hasTargetFlag flag then targetFlag else flag) ( + base.cmakeFlags or [ ] + ); + withTargetFlag = + replacedFlags ++ final.lib.optional (!(final.lib.any hasTargetFlag replacedFlags)) targetFlag; + in + base + // { + cmakeFlags = withTargetFlag; + }; + mkSccacheExtraConfig = + { + sccacheDir ? sandboxSccacheDir, + extraConfig ? "", + }: + '' + mkdir -p ${final.lib.escapeShellArg sccacheDir} + export SCCACHE_CONF=${final.lib.escapeShellArg ( + final.writeText "sccache-stdenv.conf" '' + [cache.disk] + dir = "${sccacheDir}" + size = "100G" + '' + )} + ${sccacheRuntimeModeSetup} + ${extraConfig} + ''; + mkWrappedCcForSccache = + { + cc, + extraConfig ? "", + }: + let + wrappedCompiler = final.sccache.links { + inherit extraConfig; + unwrappedCC = cc.cc; + }; + overrideArgs = cc.override.__functionArgs or { }; + in + if overrideArgs ? cc then + cc.override { cc = wrappedCompiler; } + else if overrideArgs ? llvm then + cc.override { llvm = wrappedCompiler; } + else + throw "mkWrappedCcForSccache: unsupported compiler wrapper override interface"; + mkSccacheStdenv = + { + stdenv, + sccacheDir ? "/var/cache/sccache/nix-builds/packages", + extraConfig ? "", + }: + final.overrideCC stdenv (mkWrappedCcForSccache { + inherit (stdenv) cc; + extraConfig = mkSccacheExtraConfig { + inherit extraConfig sccacheDir; + }; + }); +in +{ + inherit + sandboxSccacheDir + sharedSccacheConfig + sccacheRuntimeModeSetup + mkSccacheLauncher + mkBuildSccacheAttrs + mkCmakeSccacheAttrs + mkCmakeSccacheWithLlvmTargetAttrs + mkSccacheExtraConfig + ; + + overlay = { + sccache = modify prev.sccache (old: { + postPatch = (old.postPatch or "") + '' + substituteInPlace src/compiler/gcc.rs \ + --replace-fail \ + ' take_arg!("-isystem", PathBuf, CanBeSeparated, PreprocessorArgumentPath),' \ + ' take_arg!("-isystem", PathBuf, CanBeSeparated, PreprocessorArgumentPath), + take_arg!("-cxx-isystem", PathBuf, CanBeSeparated, PreprocessorArgumentPath),' + ''; + env = (old.env or { }) // { + RUSTC_WRAPPER = "${prev.sccache}/bin/sccache"; + SCCACHE_CONF = sharedSccacheConfig; + }; + preBuild = (old.preBuild or "") + '' + mkdir -p ${final.lib.escapeShellArg sandboxSccacheDir} + ''; + passthru = (old.passthru or { }) // { + links = + { + unwrappedCC, + extraConfig ? "", + }: + let + sccacheLauncher = mkSccacheLauncher { + name = "wrapped-sccache"; + bypassIfCmakeLauncher = true; + extraSetup = extraConfig; + }; + in + final.stdenv.mkDerivation { + pname = "sccache-links"; + inherit (old) version; + passthru = { + isClang = unwrappedCC.isClang or false; + isGNU = unwrappedCC.isGNU or false; + isSccache = true; + dev = unwrappedCC.dev or null; + lib = unwrappedCC.lib or (final.lib.getLib unwrappedCC); + } + // final.lib.optionalAttrs (unwrappedCC ? rsrc) { + inherit (unwrappedCC) rsrc; + }; + dev = unwrappedCC.dev or null; + lib = unwrappedCC.lib or (final.lib.getLib unwrappedCC); + rsrc = unwrappedCC.rsrc or null; + nativeBuildInputs = [ final.makeWrapper ]; + buildCommand = + let + targetPrefix = + if unwrappedCC.isClang or false then + "" + else + (final.lib.optionalString ( + unwrappedCC ? targetConfig && unwrappedCC.targetConfig != null && unwrappedCC.targetConfig != "" + ) "${unwrappedCC.targetConfig}-"); + in + '' + mkdir -p $out/bin + mkdir -p $out/nix-support + + wrap() { + local cname="${targetPrefix}$1" + if [ -x "${unwrappedCC}/bin/$cname" ]; then + makeWrapper ${sccacheLauncher}/bin/wrapped-sccache $out/bin/$cname \ + --add-flags ${unwrappedCC}/bin/$cname + fi + } + + wrap cc + wrap c++ + wrap gcc + wrap g++ + wrap clang + wrap clang++ + + for executable in $(ls ${unwrappedCC}/bin); do + if [ ! -x "$out/bin/$executable" ]; then + ln -s ${unwrappedCC}/bin/$executable $out/bin/$executable + fi + done + for file in $(ls ${unwrappedCC} | grep -vw bin); do + ln -s ${unwrappedCC}/$file $out/$file + done + + printf '%s\n' "${unwrappedCC}" > $out/nix-support/orig-cc + ''; + meta = final.lib.optionalAttrs (unwrappedCC.meta ? mainProgram) { + inherit (unwrappedCC.meta) mainProgram; + }; + }; + }; + }); + + sccacheWrapper = + final.lib.makeOverridable + ( + { + extraConfig ? "", + cc, + }: + mkWrappedCcForSccache { + inherit cc extraConfig; + } + ) + { + extraConfig = ""; + inherit (final.stdenv) cc; + }; + + sccacheStdenv = final.lib.lowPrio ( + final.lib.makeOverridable + ( + { + stdenv, + ... + }@extraArgs: + final.overrideCC stdenv ( + final.buildPackages.sccacheWrapper.override ( + { + inherit (stdenv) cc; + } + // final.lib.optionalAttrs (builtins.hasAttr "extraConfig" extraArgs) { + extraConfig = extraArgs.extraConfig; + } + ) + ) + ) + { + inherit (final) stdenv; + } + ); + + sccache-config = sharedSccacheConfig; + }; +}