diff --git a/pkgs/build-support/trivial-builders/default.nix b/pkgs/build-support/trivial-builders/default.nix index ac834203cf91..ab372a692ec8 100644 --- a/pkgs/build-support/trivial-builders/default.nix +++ b/pkgs/build-support/trivial-builders/default.nix @@ -572,69 +572,81 @@ rec { other derivations. A derivation created with linkFarm is often used in CI as a easy way to build multiple derivations at once. */ - symlinkJoin = - args_@{ - name ? - assert lib.assertMsg ( - args_ ? pname && args_ ? version - ) "symlinkJoin requires either a `name` OR `pname` and `version`"; - "${args_.pname}-${args_.version}", - paths, - stripPrefix ? "", - preferLocalBuild ? true, - allowSubstitutes ? false, - postBuild ? "", - failOnMissing ? stripPrefix == "", - ... - }: - assert lib.assertMsg (stripPrefix != "" -> (hasPrefix "/" stripPrefix && stripPrefix != "/")) '' - stripPrefix must be either an empty string (disable stripping behavior), or relative path prefixed with /. + symlinkJoin = lib.extendMkDerivation { + constructDrv = stdenvNoCC.mkDerivation; - Ensure that the path starts with / and specifies path to the subdirectory. - ''; + extendDrvArgs = + finalAttrs: + args_@{ + name ? + assert lib.assertMsg ( + args_ ? pname && args_ ? version + ) "symlinkJoin requires either a `name` OR `pname` and `version`"; + "${args_.pname}-${args_.version}", + paths, + stripPrefix ? "", + preferLocalBuild ? true, + allowSubstitutes ? false, + postBuild ? "", + failOnMissing ? stripPrefix == "", + ... + }: + assert lib.assertMsg (stripPrefix != "" -> (hasPrefix "/" stripPrefix && stripPrefix != "/")) '' + stripPrefix must be either an empty string (disable stripping behavior), or relative path prefixed with /. - let - mapPaths = - f: paths: - map ( - path: - if path == null then - null - else if isList path then - mapPaths f path - else - f path - ) paths; - args = - removeAttrs args_ [ - "name" - "postBuild" - "stripPrefix" - "paths" - "failOnMissing" - ] - // { - # Allow getting the proper position of the output derivation. - # Since one of these are required, it should be fairly accurate. - pos = - if args_ ? pname then - builtins.unsafeGetAttrPos "pname" args_ + Ensure that the path starts with / and specifies path to the subdirectory. + ''; + let + mapPaths = + f: paths: + map ( + path: + if path == null then + null + else if isList path then + mapPaths f path else - builtins.unsafeGetAttrPos "name" args_; - inherit preferLocalBuild allowSubstitutes; - paths = mapPaths (path: "${path}${stripPrefix}") paths; - passAsFile = [ "paths" ]; - }; # pass the defaults - in - runCommand name args '' - mkdir -p $out - for i in $(cat $pathsPath); do - ${optionalString (!failOnMissing) "if test -d $i; then "}${lndir}/bin/lndir -silent $i $out${ - optionalString (!failOnMissing) "; fi" - } - done - ${postBuild} - ''; + f path + ) paths; + drvArgs = + removeAttrs args_ [ + "name" + "postBuild" + "stripPrefix" + "paths" + "failOnMissing" + ] + // { + inherit preferLocalBuild allowSubstitutes; + paths = mapPaths (path: "${path}${stripPrefix}") paths; + }; # pass the defaults + in + { + enableParallelBuilding = true; + inherit name; + passAsFile = [ + "buildCommand" + "paths" + ]; + buildCommand = '' + mkdir -p $out + for i in $(cat $pathsPath); do + ${optionalString (!failOnMissing) "if test -d $i; then "}${lndir}/bin/lndir -silent $i $out${ + optionalString (!failOnMissing) "; fi" + } + done + ${postBuild} + ''; + } + // lib.optionalAttrs (!drvArgs ? meta) { + pos = + let + args = builtins.attrNames drvArgs; + in + if builtins.length args > 0 then builtins.unsafeGetAttrPos (builtins.head args) drvArgs else null; + } + // drvArgs; + }; # TODO: move linkFarm docs to the Nixpkgs manual /*