2023-03-07 19:18:48 +00:00
|
|
|
|
{ lib, stdenv, stdenvNoCC, lndir, runtimeShell, shellcheck, haskell }:
|
2009-11-19 16:07:47 +00:00
|
|
|
|
|
2022-08-13 08:31:18 +00:00
|
|
|
|
let
|
|
|
|
|
inherit (lib)
|
|
|
|
|
optionalAttrs
|
|
|
|
|
warn
|
|
|
|
|
;
|
|
|
|
|
in
|
|
|
|
|
|
2016-09-27 14:36:16 +00:00
|
|
|
|
rec {
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/* Run the shell command `buildCommand' to produce a store path named
|
2023-02-02 10:20:02 +00:00
|
|
|
|
`name'. The attributes in `env' are added to the environment
|
|
|
|
|
prior to running the command. By default `runCommand` runs in a
|
|
|
|
|
stdenv with no compiler environment. `runCommandCC` uses the default
|
|
|
|
|
stdenv, `pkgs.stdenv`.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
runCommand "name" {envVariable = true;} ''echo hello > $out''
|
|
|
|
|
runCommandCC "name" {} ''gcc -o myfile myfile.c; cp myfile $out'';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The `*Local` variants force a derivation to be built locally,
|
|
|
|
|
it is not substituted.
|
|
|
|
|
|
|
|
|
|
This is intended for very cheap commands (<1s execution time).
|
|
|
|
|
It saves on the network roundrip and can speed up a build.
|
|
|
|
|
|
|
|
|
|
It is the same as adding the special fields
|
|
|
|
|
|
|
|
|
|
`preferLocalBuild = true;`
|
|
|
|
|
`allowSubstitutes = false;`
|
|
|
|
|
|
|
|
|
|
to a derivation’s attributes.
|
2017-10-30 17:13:50 +00:00
|
|
|
|
*/
|
2021-08-15 15:21:15 +00:00
|
|
|
|
runCommand = name: env: runCommandWith {
|
2021-03-18 17:49:40 +00:00
|
|
|
|
stdenv = stdenvNoCC;
|
|
|
|
|
runLocal = false;
|
|
|
|
|
inherit name;
|
|
|
|
|
derivationArgs = env;
|
|
|
|
|
};
|
2021-08-15 15:21:15 +00:00
|
|
|
|
runCommandLocal = name: env: runCommandWith {
|
2021-03-18 17:49:40 +00:00
|
|
|
|
stdenv = stdenvNoCC;
|
|
|
|
|
runLocal = true;
|
|
|
|
|
inherit name;
|
|
|
|
|
derivationArgs = env;
|
|
|
|
|
};
|
2019-11-29 15:27:11 +00:00
|
|
|
|
|
2021-03-18 17:49:40 +00:00
|
|
|
|
runCommandCC = name: env: runCommandWith {
|
|
|
|
|
stdenv = stdenv;
|
|
|
|
|
runLocal = false;
|
|
|
|
|
inherit name;
|
|
|
|
|
derivationArgs = env;
|
|
|
|
|
};
|
2019-12-03 18:09:58 +00:00
|
|
|
|
# `runCommandCCLocal` left out on purpose.
|
|
|
|
|
# We shouldn’t force the user to have a cc in scope.
|
2009-11-19 16:07:47 +00:00
|
|
|
|
|
2021-03-18 17:49:40 +00:00
|
|
|
|
/* Generalized version of the `runCommand`-variants
|
2023-02-02 10:20:02 +00:00
|
|
|
|
which does customized behavior via a single
|
|
|
|
|
attribute set passed as the first argument
|
|
|
|
|
instead of having a lot of variants like
|
|
|
|
|
`runCommand*`. Additionally it allows changing
|
|
|
|
|
the used `stdenv` freely and has a more explicit
|
|
|
|
|
approach to changing the arguments passed to
|
|
|
|
|
`stdenv.mkDerivation`.
|
2021-03-18 17:49:40 +00:00
|
|
|
|
*/
|
|
|
|
|
runCommandWith =
|
|
|
|
|
let
|
|
|
|
|
# prevent infinite recursion for the default stdenv value
|
|
|
|
|
defaultStdenv = stdenv;
|
|
|
|
|
in
|
2022-12-19 07:47:54 +00:00
|
|
|
|
{
|
2021-03-18 17:49:40 +00:00
|
|
|
|
# which stdenv to use, defaults to a stdenv with a C compiler, pkgs.stdenv
|
2022-12-19 07:47:54 +00:00
|
|
|
|
stdenv ? defaultStdenv
|
2021-03-18 17:49:40 +00:00
|
|
|
|
# whether to build this derivation locally instead of substituting
|
2022-12-19 07:47:54 +00:00
|
|
|
|
, runLocal ? false
|
2021-03-18 17:49:40 +00:00
|
|
|
|
# extra arguments to pass to stdenv.mkDerivation
|
2022-12-19 07:47:54 +00:00
|
|
|
|
, derivationArgs ? {}
|
2021-03-18 17:49:40 +00:00
|
|
|
|
# name of the resulting derivation
|
2022-12-19 07:47:54 +00:00
|
|
|
|
, name
|
2022-05-21 02:03:49 +00:00
|
|
|
|
# TODO(@Artturin): enable strictDeps always
|
2021-03-18 17:49:40 +00:00
|
|
|
|
}: buildCommand:
|
|
|
|
|
stdenv.mkDerivation ({
|
2022-05-14 01:13:49 +00:00
|
|
|
|
enableParallelBuilding = true;
|
2022-03-30 08:25:49 +00:00
|
|
|
|
inherit buildCommand name;
|
2021-03-18 17:49:40 +00:00
|
|
|
|
passAsFile = [ "buildCommand" ]
|
|
|
|
|
++ (derivationArgs.passAsFile or []);
|
2023-07-07 17:10:03 +00:00
|
|
|
|
}
|
|
|
|
|
// lib.optionalAttrs (! derivationArgs?meta) {
|
2023-06-13 16:58:37 +00:00
|
|
|
|
pos = let args = builtins.attrNames derivationArgs; in
|
|
|
|
|
if builtins.length args > 0
|
|
|
|
|
then builtins.unsafeGetAttrPos (builtins.head args) derivationArgs
|
|
|
|
|
else null;
|
2021-03-18 17:49:40 +00:00
|
|
|
|
}
|
|
|
|
|
// (lib.optionalAttrs runLocal {
|
|
|
|
|
preferLocalBuild = true;
|
|
|
|
|
allowSubstitutes = false;
|
|
|
|
|
})
|
|
|
|
|
// builtins.removeAttrs derivationArgs [ "passAsFile" ]);
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/* Writes a text file to the nix store.
|
2023-02-02 10:20:02 +00:00
|
|
|
|
The contents of text is added to the file in the store.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes my-file to /nix/store/<store path>
|
|
|
|
|
writeTextFile {
|
|
|
|
|
name = "my-file";
|
|
|
|
|
text = ''
|
|
|
|
|
Contents of File
|
|
|
|
|
'';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See also the `writeText` helper function below.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes executable my-file to /nix/store/<store path>/bin/my-file
|
|
|
|
|
writeTextFile {
|
|
|
|
|
name = "my-file";
|
|
|
|
|
text = ''
|
|
|
|
|
Contents of File
|
|
|
|
|
'';
|
|
|
|
|
executable = true;
|
|
|
|
|
destination = "/bin/my-file";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
*/
|
2009-11-19 16:07:47 +00:00
|
|
|
|
writeTextFile =
|
|
|
|
|
{ name # the name of the derivation
|
|
|
|
|
, text
|
|
|
|
|
, executable ? false # run chmod +x ?
|
|
|
|
|
, destination ? "" # relative path appended to $out eg "/bin/foo"
|
2016-01-27 22:26:40 +00:00
|
|
|
|
, checkPhase ? "" # syntax checks, e.g. for scripts
|
2021-11-08 17:28:58 +00:00
|
|
|
|
, meta ? { }
|
2023-03-20 04:00:18 +00:00
|
|
|
|
, allowSubstitutes ? false
|
|
|
|
|
, preferLocalBuild ? true
|
2009-11-19 16:07:47 +00:00
|
|
|
|
}:
|
2023-05-27 15:09:44 +00:00
|
|
|
|
let
|
|
|
|
|
matches = builtins.match "/bin/([^/]+)" destination;
|
|
|
|
|
in
|
2012-04-26 15:01:41 +00:00
|
|
|
|
runCommand name
|
2023-05-27 15:09:44 +00:00
|
|
|
|
{ inherit text executable checkPhase allowSubstitutes preferLocalBuild;
|
2015-02-18 00:08:03 +00:00
|
|
|
|
passAsFile = [ "text" ];
|
2023-05-31 13:23:09 +00:00
|
|
|
|
meta = lib.optionalAttrs (executable && matches != null) {
|
2023-05-27 15:09:44 +00:00
|
|
|
|
mainProgram = lib.head matches;
|
|
|
|
|
} // meta;
|
2012-04-26 15:01:41 +00:00
|
|
|
|
}
|
2009-11-19 16:07:47 +00:00
|
|
|
|
''
|
2022-02-28 16:51:03 +00:00
|
|
|
|
target=$out${lib.escapeShellArg destination}
|
2021-12-19 22:29:07 +00:00
|
|
|
|
mkdir -p "$(dirname "$target")"
|
2015-12-31 21:14:44 +00:00
|
|
|
|
|
2015-02-18 00:08:03 +00:00
|
|
|
|
if [ -e "$textPath" ]; then
|
2021-12-19 22:29:07 +00:00
|
|
|
|
mv "$textPath" "$target"
|
2015-02-18 00:08:03 +00:00
|
|
|
|
else
|
2021-12-19 22:29:07 +00:00
|
|
|
|
echo -n "$text" > "$target"
|
2015-02-18 00:08:03 +00:00
|
|
|
|
fi
|
2015-12-31 21:14:44 +00:00
|
|
|
|
|
2023-03-29 12:06:45 +00:00
|
|
|
|
if [ -n "$executable" ]; then
|
|
|
|
|
chmod +x "$target"
|
|
|
|
|
fi
|
2016-01-27 22:26:40 +00:00
|
|
|
|
|
2023-03-29 12:06:45 +00:00
|
|
|
|
eval "$checkPhase"
|
2009-11-19 16:07:47 +00:00
|
|
|
|
'';
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Writes a text file to nix store with no optional parameters available.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes contents of file to /nix/store/<store path>
|
|
|
|
|
writeText "my-file"
|
|
|
|
|
''
|
|
|
|
|
Contents of File
|
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
*/
|
2009-11-19 16:07:47 +00:00
|
|
|
|
writeText = name: text: writeTextFile {inherit name text;};
|
2019-05-06 17:08:23 +00:00
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Writes a text file to nix store in a specific directory with no
|
|
|
|
|
optional parameters available.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes contents of file to /nix/store/<store path>/share/my-file
|
|
|
|
|
writeTextDir "share/my-file"
|
|
|
|
|
''
|
|
|
|
|
Contents of File
|
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
*/
|
2019-07-07 19:18:37 +00:00
|
|
|
|
writeTextDir = path: text: writeTextFile {
|
|
|
|
|
inherit text;
|
|
|
|
|
name = builtins.baseNameOf path;
|
|
|
|
|
destination = "/${path}";
|
|
|
|
|
};
|
2019-05-06 17:08:23 +00:00
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Writes a text file to /nix/store/<store path> and marks the file as
|
|
|
|
|
executable.
|
|
|
|
|
|
|
|
|
|
If passed as a build input, will be used as a setup hook. This makes setup
|
|
|
|
|
hooks more efficient to create: you don't need a derivation that copies
|
|
|
|
|
them to $out/nix-support/setup-hook, instead you can use the file as is.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes my-file to /nix/store/<store path> and makes executable
|
|
|
|
|
writeScript "my-file"
|
|
|
|
|
''
|
|
|
|
|
Contents of File
|
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
*/
|
2009-11-19 16:07:47 +00:00
|
|
|
|
writeScript = name: text: writeTextFile {inherit name text; executable = true;};
|
2019-05-06 17:08:23 +00:00
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Writes a text file to /nix/store/<store path>/bin/<name> and
|
|
|
|
|
marks the file as executable.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
|
|
|
|
|
writeScriptBin "my-file"
|
|
|
|
|
''
|
|
|
|
|
Contents of File
|
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
*/
|
2023-07-26 11:46:42 +00:00
|
|
|
|
writeScriptBin = name: text: writeTextFile {
|
|
|
|
|
inherit name text;
|
|
|
|
|
executable = true;
|
|
|
|
|
destination = "/bin/${name}";
|
|
|
|
|
};
|
2009-11-19 16:07:47 +00:00
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Similar to writeScript. Writes a Shell script and checks its syntax.
|
|
|
|
|
Automatically includes interpreter above the contents passed.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes my-file to /nix/store/<store path> and makes executable.
|
|
|
|
|
writeShellScript "my-file"
|
|
|
|
|
''
|
|
|
|
|
Contents of File
|
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
2019-05-06 17:08:23 +00:00
|
|
|
|
*/
|
|
|
|
|
writeShellScript = name: text:
|
|
|
|
|
writeTextFile {
|
|
|
|
|
inherit name;
|
|
|
|
|
executable = true;
|
|
|
|
|
text = ''
|
|
|
|
|
#!${runtimeShell}
|
|
|
|
|
${text}
|
|
|
|
|
'';
|
|
|
|
|
checkPhase = ''
|
2021-12-19 22:29:07 +00:00
|
|
|
|
${stdenv.shellDryRun} "$target"
|
2019-05-06 17:08:23 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Similar to writeShellScript and writeScriptBin.
|
|
|
|
|
Writes an executable Shell script to /nix/store/<store path>/bin/<name> and checks its syntax.
|
|
|
|
|
Automatically includes interpreter above the contents passed.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
|
|
|
|
|
writeShellScriptBin "my-file"
|
|
|
|
|
''
|
|
|
|
|
Contents of File
|
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
*/
|
2016-01-27 22:26:40 +00:00
|
|
|
|
writeShellScriptBin = name : text :
|
|
|
|
|
writeTextFile {
|
|
|
|
|
inherit name;
|
|
|
|
|
executable = true;
|
|
|
|
|
destination = "/bin/${name}";
|
|
|
|
|
text = ''
|
2019-02-26 11:45:54 +00:00
|
|
|
|
#!${runtimeShell}
|
2016-01-27 22:26:40 +00:00
|
|
|
|
${text}
|
|
|
|
|
'';
|
|
|
|
|
checkPhase = ''
|
2021-12-19 22:29:07 +00:00
|
|
|
|
${stdenv.shellDryRun} "$target"
|
2016-01-27 22:26:40 +00:00
|
|
|
|
'';
|
2023-08-11 05:09:11 +00:00
|
|
|
|
meta.mainProgram = name;
|
2016-01-27 22:26:40 +00:00
|
|
|
|
};
|
2009-11-19 16:07:47 +00:00
|
|
|
|
|
2021-10-12 19:31:02 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Similar to writeShellScriptBin and writeScriptBin.
|
|
|
|
|
Writes an executable Shell script to /nix/store/<store path>/bin/<name> and
|
|
|
|
|
checks its syntax with shellcheck and the shell's -n option.
|
|
|
|
|
Automatically includes sane set of shellopts (errexit, nounset, pipefail)
|
|
|
|
|
and handles creation of PATH based on runtimeInputs
|
|
|
|
|
|
|
|
|
|
Note that the checkPhase uses stdenv.shell for the test run of the script,
|
|
|
|
|
while the generated shebang uses runtimeShell. If, for whatever reason,
|
|
|
|
|
those were to mismatch you might lose fidelity in the default checks.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
writeShellApplication {
|
|
|
|
|
name = "my-file";
|
|
|
|
|
runtimeInputs = [ curl w3m ];
|
|
|
|
|
text = ''
|
|
|
|
|
curl -s 'https://nixos.org' | w3m -dump -T text/html
|
|
|
|
|
'';
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-12 19:31:02 +00:00
|
|
|
|
*/
|
|
|
|
|
writeShellApplication =
|
|
|
|
|
{ name
|
|
|
|
|
, text
|
2021-10-12 19:48:27 +00:00
|
|
|
|
, runtimeInputs ? [ ]
|
2023-08-25 13:38:21 +00:00
|
|
|
|
, meta ? { }
|
2021-10-12 19:31:02 +00:00
|
|
|
|
, checkPhase ? null
|
|
|
|
|
}:
|
|
|
|
|
writeTextFile {
|
2023-08-25 13:38:21 +00:00
|
|
|
|
inherit name meta;
|
2021-10-12 19:31:02 +00:00
|
|
|
|
executable = true;
|
|
|
|
|
destination = "/bin/${name}";
|
2023-03-20 04:00:18 +00:00
|
|
|
|
allowSubstitutes = true;
|
|
|
|
|
preferLocalBuild = false;
|
2021-10-12 19:31:02 +00:00
|
|
|
|
text = ''
|
|
|
|
|
#!${runtimeShell}
|
|
|
|
|
set -o errexit
|
|
|
|
|
set -o nounset
|
2021-10-12 20:13:58 +00:00
|
|
|
|
set -o pipefail
|
2022-08-22 18:52:27 +00:00
|
|
|
|
'' + lib.optionalString (runtimeInputs != [ ]) ''
|
2021-10-12 19:31:02 +00:00
|
|
|
|
|
2021-10-12 19:53:02 +00:00
|
|
|
|
export PATH="${lib.makeBinPath runtimeInputs}:$PATH"
|
2022-08-22 18:52:27 +00:00
|
|
|
|
'' + ''
|
2021-10-12 19:31:02 +00:00
|
|
|
|
|
|
|
|
|
${text}
|
|
|
|
|
'';
|
|
|
|
|
|
2021-11-08 17:29:14 +00:00
|
|
|
|
checkPhase =
|
2023-06-28 14:07:13 +00:00
|
|
|
|
# GHC (=> shellcheck) isn't supported on some platforms (such as risc-v)
|
|
|
|
|
# but we still want to use writeShellApplication on those platforms
|
|
|
|
|
let
|
|
|
|
|
shellcheckSupported = lib.meta.availableOn stdenv.buildPlatform shellcheck.compiler;
|
|
|
|
|
shellcheckCommand = lib.optionalString shellcheckSupported ''
|
|
|
|
|
# use shellcheck which does not include docs
|
|
|
|
|
# pandoc takes long to build and documentation isn't needed for just running the cli
|
|
|
|
|
${lib.getExe (haskell.lib.compose.justStaticExecutables shellcheck.unwrapped)} "$target"
|
|
|
|
|
'';
|
|
|
|
|
in
|
2021-11-08 17:29:14 +00:00
|
|
|
|
if checkPhase == null then ''
|
|
|
|
|
runHook preCheck
|
2021-12-19 22:29:07 +00:00
|
|
|
|
${stdenv.shellDryRun} "$target"
|
2023-06-28 14:07:13 +00:00
|
|
|
|
${shellcheckCommand}
|
2021-11-08 17:29:14 +00:00
|
|
|
|
runHook postCheck
|
|
|
|
|
''
|
|
|
|
|
else checkPhase;
|
2021-10-12 19:31:02 +00:00
|
|
|
|
};
|
|
|
|
|
|
2018-05-23 07:18:44 +00:00
|
|
|
|
# Create a C binary
|
2023-09-21 01:09:34 +00:00
|
|
|
|
writeCBin = pname: code:
|
|
|
|
|
runCommandCC pname
|
2018-05-23 07:18:44 +00:00
|
|
|
|
{
|
2023-09-21 01:09:34 +00:00
|
|
|
|
inherit pname code;
|
2018-05-23 07:18:44 +00:00
|
|
|
|
executable = true;
|
|
|
|
|
passAsFile = ["code"];
|
|
|
|
|
# Pointless to do this on a remote machine.
|
|
|
|
|
preferLocalBuild = true;
|
|
|
|
|
allowSubstitutes = false;
|
2023-07-26 11:46:42 +00:00
|
|
|
|
meta = {
|
2023-09-21 01:09:34 +00:00
|
|
|
|
mainProgram = pname;
|
2023-07-26 11:46:42 +00:00
|
|
|
|
};
|
2018-05-23 07:18:44 +00:00
|
|
|
|
}
|
|
|
|
|
''
|
2023-09-21 01:09:34 +00:00
|
|
|
|
n=$out/bin/${pname}
|
2022-05-15 23:43:05 +00:00
|
|
|
|
mkdir -p "$(dirname "$n")"
|
|
|
|
|
mv "$codePath" code.c
|
|
|
|
|
$CC -x c code.c -o "$n"
|
2018-05-23 07:18:44 +00:00
|
|
|
|
'';
|
|
|
|
|
|
2021-11-28 00:28:11 +00:00
|
|
|
|
|
|
|
|
|
/* concat a list of files to the nix store.
|
2023-02-02 10:20:02 +00:00
|
|
|
|
The contents of files are added to the file in the store.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes my-file to /nix/store/<store path>
|
|
|
|
|
concatTextFile {
|
|
|
|
|
name = "my-file";
|
|
|
|
|
files = [ drv1 "${drv2}/path/to/file" ];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See also the `concatText` helper function below.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes executable my-file to /nix/store/<store path>/bin/my-file
|
|
|
|
|
concatTextFile {
|
|
|
|
|
name = "my-file";
|
|
|
|
|
files = [ drv1 "${drv2}/path/to/file" ];
|
|
|
|
|
executable = true;
|
|
|
|
|
destination = "/bin/my-file";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-11-28 00:28:11 +00:00
|
|
|
|
*/
|
|
|
|
|
concatTextFile =
|
|
|
|
|
{ name # the name of the derivation
|
|
|
|
|
, files
|
|
|
|
|
, executable ? false # run chmod +x ?
|
|
|
|
|
, destination ? "" # relative path appended to $out eg "/bin/foo"
|
|
|
|
|
, checkPhase ? "" # syntax checks, e.g. for scripts
|
|
|
|
|
, meta ? { }
|
|
|
|
|
}:
|
|
|
|
|
runCommandLocal name
|
|
|
|
|
{ inherit files executable checkPhase meta destination; }
|
|
|
|
|
''
|
2021-11-28 18:33:22 +00:00
|
|
|
|
file=$out$destination
|
|
|
|
|
mkdir -p "$(dirname "$file")"
|
|
|
|
|
cat $files > "$file"
|
2021-11-28 00:28:11 +00:00
|
|
|
|
|
2023-03-29 12:06:45 +00:00
|
|
|
|
if [ -n "$executable" ]; then
|
|
|
|
|
chmod +x "$file"
|
|
|
|
|
fi
|
|
|
|
|
|
2021-11-28 00:28:11 +00:00
|
|
|
|
eval "$checkPhase"
|
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Writes a text file to nix store with no optional parameters available.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Writes contents of files to /nix/store/<store path>
|
|
|
|
|
concatText "my-file" [ file1 file2 ]
|
|
|
|
|
|
|
|
|
|
|
2021-11-28 00:28:11 +00:00
|
|
|
|
*/
|
|
|
|
|
concatText = name: files: concatTextFile { inherit name files; };
|
|
|
|
|
|
2023-02-02 10:20:02 +00:00
|
|
|
|
/*
|
|
|
|
|
Writes a text file to nix store with and mark it as executable.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
# Writes contents of files to /nix/store/<store path>
|
|
|
|
|
concatScript "my-file" [ file1 file2 ]
|
|
|
|
|
|
2021-11-28 00:28:11 +00:00
|
|
|
|
*/
|
2021-11-28 20:43:17 +00:00
|
|
|
|
concatScript = name: files: concatTextFile { inherit name files; executable = true; };
|
2021-11-28 00:28:11 +00:00
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Create a forest of symlinks to the files in `paths'.
|
|
|
|
|
|
|
|
|
|
This creates a single derivation that replicates the directory structure
|
|
|
|
|
of all the input paths.
|
|
|
|
|
|
|
|
|
|
BEWARE: it may not "work right" when the passed paths contain symlinks to directories.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# adds symlinks of hello to current build.
|
|
|
|
|
symlinkJoin { name = "myhello"; paths = [ pkgs.hello ]; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# adds symlinks of hello and stack to current build and prints "links added"
|
|
|
|
|
symlinkJoin { name = "myexample"; paths = [ pkgs.hello pkgs.stack ]; postBuild = "echo links added"; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This creates a derivation with a directory structure like the following:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/nix/store/sglsr5g079a5235hy29da3mq3hv8sjmm-myexample
|
|
|
|
|
|-- bin
|
|
|
|
|
| |-- hello -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/bin/hello
|
|
|
|
|
| `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/bin/stack
|
|
|
|
|
`-- share
|
|
|
|
|
|-- bash-completion
|
|
|
|
|
| `-- completions
|
|
|
|
|
| `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/bash-completion/completions/stack
|
|
|
|
|
|-- fish
|
|
|
|
|
| `-- vendor_completions.d
|
|
|
|
|
| `-- stack.fish -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/fish/vendor_completions.d/stack.fish
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
symlinkJoin and linkFarm are similar functions, but they output
|
|
|
|
|
derivations with different structure.
|
|
|
|
|
|
|
|
|
|
symlinkJoin is used to create a derivation with a familiar directory
|
|
|
|
|
structure (top-level bin/, share/, etc), but with all actual files being symlinks to
|
|
|
|
|
the files in the input derivations.
|
|
|
|
|
|
|
|
|
|
symlinkJoin is used many places in nixpkgs to create a single derivation
|
|
|
|
|
that appears to contain binaries, libraries, documentation, etc from
|
|
|
|
|
multiple input derivations.
|
|
|
|
|
|
|
|
|
|
linkFarm is instead used to create a simple derivation with symlinks to
|
|
|
|
|
other derivations. A derivation created with linkFarm is often used in CI
|
|
|
|
|
as a easy way to build multiple derivations at once.
|
2020-02-14 04:46:49 +00:00
|
|
|
|
*/
|
2016-04-26 12:10:42 +00:00
|
|
|
|
symlinkJoin =
|
2016-07-14 13:30:30 +00:00
|
|
|
|
args_@{ name
|
2016-05-27 10:38:06 +00:00
|
|
|
|
, paths
|
|
|
|
|
, preferLocalBuild ? true
|
|
|
|
|
, allowSubstitutes ? false
|
|
|
|
|
, postBuild ? ""
|
|
|
|
|
, ...
|
|
|
|
|
}:
|
2016-07-14 13:30:30 +00:00
|
|
|
|
let
|
|
|
|
|
args = removeAttrs args_ [ "name" "postBuild" ]
|
2020-02-17 10:45:44 +00:00
|
|
|
|
// {
|
|
|
|
|
inherit preferLocalBuild allowSubstitutes;
|
|
|
|
|
passAsFile = [ "paths" ];
|
|
|
|
|
}; # pass the defaults
|
2016-07-14 13:30:30 +00:00
|
|
|
|
in runCommand name args
|
2009-11-19 16:07:47 +00:00
|
|
|
|
''
|
|
|
|
|
mkdir -p $out
|
2020-02-17 10:45:44 +00:00
|
|
|
|
for i in $(cat $pathsPath); do
|
2023-03-29 12:34:08 +00:00
|
|
|
|
${lndir}/bin/lndir -silent $i $out
|
|
|
|
|
done
|
2016-04-26 12:10:42 +00:00
|
|
|
|
${postBuild}
|
2009-11-19 16:07:47 +00:00
|
|
|
|
'';
|
|
|
|
|
|
2020-02-14 04:46:49 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Quickly create a set of symlinks to derivations.
|
|
|
|
|
|
|
|
|
|
This creates a simple derivation with symlinks to all inputs.
|
|
|
|
|
|
|
|
|
|
entries can be a list of attribute sets like
|
|
|
|
|
|
|
|
|
|
[ { name = "name" ; path = "/nix/store/..."; } ]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
or an attribute set name -> path like:
|
|
|
|
|
|
|
|
|
|
{ name = "/nix/store/..."; other = "/nix/store/..."; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
# Symlinks hello and stack paths in store to current $out/hello-test and
|
|
|
|
|
# $out/foobar.
|
|
|
|
|
linkFarm "myexample" [ { name = "hello-test"; path = pkgs.hello; } { name = "foobar"; path = pkgs.stack; } ]
|
|
|
|
|
|
|
|
|
|
This creates a derivation with a directory structure like the following:
|
|
|
|
|
|
|
|
|
|
/nix/store/qc5728m4sa344mbks99r3q05mymwm4rw-myexample
|
|
|
|
|
|-- foobar -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1
|
|
|
|
|
`-- hello-test -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See the note on symlinkJoin for the difference between linkFarm and symlinkJoin.
|
2020-02-14 04:46:49 +00:00
|
|
|
|
*/
|
2022-04-25 23:17:21 +00:00
|
|
|
|
linkFarm = name: entries:
|
|
|
|
|
let
|
|
|
|
|
entries' =
|
|
|
|
|
if (lib.isAttrs entries) then entries
|
2022-04-25 23:17:21 +00:00
|
|
|
|
# We do this foldl to have last-wins semantics in case of repeated entries
|
|
|
|
|
else if (lib.isList entries) then lib.foldl (a: b: a // { "${b.name}" = b.path; }) { } entries
|
2022-04-25 23:17:21 +00:00
|
|
|
|
else throw "linkFarm entries must be either attrs or a list!";
|
|
|
|
|
|
|
|
|
|
linkCommands = lib.mapAttrsToList (name: path: ''
|
|
|
|
|
mkdir -p "$(dirname ${lib.escapeShellArg "${name}"})"
|
|
|
|
|
ln -s ${lib.escapeShellArg "${path}"} ${lib.escapeShellArg "${name}"}
|
|
|
|
|
'') entries';
|
|
|
|
|
in
|
|
|
|
|
runCommand name {
|
|
|
|
|
preferLocalBuild = true;
|
|
|
|
|
allowSubstitutes = false;
|
|
|
|
|
passthru.entries = entries';
|
2022-04-24 04:04:34 +00:00
|
|
|
|
} ''
|
|
|
|
|
mkdir -p $out
|
|
|
|
|
cd $out
|
2022-04-25 23:17:21 +00:00
|
|
|
|
${lib.concatStrings linkCommands}
|
2022-04-24 04:04:34 +00:00
|
|
|
|
'';
|
2020-02-14 04:46:49 +00:00
|
|
|
|
|
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Easily create a linkFarm from a set of derivations.
|
|
|
|
|
|
|
|
|
|
This calls linkFarm with a list of entries created from the list of input
|
|
|
|
|
derivations. It turns each input derivation into an attribute set
|
|
|
|
|
like { name = drv.name ; path = drv }, and passes this to linkFarm.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
# Symlinks the hello, gcc, and ghc derivations in $out
|
|
|
|
|
linkFarmFromDrvs "myexample" [ pkgs.hello pkgs.gcc pkgs.ghc ]
|
|
|
|
|
|
|
|
|
|
This creates a derivation with a directory structure like the following:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/nix/store/m3s6wkjy9c3wy830201bqsb91nk2yj8c-myexample
|
|
|
|
|
|-- gcc-wrapper-9.2.0 -> /nix/store/fqhjxf9ii4w4gqcsx59fyw2vvj91486a-gcc-wrapper-9.2.0
|
|
|
|
|
|-- ghc-8.6.5 -> /nix/store/gnf3s07bglhbbk4y6m76sbh42siym0s6-ghc-8.6.5
|
|
|
|
|
`-- hello-2.10 -> /nix/store/k0ll91c4npk4lg8lqhx00glg2m735g74-hello-2.10
|
|
|
|
|
|
|
|
|
|
*/
|
2020-02-14 04:46:49 +00:00
|
|
|
|
linkFarmFromDrvs = name: drvs:
|
|
|
|
|
let mkEntryFromDrv = drv: { name = drv.name; path = drv; };
|
|
|
|
|
in linkFarm name (map mkEntryFromDrv drvs);
|
|
|
|
|
|
2009-11-19 16:07:47 +00:00
|
|
|
|
|
2023-01-28 19:57:21 +00:00
|
|
|
|
# docs in doc/builders/special/makesetuphook.section.md
|
2023-01-18 16:30:55 +00:00
|
|
|
|
makeSetupHook =
|
|
|
|
|
{ name ? lib.warn "calling makeSetupHook without passing a name is deprecated." "hook"
|
2022-12-30 20:14:00 +00:00
|
|
|
|
, deps ? [ ]
|
|
|
|
|
# hooks go in nativeBuildInput so these will be nativeBuildInput
|
|
|
|
|
, propagatedBuildInputs ? [ ]
|
|
|
|
|
# these will be buildInputs
|
|
|
|
|
, depsTargetTargetPropagated ? [ ]
|
|
|
|
|
, meta ? { }
|
|
|
|
|
, passthru ? { }
|
|
|
|
|
, substitutions ? { }
|
2023-01-18 16:30:55 +00:00
|
|
|
|
}:
|
|
|
|
|
script:
|
2022-03-22 18:20:58 +00:00
|
|
|
|
runCommand name
|
|
|
|
|
(substitutions // {
|
2023-06-30 16:37:17 +00:00
|
|
|
|
# TODO(@Artturin:) substitutions should be inside the env attrset
|
|
|
|
|
# but users are likely passing non-substitution arguments through substitutions
|
|
|
|
|
# turn off __structuredAttrs to unbreak substituteAll
|
|
|
|
|
__structuredAttrs = false;
|
2022-03-22 18:20:58 +00:00
|
|
|
|
inherit meta;
|
2022-12-30 20:14:00 +00:00
|
|
|
|
inherit depsTargetTargetPropagated;
|
|
|
|
|
propagatedBuildInputs =
|
|
|
|
|
# remove list conditionals before 23.11
|
2023-01-01 20:27:28 +00:00
|
|
|
|
lib.warnIf (!lib.isList deps) "'deps' argument to makeSetupHook must be a list. content of deps: ${toString deps}"
|
|
|
|
|
(lib.warnIf (deps != [ ]) "'deps' argument to makeSetupHook is deprecated and will be removed in release 23.11., Please use propagatedBuildInputs instead. content of deps: ${toString deps}"
|
|
|
|
|
propagatedBuildInputs ++ (if lib.isList deps then deps else [ deps ]));
|
2022-05-21 16:58:22 +00:00
|
|
|
|
strictDeps = true;
|
2022-08-13 08:31:18 +00:00
|
|
|
|
# TODO 2023-01, no backport: simplify to inherit passthru;
|
|
|
|
|
passthru = passthru
|
|
|
|
|
// optionalAttrs (substitutions?passthru)
|
|
|
|
|
(warn "makeSetupHook (name = ${lib.strings.escapeNixString name}): `substitutions.passthru` is deprecated. Please set `passthru` directly."
|
|
|
|
|
substitutions.passthru);
|
2022-03-22 18:20:58 +00:00
|
|
|
|
})
|
2011-03-28 16:33:33 +00:00
|
|
|
|
(''
|
2012-01-18 20:16:00 +00:00
|
|
|
|
mkdir -p $out/nix-support
|
2009-11-19 16:07:47 +00:00
|
|
|
|
cp ${script} $out/nix-support/setup-hook
|
2022-12-30 20:14:00 +00:00
|
|
|
|
recordPropagatedDependencies
|
2014-10-27 09:25:35 +00:00
|
|
|
|
'' + lib.optionalString (substitutions != {}) ''
|
2011-03-29 15:19:59 +00:00
|
|
|
|
substituteAll ${script} $out/nix-support/setup-hook
|
2011-03-28 16:33:33 +00:00
|
|
|
|
'');
|
2009-11-19 16:07:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Write the references (i.e. the runtime dependencies in the Nix store) of `path' to a file.
|
2017-10-30 17:13:50 +00:00
|
|
|
|
|
2009-11-19 16:07:47 +00:00
|
|
|
|
writeReferencesToFile = path: runCommand "runtime-deps"
|
|
|
|
|
{
|
|
|
|
|
exportReferencesGraph = ["graph" path];
|
|
|
|
|
}
|
|
|
|
|
''
|
|
|
|
|
touch $out
|
|
|
|
|
while read path; do
|
|
|
|
|
echo $path >> $out
|
|
|
|
|
read dummy
|
|
|
|
|
read nrRefs
|
|
|
|
|
for ((i = 0; i < nrRefs; i++)); do read ref; done
|
|
|
|
|
done < graph
|
|
|
|
|
'';
|
|
|
|
|
|
2021-05-14 15:27:25 +00:00
|
|
|
|
/*
|
|
|
|
|
Write the set of references to a file, that is, their immediate dependencies.
|
|
|
|
|
|
|
|
|
|
This produces the equivalent of `nix-store -q --references`.
|
|
|
|
|
*/
|
|
|
|
|
writeDirectReferencesToFile = path: runCommand "runtime-references"
|
|
|
|
|
{
|
|
|
|
|
exportReferencesGraph = ["graph" path];
|
|
|
|
|
inherit path;
|
|
|
|
|
}
|
|
|
|
|
''
|
|
|
|
|
touch ./references
|
|
|
|
|
while read p; do
|
|
|
|
|
read dummy
|
|
|
|
|
read nrRefs
|
|
|
|
|
if [[ $p == $path ]]; then
|
|
|
|
|
for ((i = 0; i < nrRefs; i++)); do
|
|
|
|
|
read ref;
|
|
|
|
|
echo $ref >>./references
|
|
|
|
|
done
|
|
|
|
|
else
|
|
|
|
|
for ((i = 0; i < nrRefs; i++)); do
|
|
|
|
|
read ref;
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
done < graph
|
|
|
|
|
sort ./references >$out
|
|
|
|
|
'';
|
|
|
|
|
|
2016-09-27 12:10:36 +00:00
|
|
|
|
|
2021-10-15 15:22:37 +00:00
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
Extract a string's references to derivations and paths (its
|
|
|
|
|
context) and write them to a text file, removing the input string
|
|
|
|
|
itself from the dependency graph. This is useful when you want to
|
|
|
|
|
make a derivation depend on the string's references, but not its
|
|
|
|
|
contents (to avoid unnecessary rebuilds, for example).
|
|
|
|
|
|
|
|
|
|
Note that this only works as intended on Nix >= 2.3.
|
2021-10-15 15:22:37 +00:00
|
|
|
|
*/
|
|
|
|
|
writeStringReferencesToFile = string:
|
|
|
|
|
/*
|
2023-02-02 10:20:02 +00:00
|
|
|
|
The basic operation this performs is to copy the string context
|
|
|
|
|
from `string' to a second string and wrap that string in a
|
|
|
|
|
derivation. However, that alone is not enough, since nothing in the
|
|
|
|
|
string refers to the output paths of the derivations/paths in its
|
|
|
|
|
context, meaning they'll be considered build-time dependencies and
|
|
|
|
|
removed from the wrapper derivation's closure. Putting the
|
|
|
|
|
necessary output paths in the new string is however not very
|
|
|
|
|
straightforward - the attrset returned by `getContext' contains
|
|
|
|
|
only references to derivations' .drv-paths, not their output
|
|
|
|
|
paths. In order to "convert" them, we try to extract the
|
|
|
|
|
corresponding paths from the original string using regex.
|
2021-10-15 15:22:37 +00:00
|
|
|
|
*/
|
|
|
|
|
let
|
|
|
|
|
# Taken from https://github.com/NixOS/nix/blob/130284b8508dad3c70e8160b15f3d62042fc730a/src/libutil/hash.cc#L84
|
|
|
|
|
nixHashChars = "0123456789abcdfghijklmnpqrsvwxyz";
|
|
|
|
|
context = builtins.getContext string;
|
|
|
|
|
derivations = lib.filterAttrs (n: v: v ? outputs) context;
|
|
|
|
|
# Objects copied from outside of the store, such as paths and
|
|
|
|
|
# `builtins.fetch*`ed ones
|
|
|
|
|
sources = lib.attrNames (lib.filterAttrs (n: v: v ? path) context);
|
|
|
|
|
packages =
|
|
|
|
|
lib.mapAttrs'
|
|
|
|
|
(name: value:
|
|
|
|
|
{
|
|
|
|
|
inherit value;
|
|
|
|
|
name = lib.head (builtins.match "${builtins.storeDir}/[${nixHashChars}]+-(.*)\.drv" name);
|
|
|
|
|
})
|
|
|
|
|
derivations;
|
|
|
|
|
# The syntax of output paths differs between outputs named `out`
|
|
|
|
|
# and other, explicitly named ones. For explicitly named ones,
|
|
|
|
|
# the output name is suffixed as `-name`, but `out` outputs
|
|
|
|
|
# aren't suffixed at all, and thus aren't easily distinguished
|
|
|
|
|
# from named output paths. Therefore, we find all the named ones
|
|
|
|
|
# first so we can use them to remove false matches when looking
|
|
|
|
|
# for `out` outputs (see the definition of `outputPaths`).
|
|
|
|
|
namedOutputPaths =
|
|
|
|
|
lib.flatten
|
|
|
|
|
(lib.mapAttrsToList
|
|
|
|
|
(name: value:
|
|
|
|
|
(map
|
|
|
|
|
(output:
|
|
|
|
|
lib.filter
|
|
|
|
|
lib.isList
|
|
|
|
|
(builtins.split "(${builtins.storeDir}/[${nixHashChars}]+-${name}-${output})" string))
|
|
|
|
|
(lib.remove "out" value.outputs)))
|
|
|
|
|
packages);
|
|
|
|
|
# Only `out` outputs
|
|
|
|
|
outputPaths =
|
|
|
|
|
lib.flatten
|
|
|
|
|
(lib.mapAttrsToList
|
|
|
|
|
(name: value:
|
|
|
|
|
if lib.elem "out" value.outputs then
|
|
|
|
|
lib.filter
|
|
|
|
|
(x: lib.isList x &&
|
|
|
|
|
# If the matched path is in `namedOutputPaths`,
|
|
|
|
|
# it's a partial match of an output path where
|
|
|
|
|
# the output name isn't `out`
|
|
|
|
|
lib.all (o: !lib.hasPrefix (lib.head x) o) namedOutputPaths)
|
|
|
|
|
(builtins.split "(${builtins.storeDir}/[${nixHashChars}]+-${name})" string)
|
|
|
|
|
else
|
|
|
|
|
[])
|
|
|
|
|
packages);
|
|
|
|
|
allPaths = lib.concatStringsSep "\n" (lib.unique (sources ++ namedOutputPaths ++ outputPaths));
|
|
|
|
|
allPathsWithContext = builtins.appendContext allPaths context;
|
|
|
|
|
in
|
|
|
|
|
if builtins ? getContext then
|
|
|
|
|
writeText "string-references" allPathsWithContext
|
|
|
|
|
else
|
|
|
|
|
writeDirectReferencesToFile (writeText "string-file" string);
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
/* Print an error message if the file with the specified name and
|
2023-02-02 10:20:02 +00:00
|
|
|
|
hash doesn't exist in the Nix store. This function should only
|
|
|
|
|
be used by non-redistributable software with an unfree license
|
|
|
|
|
that we need to require the user to download manually. It produces
|
|
|
|
|
packages that cannot be built automatically.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
requireFile {
|
|
|
|
|
name = "my-file";
|
|
|
|
|
url = "http://example.com/download/";
|
|
|
|
|
sha256 = "ffffffffffffffffffffffffffffffffffffffffffffffffffff";
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-30 17:13:50 +00:00
|
|
|
|
*/
|
2015-07-08 10:24:38 +00:00
|
|
|
|
requireFile = { name ? null
|
|
|
|
|
, sha256 ? null
|
|
|
|
|
, sha1 ? null
|
2023-04-22 15:02:34 +00:00
|
|
|
|
, hash ? null
|
2015-07-08 10:24:38 +00:00
|
|
|
|
, url ? null
|
|
|
|
|
, message ? null
|
2018-05-16 06:41:13 +00:00
|
|
|
|
, hashMode ? "flat"
|
2015-07-08 10:24:38 +00:00
|
|
|
|
} :
|
2010-05-03 09:13:17 +00:00
|
|
|
|
assert (message != null) || (url != null);
|
2023-04-22 15:02:34 +00:00
|
|
|
|
assert (sha256 != null) || (sha1 != null) || (hash != null);
|
2015-07-08 10:24:38 +00:00
|
|
|
|
assert (name != null) || (url != null);
|
2010-05-03 09:13:17 +00:00
|
|
|
|
let msg =
|
|
|
|
|
if message != null then message
|
|
|
|
|
else ''
|
2016-09-27 12:10:36 +00:00
|
|
|
|
Unfortunately, we cannot download file ${name_} automatically.
|
|
|
|
|
Please go to ${url} to download it yourself, and add it to the Nix store
|
2010-05-03 09:13:17 +00:00
|
|
|
|
using either
|
2015-07-08 10:24:38 +00:00
|
|
|
|
nix-store --add-fixed ${hashAlgo} ${name_}
|
2010-05-03 09:13:17 +00:00
|
|
|
|
or
|
2016-01-14 13:13:51 +00:00
|
|
|
|
nix-prefetch-url --type ${hashAlgo} file:///path/to/${name_}
|
2010-05-03 09:13:17 +00:00
|
|
|
|
'';
|
2023-08-04 12:34:30 +00:00
|
|
|
|
hashAlgo = if hash != null then (builtins.head (lib.strings.splitString "-" hash))
|
2023-04-22 15:02:34 +00:00
|
|
|
|
else if sha256 != null then "sha256"
|
|
|
|
|
else "sha1";
|
2023-08-04 12:34:30 +00:00
|
|
|
|
hashAlgo_ = if hash != null then "" else hashAlgo;
|
2023-04-22 15:02:34 +00:00
|
|
|
|
hash_ = if hash != null then hash
|
|
|
|
|
else if sha256 != null then sha256
|
|
|
|
|
else sha1;
|
2015-07-08 10:24:38 +00:00
|
|
|
|
name_ = if name == null then baseNameOf (toString url) else name;
|
2010-05-03 09:13:17 +00:00
|
|
|
|
in
|
2018-05-21 23:19:29 +00:00
|
|
|
|
stdenvNoCC.mkDerivation {
|
2015-07-08 10:24:38 +00:00
|
|
|
|
name = name_;
|
2018-05-16 06:41:13 +00:00
|
|
|
|
outputHashMode = hashMode;
|
2023-08-04 12:34:30 +00:00
|
|
|
|
outputHashAlgo = hashAlgo_;
|
2023-04-22 15:02:34 +00:00
|
|
|
|
outputHash = hash_;
|
2016-02-19 12:46:21 +00:00
|
|
|
|
preferLocalBuild = true;
|
2018-06-27 01:47:24 +00:00
|
|
|
|
allowSubstitutes = false;
|
2010-05-03 09:13:17 +00:00
|
|
|
|
builder = writeScript "restrict-message" ''
|
2018-05-21 23:19:29 +00:00
|
|
|
|
source ${stdenvNoCC}/setup
|
2016-02-19 12:46:21 +00:00
|
|
|
|
cat <<_EOF_
|
2010-05-03 09:13:17 +00:00
|
|
|
|
|
2016-02-19 12:46:21 +00:00
|
|
|
|
***
|
|
|
|
|
${msg}
|
|
|
|
|
***
|
2010-05-03 09:13:17 +00:00
|
|
|
|
|
2016-02-19 12:46:21 +00:00
|
|
|
|
_EOF_
|
2018-04-15 12:58:05 +00:00
|
|
|
|
exit 1
|
2010-05-03 09:13:17 +00:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2016-09-27 12:10:36 +00:00
|
|
|
|
|
2023-02-02 10:20:02 +00:00
|
|
|
|
/*
|
|
|
|
|
Copy a path to the Nix store.
|
|
|
|
|
Nix automatically copies files to the store before stringifying paths.
|
|
|
|
|
If you need the store path of a file, ${copyPathToStore <path>} can be
|
|
|
|
|
shortened to ${<path>}.
|
|
|
|
|
*/
|
2015-12-16 21:00:44 +00:00
|
|
|
|
copyPathToStore = builtins.filterSource (p: t: true);
|
|
|
|
|
|
2016-09-27 12:10:36 +00:00
|
|
|
|
|
2023-02-02 10:20:02 +00:00
|
|
|
|
/*
|
|
|
|
|
Copy a list of paths to the Nix store.
|
|
|
|
|
*/
|
2015-12-16 21:00:44 +00:00
|
|
|
|
copyPathsToStore = builtins.map copyPathToStore;
|
|
|
|
|
|
2019-09-02 09:13:19 +00:00
|
|
|
|
/* Applies a list of patches to a source directory.
|
2023-02-02 10:20:02 +00:00
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
|
|
# Patching nixpkgs:
|
|
|
|
|
|
|
|
|
|
applyPatches {
|
|
|
|
|
src = pkgs.path;
|
|
|
|
|
patches = [
|
|
|
|
|
(pkgs.fetchpatch {
|
|
|
|
|
url = "https://github.com/NixOS/nixpkgs/commit/1f770d20550a413e508e081ddc08464e9d08ba3d.patch";
|
|
|
|
|
sha256 = "1nlzx171y3r3jbk0qhvnl711kmdk57jlq4na8f8bs8wz2pbffymr";
|
|
|
|
|
})
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-02 09:13:19 +00:00
|
|
|
|
*/
|
|
|
|
|
applyPatches =
|
|
|
|
|
{ src
|
|
|
|
|
, name ? (if builtins.typeOf src == "path"
|
|
|
|
|
then builtins.baseNameOf src
|
|
|
|
|
else
|
|
|
|
|
if builtins.isAttrs src && builtins.hasAttr "name" src
|
|
|
|
|
then src.name
|
|
|
|
|
else throw "applyPatches: please supply a `name` argument because a default name can only be computed when the `src` is a path or is an attribute set with a `name` attribute."
|
|
|
|
|
) + "-patched"
|
|
|
|
|
, patches ? []
|
|
|
|
|
, postPatch ? ""
|
2023-06-18 12:12:25 +00:00
|
|
|
|
, ...
|
|
|
|
|
}@args: stdenvNoCC.mkDerivation {
|
2019-09-02 09:13:19 +00:00
|
|
|
|
inherit name src patches postPatch;
|
|
|
|
|
preferLocalBuild = true;
|
|
|
|
|
allowSubstitutes = false;
|
|
|
|
|
phases = "unpackPhase patchPhase installPhase";
|
|
|
|
|
installPhase = "cp -R ./ $out";
|
2023-06-18 12:12:25 +00:00
|
|
|
|
}
|
|
|
|
|
# Carry `meta` information from the underlying `src` if present.
|
2023-08-20 09:51:21 +00:00
|
|
|
|
// (optionalAttrs (src?meta) { inherit (src) meta; })
|
2023-06-18 12:12:25 +00:00
|
|
|
|
// (removeAttrs args [ "src" "name" "patches" "postPatch" ]);
|
2021-05-06 08:08:08 +00:00
|
|
|
|
|
2021-06-12 15:28:00 +00:00
|
|
|
|
/* An immutable file in the store with a length of 0 bytes. */
|
|
|
|
|
emptyFile = runCommand "empty-file" {
|
|
|
|
|
outputHashAlgo = "sha256";
|
|
|
|
|
outputHashMode = "recursive";
|
|
|
|
|
outputHash = "0ip26j2h11n1kgkz36rl4akv694yz65hr72q4kv4b3lxcbi65b3p";
|
|
|
|
|
preferLocalBuild = true;
|
|
|
|
|
} "touch $out";
|
|
|
|
|
|
|
|
|
|
/* An immutable empty directory in the store. */
|
|
|
|
|
emptyDirectory = runCommand "empty-directory" {
|
|
|
|
|
outputHashAlgo = "sha256";
|
|
|
|
|
outputHashMode = "recursive";
|
|
|
|
|
outputHash = "0sjjj9z1dhilhpc8pq4154czrb79z9cm044jvn75kxcjv6v5l2m5";
|
|
|
|
|
preferLocalBuild = true;
|
|
|
|
|
} "mkdir $out";
|
2009-11-19 16:07:47 +00:00
|
|
|
|
}
|