diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index acc433496b0e8..f3017dd5bfb76 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -8,6 +8,7 @@ { name ? "" , lib , stdenvNoCC +, testers ? {} , bintools ? null, libc ? null, coreutils ? null, shell ? stdenvNoCC.shell, gnugrep ? null , netbsd ? null, netbsdCross ? null , sharedLibraryLoader ? @@ -100,7 +101,7 @@ let in -stdenv.mkDerivation { +stdenv.mkDerivation (finalAttrs: { pname = targetPrefix + (if name != "" then name else "${bintoolsName}-wrapper"); version = if bintools == null then "" else bintoolsVersion; @@ -113,6 +114,11 @@ stdenv.mkDerivation { inherit targetPrefix suffixSalt; inherit bintools libc nativeTools nativeLibc nativePrefix isGNU isLLVM; + tests = import ./tests.nix { + inherit lib stdenvNoCC testers; + inherit (finalAttrs) finalPackage; + }; + emacsBufferSetup = pkgs: '' ; We should handle propagation here too (mapc @@ -397,4 +403,4 @@ stdenv.mkDerivation { } // optionalAttrs useMacosReexportHack { platforms = lib.platforms.darwin; }; -} +}) diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh index dcbe8a4c24948..0e03da13eec46 100644 --- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh +++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh @@ -20,8 +20,8 @@ if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then source @out@/nix-support/add-flags.sh fi - -# Optionally filter out paths not refering to the store. +extraAfter=() +extraBefore=() expandResponseParams "$@" # NIX_LINK_TYPE is set if ld has been called through our cc wrapper. We take @@ -33,6 +33,22 @@ else linkType=$(checkLinkType "${params[@]}") fi +# `lld` supports specifying the linker flavor (i.e. gnu, link, ld64, wasm, etc) +# via the `-flavor` argument: +# https://github.com/llvm/llvm-project/blob/1ba9ec0d10c8c95216d8d7fc47f028344c1640bb/lld/tools/lld/lld.cpp#L125-L142 +# +# However, this must be the *first* argument to `lld`. So, if `-flavor` is the +# first arg in `params`, we hoist it to the front of `extraBefore`: +if [[ ${#params[@]} -ge 2 ]] && [[ ${params[0]} == "-flavor" ]]; then + # As per the link above, only `-flavor ` is supported. Not + # `--flavor`, `-flavor=...`, `/flavor:...`, etc. + linkFlavor="${params[1]}" + extraBefore=(-flavor "$linkFlavor" "${extraBefore[@]}") + + params=("${params[@]:2}") +fi + +# Optionally filter out paths not refering to the store. if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}" && ( -z "$NIX_IGNORE_LD_THROUGH_GCC_@suffixSalt@" || -z "${NIX_LINK_TYPE_@suffixSalt@:-}" ) ]]; then rest=() @@ -76,8 +92,7 @@ fi source @out@/nix-support/add-hardening.sh -extraAfter=() -extraBefore=(${hardeningLDFlags[@]+"${hardeningLDFlags[@]}"}) +extraBefore+=(${hardeningLDFlags[@]+"${hardeningLDFlags[@]}"}) if [ -z "${NIX_LINK_TYPE_@suffixSalt@:-}" ]; then extraAfter+=($(filterRpathFlags "$linkType" $NIX_LDFLAGS_@suffixSalt@)) diff --git a/pkgs/build-support/bintools-wrapper/tests.nix b/pkgs/build-support/bintools-wrapper/tests.nix new file mode 100644 index 0000000000000..d4dc808bab036 --- /dev/null +++ b/pkgs/build-support/bintools-wrapper/tests.nix @@ -0,0 +1,52 @@ +{ stdenvNoCC +, lib +, finalPackage +, testers +}: let + testVersion = { binaryName }: testers.testVersion { + package = finalPackage; + command = "${binaryName} --version"; + }; +in lib.optionalAttrs finalPackage.isLLVM { + # `lld` supports specifying the linker flavor with `-flavor` but requires that + # this be the _first_ argument. + flavorArgumentParsed = stdenvNoCC.mkDerivation { + name = "bintools-wrapper-lld-flavor-arg-test"; + nativeBuildInputs = [ finalPackage ]; + buildCommand = '' + # We expect `-flavor` to be moved before `--help`: + NIX_LDFLAGS_BEFORE="--help" ld -flavor gnu \ + | grep "supported targets: elf" + + # If `-flavor` isn't the first arg the wrapper should not move it; i.e. + # we expect the below to fail with an error about `-flavor`: + { ld --gc-sections -flavor gnu || :; } \ + |& grep "unknown argument '-flavor'" + + # Note that we allow non-zero exit codes for the other linker flavors; + # `ld-wrapper` still injects flags that don't account for the linker + # flavor and so arg parsing fails on some hostPlatforms. + + # We should be able to specify the `link` flavor: + { NIX_LDFLAGS_BEFORE="/help" ld -flavor link || :; } \ + | grep "Create a DLL" + + # `ld64`: + { NIX_LDFLAGS_BEFORE="--help" ld -flavor ld64 || :; } \ + | grep "macos, ios" + '' + lib.optionalString (lib.versionAtLeast "6.0.0" finalPackage.version) '' + # wasm support was added to lld in v6.0: + # https://github.com/llvm/llvm-project/commit/c94d393ad52b6698b15400ee7a33a68b4bda274b + { NIX_LDFLAGS_BEFORE="--help" ld -flavor wasm || :; } \ + | grep "OVERVIEW: LLVM Linker" + '' + '' + ''; + }; + + # The `lld` package exposes several linker symlinks for its various flavors + # (`wasm-ld`, `ld64.lld`, `ld.lld`, `lld-link`) as well as an `lld` binary but + # at the moment we only expose `ld.lld` (and `ld`, a symlink) so that's all + # we test for here: + ldVersion = testVersion { binaryName = "ld"; }; + ldLldVersion = testVersion { binaryName = "ld.lld"; }; +}