summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/cc-wrapper/cc-wrapper.sh2
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix1
-rw-r--r--pkgs/build-support/rust/build-rust-package/default.nix10
-rw-r--r--pkgs/build-support/rust/hooks/cargo-build-hook.sh11
-rw-r--r--pkgs/build-support/rust/hooks/cargo-check-hook.sh4
-rw-r--r--pkgs/build-support/rust/hooks/cargo-install-hook.sh4
-rw-r--r--pkgs/build-support/rust/hooks/cargo-nextest-hook.sh4
-rw-r--r--pkgs/build-support/rust/hooks/default.nix49
-rw-r--r--pkgs/build-support/rust/hooks/maturin-build-hook.sh7
-rw-r--r--pkgs/build-support/rust/lib/default.nix86
-rw-r--r--pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh15
11 files changed, 134 insertions, 59 deletions
diff --git a/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/pkgs/build-support/cc-wrapper/cc-wrapper.sh
index 9dcd29c6443..6c43f8cbfa6 100644
--- a/pkgs/build-support/cc-wrapper/cc-wrapper.sh
+++ b/pkgs/build-support/cc-wrapper/cc-wrapper.sh
@@ -31,7 +31,6 @@ cxxLibrary=1
 cInclude=1
 
 expandResponseParams "$@"
-linkType=$(checkLinkType "${params[@]}")
 
 declare -ag positionalArgs=()
 declare -i n=0
