387 lines
12 KiB
Nix
387 lines
12 KiB
Nix
{ 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;
|
|
};
|
|
}
|