about 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/bintools-wrapper/add-lld-ldflags-before.sh6
-rw-r--r--pkgs/build-support/bintools-wrapper/default.nix65
-rw-r--r--pkgs/build-support/bintools-wrapper/ld-wrapper.sh5
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix14
-rw-r--r--pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix27
-rw-r--r--pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh (renamed from pkgs/build-support/setup-hooks/make-binary-wrapper.sh)25
-rw-r--r--pkgs/build-support/setup-hooks/make-wrapper.sh23
-rw-r--r--pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix4
8 files changed, 106 insertions, 63 deletions
diff --git a/pkgs/build-support/bintools-wrapper/add-lld-ldflags-before.sh b/pkgs/build-support/bintools-wrapper/add-lld-ldflags-before.sh
new file mode 100644
index 0000000000000..265339eb1857a
--- /dev/null
+++ b/pkgs/build-support/bintools-wrapper/add-lld-ldflags-before.sh
@@ -0,0 +1,6 @@
+# ld.lld has two incompatible command-line drivers: One for the gnu-compatible COFF linker and one for
+# the ELF linker. If no emulation is set (with -m), it will default to the ELF linker;
+# unfortunately, some configure scripts use `ld --help` to check for certain Windows-specific flags,
+# which don't show up in the help for the ELF linker. So we set a default -m here.
+
+extraBefore+=("-m" "@mtype@")
diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix
index c2d67169c9caf..e4fb3c6d6a6d6 100644
--- a/pkgs/build-support/bintools-wrapper/default.nix
+++ b/pkgs/build-support/bintools-wrapper/default.nix
@@ -31,6 +31,13 @@
 
 # Darwin code signing support utilities
 , postLinkSignHook ? null, signingUtils ? null
+
+# Linker type
+, isLld ? bintools.isLld or false
+, isCctools ? bintools.isCctools or false
+, isGNU ? bintools.isGNU or false
+, isGold ? bintools.isGold or false
+, isBfd ? bintools.isBfd or false
 }:
 
 with lib;