@@ -175,6 +174,7 @@ extraAfter=(${hardeningCFlagsAfter[@]+"${hardeningCFlagsAfter[@]}"} $NIX_CFLAGS_
 extraBefore=(${hardeningCFlagsBefore[@]+"${hardeningCFlagsBefore[@]}"} $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@)
 
 if [ "$dontLink" != 1 ]; then
+    linkType=$(checkLinkType $NIX_LDFLAGS_BEFORE_@suffixSalt@ "${params[@]}" ${NIX_CFLAGS_LINK_@suffixSalt@:-} $NIX_LDFLAGS_@suffixSalt@)
 
     # Add the flags that should only be passed to the compiler when
     # linking.
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index e1da3ceb5bc..eef67154ef9 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -469,6 +469,7 @@ stdenv.mkDerivation {
     ''
     + optionalString (libcxx.isLLVM or false) ''
       echo "-isystem ${lib.getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
+      echo "-isystem ${lib.getDev libcxx.cxxabi}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
       echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags
       echo "-l${libcxx.cxxabi.libName}" >> $out/nix-support/libcxx-ldflags
     ''
diff --git a/pkgs/build-support/rust/build-rust-package/default.nix b/pkgs/build-support/rust/build-rust-package/default.nix
index 9b2e62fc240..da868861e2c 100644
--- a/pkgs/build-support/rust/build-rust-package/default.nix
+++ b/pkgs/build-support/rust/build-rust-package/default.nix
@@ -62,7 +62,6 @@
 assert cargoVendorDir == null && cargoLock == null
     -> !(args ? cargoSha256 && args.cargoSha256 != null) && !(args ? cargoHash && args.cargoHash != null)
     -> throw "cargoSha256, cargoHash, cargoVendorDir, or cargoLock must be set";
-assert buildType == "release" || buildType == "debug";
 
 let
 
@@ -83,14 +82,9 @@ let
   targetIsJSON = lib.hasSuffix ".json" target;
   useSysroot = targetIsJSON && !__internal_dontAddSysroot;
 
-  # see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168
-  # the "${}" is needed to transform the path into a /nix/store path before baseNameOf
-  shortTarget = if targetIsJSON then
-      (lib.removeSuffix ".json" (builtins.baseNameOf "${target}"))
-    else target;
-
   sysroot = callPackage ./sysroot { } {
-    inherit target shortTarget;
+    inherit target;
+    shortTarget = rust.lib.toRustTargetSpecShort stdenv.hostPlatform;
     RUSTFLAGS = args.RUSTFLAGS or "";
     originalCargoToml = src + /Cargo.toml; # profile info is later extracted
   };
diff --git a/pkgs/build-support/rust/hooks/cargo-build-hook.sh b/pkgs/build-support/rust/hooks/cargo-build-hook.sh
index af94e02e38a..ed982c7ff30 100644
--- a/pkgs/build-support/rust/hooks/cargo-build-hook.sh
+++ b/pkgs/build-support/rust/hooks/cargo-build-hook.sh
@@ -17,7 +17,7 @@ cargoBuildHook() {
     fi
 
     if [ "${cargoBuildType}" != "debug" ]; then
-        cargoBuildProfileFlag="--${cargoBuildType}"
+        cargoBuildProfileFlag="--profile ${cargoBuildType}"
     fi
 
     if [ -n "${cargoBuildNoDefaultFeatures-}" ]; then
@@ -30,13 +30,8 @@ cargoBuildHook() {
 
     (
     set -x
-    env \
-      "CC_@rustBuildPlatform@=@ccForBuild@" \
-      "CXX_@rustBuildPlatform@=@cxxForBuild@" \
-      "CC_@rustTargetPlatform@=@ccForHost@" \
-      "CXX_@rustTargetPlatform@=@cxxForHost@" \
-      cargo build -j $NIX_BUILD_CORES \
-        --target @rustTargetPlatformSpec@ \
+    @setEnv@ cargo build -j $NIX_BUILD_CORES \
+        --target @rustHostPlatformSpec@ \
         --frozen \
         ${cargoBuildProfileFlag} \
         ${cargoBuildNoDefaultFeaturesFlag} \
diff --git a/pkgs/build-support/rust/hooks/cargo-check-hook.sh b/pkgs/build-support/rust/hooks/cargo-check-hook.sh
index 57fc2779cfe..971a140ec17 100644
--- a/pkgs/build-support/rust/hooks/cargo-check-hook.sh
+++ b/pkgs/build-support/rust/hooks/cargo-check-hook.sh
@@ -17,7 +17,7 @@ cargoCheckHook() {
     fi
 
     if [ "${cargoCheckType}" != "debug" ]; then
-        cargoCheckProfileFlag="--${cargoCheckType}"
+        cargoCheckProfileFlag="--profile ${cargoCheckType}"
     fi
 
     if [ -n "${cargoCheckNoDefaultFeatures-}" ]; then
@@ -29,7 +29,7 @@ cargoCheckHook() {
     fi
 
     argstr="${cargoCheckProfileFlag} ${cargoCheckNoDefaultFeaturesFlag} ${cargoCheckFeaturesFlag}
-        --target @rustTargetPlatformSpec@ --frozen ${cargoTestFlags}"
+        --target @rustHostPlatformSpec@ --frozen ${cargoTestFlags}"
 
     (
         set -x
diff --git a/pkgs/build-support/rust/hooks/cargo-install-hook.sh b/pkgs/build-support/rust/hooks/cargo-install-hook.sh
index 69ce7266936..24a6e6fa9eb 100644
--- a/pkgs/build-support/rust/hooks/cargo-install-hook.sh
+++ b/pkgs/build-support/rust/hooks/cargo-install-hook.sh
@@ -1,7 +1,7 @@
 cargoInstallPostBuildHook() {
     echo "Executing cargoInstallPostBuildHook"
 
-    releaseDir=target/@shortTarget@/$cargoBuildType
+    releaseDir=target/@targetSubdirectory@/$cargoBuildType
     tmpDir="${releaseDir}-tmp";
 
     mkdir -p $tmpDir
@@ -21,7 +21,7 @@ cargoInstallHook() {
 
     # rename the output dir to a architecture independent one
 
-    releaseDir=target/@shortTarget@/$cargoBuildType
+    releaseDir=target/@targetSubdirectory@/$cargoBuildType
     tmpDir="${releaseDir}-tmp";
 
     mapfile -t targets < <(find "$NIX_BUILD_TOP" -type d | grep "${tmpDir}$")
diff --git a/pkgs/build-support/rust/hooks/cargo-nextest-hook.sh b/pkgs/build-support/rust/hooks/cargo-nextest-hook.sh
index de85683ead2..29ba18a6a1e 100644
--- a/pkgs/build-support/rust/hooks/cargo-nextest-hook.sh
+++ b/pkgs/build-support/rust/hooks/cargo-nextest-hook.sh
@@ -17,7 +17,7 @@ cargoNextestHook() {
     fi
 
     if [ "${cargoCheckType}" != "debug" ]; then
-        cargoCheckProfileFlag="--${cargoCheckType}"
+        cargoCheckProfileFlag="--cargo-profile ${cargoCheckType}"
     fi
 
     if [ -n "${cargoCheckNoDefaultFeatures-}" ]; then
@@ -29,7 +29,7 @@ cargoNextestHook() {
     fi
 
     argstr="${cargoCheckProfileFlag} ${cargoCheckNoDefaultFeaturesFlag} ${cargoCheckFeaturesFlag}
-        --target @rustTargetPlatformSpec@ --frozen ${cargoTestFlags}"
+        --target @rustHostPlatformSpec@ --frozen ${cargoTestFlags}"
 
     (
         set -x
diff --git a/pkgs/build-support/rust/hooks/default.nix b/pkgs/build-support/rust/hooks/default.nix
index 2eb388fe07b..205d085d350 100644
--- a/pkgs/build-support/rust/hooks/default.nix
+++ b/pkgs/build-support/rust/hooks/default.nix
@@ -9,32 +9,20 @@
 , rust
 , rustc
 , stdenv
-, target ? rust.toRustTargetSpec stdenv.hostPlatform
-}:
 
-let
-  targetIsJSON = lib.hasSuffix ".json" target;
+# This confusingly-named parameter indicates the *subdirectory of
+# `target/` from which to copy the build artifacts.  It is derived
+# from a stdenv platform (or a JSON file).
+, target ? rust.lib.toRustTargetSpecShort stdenv.hostPlatform
+}:
 
-  # see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168
-  # the "${}" is needed to transform the path into a /nix/store path before baseNameOf
-  shortTarget = if targetIsJSON then
-      (lib.removeSuffix ".json" (builtins.baseNameOf "${target}"))
-    else target;
-  ccForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
-  cxxForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++";
-  ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
-  cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
-  rustBuildPlatform = rust.toRustTarget stdenv.buildPlatform;
-  rustTargetPlatform = rust.toRustTarget stdenv.hostPlatform;
-  rustTargetPlatformSpec = rust.toRustTargetSpec stdenv.hostPlatform;
-in {
+{
   cargoBuildHook = callPackage ({ }:
     makeSetupHook {
       name = "cargo-build-hook.sh";
       propagatedBuildInputs = [ cargo ];
       substitutions = {
-        inherit ccForBuild ccForHost cxxForBuild cxxForHost
-          rustBuildPlatform rustTargetPlatform rustTargetPlatformSpec;
+        inherit (rust.envVars) rustHostPlatformSpec setEnv;
       };
     } ./cargo-build-hook.sh) {};
 
@@ -43,7 +31,7 @@ in {
       name = "cargo-check-hook.sh";
       propagatedBuildInputs = [ cargo ];
       substitutions = {
-        inherit rustTargetPlatformSpec;
+        inherit (rust.envVars) rustHostPlatformSpec;
       };
     } ./cargo-check-hook.sh) {};
 
@@ -52,7 +40,7 @@ in {
       name = "cargo-install-hook.sh";
       propagatedBuildInputs = [ ];
       substitutions = {
-        inherit shortTarget;
+        targetSubdirectory = target;
       };
     } ./cargo-install-hook.sh) {};
 
@@ -61,7 +49,7 @@ in {
       name = "cargo-nextest-hook.sh";
       propagatedBuildInputs = [ cargo cargo-nextest ];
       substitutions = {
-        inherit rustTargetPlatformSpec;
+        inherit (rust.envVars) rustHostPlatformSpec;
       };
     } ./cargo-nextest-hook.sh) {};
 
@@ -78,23 +66,26 @@ in {
 
         cargoConfig = ''
           [target."${rust.toRustTarget stdenv.buildPlatform}"]
-          "linker" = "${ccForBuild}"
+          "linker" = "${rust.envVars.ccForBuild}"
           ${lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) ''
-            [target."${shortTarget}"]
-            "linker" = "${ccForHost}"
+            [target."${rust.toRustTarget stdenv.hostPlatform}"]
+            "linker" = "${rust.envVars.ccForHost}"
           ''}
           "rustflags" = [ "-C", "target-feature=${if stdenv.hostPlatform.isStatic then "+" else "-"}crt-static" ]
         '';
       };
     } ./cargo-setup-hook.sh) {};
 
-  maturinBuildHook = callPackage ({ }:
+  maturinBuildHook = callPackage ({ pkgsHostTarget }:
     makeSetupHook {
       name = "maturin-build-hook.sh";
-      propagatedBuildInputs = [ cargo maturin rustc ];
+      propagatedBuildInputs = [
+        pkgsHostTarget.maturin
+        pkgsHostTarget.cargo
+        pkgsHostTarget.rustc
+      ];
       substitutions = {
-        inherit ccForBuild ccForHost cxxForBuild cxxForHost
-          rustBuildPlatform rustTargetPlatform rustTargetPlatformSpec;
+        inherit (rust.envVars) rustTargetPlatformSpec setEnv;
       };
     } ./maturin-build-hook.sh) {};
 
diff --git a/pkgs/build-support/rust/hooks/maturin-build-hook.sh b/pkgs/build-support/rust/hooks/maturin-build-hook.sh
index 62d5619660c..d5ff069290b 100644
--- a/pkgs/build-support/rust/hooks/maturin-build-hook.sh
+++ b/pkgs/build-support/rust/hooks/maturin-build-hook.sh
@@ -9,12 +9,7 @@ maturinBuildHook() {
 
     (
     set -x
-    env \
-      "CC_@rustBuildPlatform@=@ccForBuild@" \
-      "CXX_@rustBuildPlatform@=@cxxForBuild@" \
-      "CC_@rustTargetPlatform@=@ccForHost@" \
-      "CXX_@rustTargetPlatform@=@cxxForHost@" \
-      maturin build \
+    @setEnv@ maturin build \
         --jobs=$NIX_BUILD_CORES \
         --frozen \
         --target @rustTargetPlatformSpec@ \
diff --git a/pkgs/build-support/rust/lib/default.nix b/pkgs/build-support/rust/lib/default.nix
index aa5ba14c139..ceca7323176 100644
--- a/pkgs/build-support/rust/lib/default.nix
+++ b/pkgs/build-support/rust/lib/default.nix
@@ -1,4 +1,8 @@
-{ lib }:
+{ lib
+, stdenv
+, buildPackages
+, targetPackages
+}:
 
 rec {
   # https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch
@@ -59,8 +63,88 @@ rec {
     then builtins.toFile (toRustTarget platform + ".json") (builtins.toJSON platform.rustc.platform)
     else toRustTarget platform;
 
+  # Returns the name of the rust target if it is standard, or the
+  # basename of the file containing the custom target spec, without
+  # the .json extension.
+  #
+  # This is the name used by Cargo for target subdirectories.
+  toRustTargetSpecShort = platform:
+    lib.removeSuffix ".json"
+      (baseNameOf "${toRustTargetSpec platform}");
+
+  # When used as part of an environment variable name, triples are
+  # uppercased and have all hyphens replaced by underscores:
+  #
+  # https://github.com/rust-lang/cargo/pull/9169
+  # https://github.com/rust-lang/cargo/issues/8285#issuecomment-634202431
+  #
+  toRustTargetForUseInEnvVars = platform:
+    lib.strings.replaceStrings ["-"] ["_"]
+      (lib.strings.toUpper
+        (toRustTargetSpecShort platform));
+
   # Returns true if the target is no_std
   # https://github.com/rust-lang/rust/blob/2e44c17c12cec45b6a682b1e53a04ac5b5fcc9d2/src/bootstrap/config.rs#L415-L421
   IsNoStdTarget = platform: let rustTarget = toRustTarget platform; in
     builtins.any (t: lib.hasInfix t rustTarget) ["-none" "nvptx" "switch" "-uefi"];
+
+  # These environment variables must be set when using `cargo-c` and
+  # several other tools which do not deal well with cross
+  # compilation.  The symptom of the problem they fix is errors due
+  # to buildPlatform CFLAGS being passed to the
+  # hostPlatform-targeted compiler -- for example, `-m64` being
+  # passed on a build=x86_64/host=aarch64 compilation.
+  envVars = let
+    ccForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
+    cxxForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++";
+    ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
+    cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
+
+    # Unfortunately we must use the dangerous `targetPackages` here
+    # because hooks are artificially phase-shifted one slot earlier
+    # (they go in nativeBuildInputs, so the hostPlatform looks like
+    # a targetPlatform to them).
+    ccForTarget = "${targetPackages.stdenv.cc}/bin/${targetPackages.stdenv.cc.targetPrefix}cc";
+    cxxForTarget = "${targetPackages.stdenv.cc}/bin/${targetPackages.stdenv.cc.targetPrefix}c++";
+
+    rustBuildPlatform = toRustTarget stdenv.buildPlatform;
+    rustBuildPlatformSpec = toRustTargetSpec stdenv.buildPlatform;
+    rustHostPlatform = toRustTarget stdenv.hostPlatform;
+    rustHostPlatformSpec = toRustTargetSpec stdenv.hostPlatform;
+    rustTargetPlatform = toRustTarget stdenv.targetPlatform;
+    rustTargetPlatformSpec = toRustTargetSpec stdenv.targetPlatform;
+  in {
+    inherit
+      ccForBuild  cxxForBuild  rustBuildPlatform   rustBuildPlatformSpec
+      ccForHost   cxxForHost   rustHostPlatform    rustHostPlatformSpec
+      ccForTarget cxxForTarget rustTargetPlatform  rustTargetPlatformSpec;
+
+    # Prefix this onto a command invocation in order to set the
+    # variables needed by cargo.
+    #
+    setEnv = ''
+    env \
+    ''
+    # Due to a bug in how splicing and targetPackages works, in
+    # situations where targetPackages is irrelevant
+    # targetPackages.stdenv.cc is often simply wrong.  We must omit
+    # the following lines when rustTargetPlatform collides with
+    # rustHostPlatform.
+    + lib.optionalString (rustTargetPlatform != rustHostPlatform) ''
+      "CC_${toRustTargetForUseInEnvVars stdenv.targetPlatform}=${ccForTarget}" \
+      "CXX_${toRustTargetForUseInEnvVars stdenv.targetPlatform}=${cxxForTarget}" \
+      "CARGO_TARGET_${toRustTargetForUseInEnvVars stdenv.targetPlatform}_LINKER=${ccForTarget}" \
+    '' + ''
+      "CC_${toRustTargetForUseInEnvVars stdenv.hostPlatform}=${ccForHost}" \
+      "CXX_${toRustTargetForUseInEnvVars stdenv.hostPlatform}=${cxxForHost}" \
+      "CARGO_TARGET_${toRustTargetForUseInEnvVars stdenv.hostPlatform}_LINKER=${ccForHost}" \
+    '' + ''
+      "CC_${toRustTargetForUseInEnvVars stdenv.buildPlatform}=${ccForBuild}" \
+      "CXX_${toRustTargetForUseInEnvVars stdenv.buildPlatform}=${cxxForBuild}" \
+      "CARGO_TARGET_${toRustTargetForUseInEnvVars stdenv.buildPlatform}_LINKER=${ccForBuild}" \
+      "CARGO_BUILD_TARGET=${rustBuildPlatform}" \
+      "HOST_CC=${buildPackages.stdenv.cc}/bin/cc" \
+      "HOST_CXX=${buildPackages.stdenv.cc}/bin/c++" \
+    '';
+  };
 }
diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh
index 88a50befd73..6cd01f6bf63 100644
--- a/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh
+++ b/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh
@@ -193,8 +193,23 @@ makeCWrapper() {
 
 addFlags() {
     local n flag before after var
+
+    # Disable file globbing, since bash will otherwise try to find
+    # filenames matching the the value to be prefixed/suffixed if
+    # it contains characters considered wildcards, such as `?` and
+    # `*`. We want the value as is, except we also want to split
+    # it on on the separator; hence we can't quote it.
+    local reenableGlob=0
+    if [[ ! -o noglob ]]; then
+        reenableGlob=1
+    fi
+    set -o noglob
     # shellcheck disable=SC2086
     before=($1) after=($2)
+    if (( reenableGlob )); then
+        set +o noglob
+    fi
+
     var="argv_tmp"
     printf '%s\n' "char **$var = calloc(${#before[@]} + argc + ${#after[@]} + 1, sizeof(*$var));"
     printf '%s\n' "assert($var != NULL);"