@@ -113,6 +120,8 @@ stdenv.mkDerivation {
   passthru = {
     inherit bintools libc nativeTools nativeLibc nativePrefix;
 
+    inherit isLld isCctools isGNU isGold isBfd;
+
     emacsBufferSetup = pkgs: ''
       ; We should handle propagation here too
       (mapc
@@ -184,39 +193,6 @@ stdenv.mkDerivation {
       done
     '';
 
-  emulation = let
-    fmt =
-      /**/ if targetPlatform.isDarwin  then "mach-o"
-      else if targetPlatform.isWindows then "pe"
-      else "elf" + toString targetPlatform.parsed.cpu.bits;
-    endianPrefix = if targetPlatform.isBigEndian then "big" else "little";
-    sep = optionalString (!targetPlatform.isMips && !targetPlatform.isPower && !targetPlatform.isRiscV) "-";
-    arch =
-      /**/ if targetPlatform.isAarch64 then endianPrefix + "aarch64"
-      else if targetPlatform.isAarch32     then endianPrefix + "arm"
-      else if targetPlatform.isx86_64  then "x86-64"
-      else if targetPlatform.isx86_32  then "i386"
-      else if targetPlatform.isMips    then {
-          mips     = "btsmipn32"; # n32 variant
-          mipsel   = "ltsmipn32"; # n32 variant
-          mips64   = "btsmip";
-          mips64el = "ltsmip";
-        }.${targetPlatform.parsed.cpu.name}
-      else if targetPlatform.isMmix then "mmix"
-      else if targetPlatform.isPower then if targetPlatform.isBigEndian then "ppc" else "lppc"
-      else if targetPlatform.isSparc then "sparc"
-      else if targetPlatform.isMsp430 then "msp430"
-      else if targetPlatform.isAvr then "avr"
-      else if targetPlatform.isAlpha then "alpha"
-      else if targetPlatform.isVc4 then "vc4"
-      else if targetPlatform.isOr1k then "or1k"
-      else if targetPlatform.isM68k then "m68k"
-      else if targetPlatform.isS390 then "s390"
-      else if targetPlatform.isRiscV then "lriscv"
-      else throw "unknown emulation for platform: ${targetPlatform.config}";
-    in if targetPlatform.useLLVM or false then ""
-       else targetPlatform.bfdEmulation or (fmt + sep + arch);
-
   strictDeps = true;
   depsTargetTargetPropagated = extraPackages;
 
@@ -326,6 +302,11 @@ stdenv.mkDerivation {
       echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/libc-ldflags
     ''
 
+    # lld's MinGW driver (e.g. `ld.lld -m i386pep`) does not support the `-z` flag.
+    + optionalString (targetPlatform.isWindows && isLld) ''
+      hardening_unsupported_flags+=" relro bindnow"
+    ''
+
     ##
     ## GNU specific extra strip flags
     ##
@@ -371,6 +352,24 @@ stdenv.mkDerivation {
     )
 
     ##
+    ## Set the default machine type so that $prefix-ld.lld uses the COFF driver for --help
+    ##
+    ## Needed because autotools parses --help for linker features...
+    ##
+    + optionalString (isLld && stdenv.targetPlatform.isWindows) (let
+      mtype =
+        /**/ if targetPlatform.isx86_32 then "i386pe"
+        else if targetPlatform.isx86_64 then "i386pep"
+        else if targetPlatform.isAarch32 then "thumb2pe"
+        else if targetPlatform.isAarch64 then "arm64pe"
+        else throw "unsupported target arch for lld";
+    in ''
+      export mtype=${mtype}
+      substituteAll ${./add-lld-ldflags-before.sh} add-local-ldflags-before.sh
+      cat add-local-ldflags-before.sh >> $out/nix-support/add-local-ldflags-before.sh
+    '')
+
+    ##
     ## Code signing on Apple Silicon
     ##
     + optionalString (targetPlatform.isDarwin && targetPlatform.isAarch64) ''
diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
index fb01c5096d5b6..f8bddabbc6871 100644
--- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
+++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
@@ -93,11 +93,6 @@ if [ -e @out@/nix-support/add-local-ldflags-before.sh ]; then
 fi
 
 
-# Specify the target emulation if nothing is passed in ("-m" overrides this
-# environment variable). Ensures we never blindly fallback on targeting the host
-# platform.
-: ${LDEMULATION:=@emulation@}
-
 # Three tasks:
 #
 #   1. Find all -L... switches for rpath
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index 3738f628b187b..6e8e65fbb3f53 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -14,9 +14,11 @@
 , nativeTools, noLibc ? false, nativeLibc, nativePrefix ? ""
 , propagateDoc ? cc != null && cc ? man
 , extraTools ? [], extraPackages ? [], extraBuildCommands ? ""
+, nixSupport ? {}
 , isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null
 , buildPackages ? {}
 , libcxx ? null
+, isCompilerRT ? false
 }:
 
 with lib;
@@ -145,7 +147,7 @@ stdenv.mkDerivation {
     # Binutils, and Apple's "cctools"; "bintools" as an attempt to find an
     # unused middle-ground name that evokes both.
     inherit bintools;
-    inherit libc nativeTools nativeLibc nativePrefix isGNU isClang;
+    inherit libc nativeTools nativeLibc nativePrefix isGNU isClang isCompilerRT;
 
     emacsBufferSetup = pkgs: ''
       ; We should handle propagation here too
@@ -155,6 +157,8 @@ stdenv.mkDerivation {
             (setenv "NIX_CFLAGS_COMPILE_${suffixSalt}" (concat (getenv "NIX_CFLAGS_COMPILE_${suffixSalt}") " -isystem " arg "/include"))))
         '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
     '';
+
+    inherit nixSupport;
   };
 
   dontBuild = true;
@@ -476,6 +480,8 @@ stdenv.mkDerivation {
       hardening_unsupported_flags+=" pic"
     '' + optionalString targetPlatform.isMinGW ''
       hardening_unsupported_flags+=" stackprotector fortify"
+    '' + optionalString (targetPlatform.isWindows && isClang) ''
+      hardening_unsupported_flags+=" pic"
     '' + optionalString targetPlatform.isAvr ''
       hardening_unsupported_flags+=" stackprotector pic"
     '' + optionalString (targetPlatform.libc == "newlib") ''
@@ -521,7 +527,11 @@ stdenv.mkDerivation {
     ##
     ## Extra custom steps
     ##
-    + extraBuildCommands;
+    + extraBuildCommands
+    + lib.strings.concatStringsSep "; "
+      (lib.attrsets.mapAttrsToList
+        (name: value: "echo ${toString value} >> $out/nix-support/${name}")
+        nixSupport);
 
   inherit expand-response-params;
 
diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix b/pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix
new file mode 100644
index 0000000000000..fd0fa3ea00970
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/make-binary-wrapper/default.nix
@@ -0,0 +1,27 @@
+{ stdenv
+, lib
+, darwin
+, makeSetupHook
+, dieHook
+, writeShellScript
+, tests
+, cc ? stdenv.cc
+, sanitizers ? []
+}:
+
+makeSetupHook {
+  deps = [ dieHook ]
+    # https://github.com/NixOS/nixpkgs/issues/148189
+    ++ lib.optional (stdenv.isDarwin && stdenv.isAarch64) darwin.cctools;
+
+  substitutions = {
+    cc = "${cc}/bin/cc ${lib.escapeShellArgs (map (s: "-fsanitize=${s}") sanitizers)}";
+
+    # Extract the function call used to create a binary wrapper from its embedded docstring
+    passthru.extractCmd = writeShellScript "extract-binary-wrapper-cmd" ''
+      strings -dw "$1" | sed -n '/^makeCWrapper/,/^$/ p'
+    '';
+
+    passthru.tests = tests.makeBinaryWrapper;
+  };
+} ./make-binary-wrapper.sh
diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh
index 3931b37c24295..6b8f5d60eb65f 100644
--- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh
+++ b/pkgs/build-support/setup-hooks/make-binary-wrapper/make-binary-wrapper.sh
@@ -15,24 +15,25 @@ assertExecutable() {
 # makeWrapper EXECUTABLE OUT_PATH ARGS
 
 # ARGS:
-# --argv0       NAME    : set name of executed process to NAME
-#                         (otherwise it’s called …-wrapped)
+# --argv0       NAME    : set the name of the executed process to NAME
+#                         (if unset or empty, defaults to EXECUTABLE)
 # --inherit-argv0       : the executable inherits argv0 from the wrapper.
 #                         (use instead of --argv0 '$0')
-# --set         VAR VAL : add VAR with value VAL to the executable’s
-#                         environment
+# --set         VAR VAL : add VAR with value VAL to the executable's environment
 # --set-default VAR VAL : like --set, but only adds VAR if not already set in
 #                         the environment
 # --unset       VAR     : remove VAR from the environment
 # --chdir       DIR     : change working directory (use instead of --run "cd DIR")
 # --add-flags   FLAGS   : add FLAGS to invocation of executable
+# TODO(@ncfavier): --append-flags
 
 # --prefix          ENV SEP VAL   : suffix/prefix ENV with VAL, separated by SEP
 # --suffix
 
 # To troubleshoot a binary wrapper after you compiled it,
 # use the `strings` command or open the binary file in a text editor.
-makeWrapper() {
+makeWrapper() { makeBinaryWrapper "$@"; }
+makeBinaryWrapper() {
     local NIX_CFLAGS_COMPILE= NIX_CFLAGS_LINK=
     local original="$1"
     local wrapper="$2"
@@ -43,7 +44,7 @@ makeWrapper() {
     mkdir -p "$(dirname "$wrapper")"
 
     makeDocumentedCWrapper "$original" "$@" | \
-      @CC@ \
+      @cc@ \
         -Wall -Werror -Wpedantic \
         -Wno-overlength-strings \
         -Os \
@@ -52,7 +53,8 @@ makeWrapper() {
 }
 
 # Syntax: wrapProgram <PROGRAM> <MAKE-WRAPPER FLAGS...>
-wrapProgram() {
+wrapProgram() { wrapProgramBinary "$@"; }
+wrapProgramBinary() {
     local prog="$1"
     local hidden
 
@@ -63,8 +65,6 @@ wrapProgram() {
       hidden="${hidden}_"
     done
     mv "$prog" "$hidden"
-    # Silence warning about unexpanded $0:
-    # shellcheck disable=SC2016
     makeWrapper "$hidden" "$prog" --inherit-argv0 "${@:2}"
 }
 
@@ -311,8 +311,9 @@ void set_env_suffix(char *env, char *sep, char *suffix) {
 "
 }
 
-# Embed a C string which shows up as readable text in the compiled binary wrapper
-# documentationString ARGS
+# Embed a C string which shows up as readable text in the compiled binary wrapper,
+# giving instructions for recreating the wrapper.
+# Keep in sync with makeBinaryWrapper.extractCmd
 docstring() {
     printf '%s' "const char * DOCSTRING = \"$(escapeStringLiteral "
 
@@ -333,7 +334,7 @@ makeCWrapper $(formatArgs "$@")
 
 # formatArgs EXECUTABLE ARGS
 formatArgs() {
-    printf '%s' "$1"
+    printf '%s' "${1@Q}"
     shift
     while [ $# -gt 0 ]; do
         case "$1" in
diff --git a/pkgs/build-support/setup-hooks/make-wrapper.sh b/pkgs/build-support/setup-hooks/make-wrapper.sh
index 7d598956168c9..8a38c39efc478 100644
--- a/pkgs/build-support/setup-hooks/make-wrapper.sh
+++ b/pkgs/build-support/setup-hooks/make-wrapper.sh
@@ -11,16 +11,18 @@ assertExecutable() {
 # makeWrapper EXECUTABLE OUT_PATH ARGS
 
 # ARGS:
-# --argv0       NAME    : set name of executed process to NAME
-#                         (otherwise it’s called …-wrapped)
-# --set         VAR VAL : add VAR with value VAL to the executable’s
-#                         environment
+# --argv0       NAME    : set the name of the executed process to NAME
+#                         (if unset or empty, defaults to EXECUTABLE)
+# --inherit-argv0       : the executable inherits argv0 from the wrapper.
+#                         (use instead of --argv0 '$0')
+# --set         VAR VAL : add VAR with value VAL to the executable's environment
 # --set-default VAR VAL : like --set, but only adds VAR if not already set in
 #                         the environment
 # --unset       VAR     : remove VAR from the environment
 # --chdir       DIR     : change working directory (use instead of --run "cd DIR")
 # --run         COMMAND : run command before the executable
 # --add-flags   FLAGS   : add FLAGS to invocation of executable
+# TODO(@ncfavier): --append-flags
 
 # --prefix          ENV SEP VAL   : suffix/prefix ENV with VAL, separated by SEP
 # --suffix
@@ -29,7 +31,8 @@ assertExecutable() {
 # --prefix-contents ENV SEP FILES : like --suffix-each, but contents of FILES
 #                                   are read first and used as VALS
 # --suffix-contents
-makeWrapper() {
+makeWrapper() { makeShellWrapper "$@"; }
+makeShellWrapper() {
     local original="$1"
     local wrapper="$2"
     local params varName value command separator n fileNames
@@ -165,6 +168,9 @@ makeWrapper() {
         elif [[ "$p" == "--argv0" ]]; then
             argv0="${params[$((n + 1))]}"
             n=$((n + 1))
+        elif [[ "$p" == "--inherit-argv0" ]]; then
+            # Whichever comes last of --argv0 and --inherit-argv0 wins
+            argv0='$0'
         else
             die "makeWrapper doesn't understand the arg $p"
         fi
@@ -193,7 +199,8 @@ filterExisting() {
 }
 
 # Syntax: wrapProgram <PROGRAM> <MAKE-WRAPPER FLAGS...>
-wrapProgram() {
+wrapProgram() { wrapProgramShell "$@"; }
+wrapProgramShell() {
     local prog="$1"
     local hidden
 
@@ -204,7 +211,5 @@ wrapProgram() {
       hidden="${hidden}_"
     done
     mv "$prog" "$hidden"
-    # Silence warning about unexpanded $0:
-    # shellcheck disable=SC2016
-    makeWrapper "$hidden" "$prog" --argv0 '$0' "${@:2}"
+    makeWrapper "$hidden" "$prog" --inherit-argv0 "${@:2}"
 }
diff --git a/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix b/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix
index 8c10f67c152ce..d7699b2557fc4 100644
--- a/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix
+++ b/pkgs/build-support/setup-hooks/wrap-gapps-hook/default.nix
@@ -1,7 +1,7 @@
 { stdenv
 , lib
 , makeSetupHook
-, makeBinaryWrapper
+, makeWrapper
 , gobject-introspection
 , isGraphical ? true
 , gtk3
@@ -34,7 +34,7 @@ makeSetupHook {
   ] ++ [
 
     # We use the wrapProgram function.
-    makeBinaryWrapper
+    makeWrapper
   ];
   substitutions = {
     passthru.tests = let