summary refs log tree commit diff
path: root/pkgs/build-support/cc-wrapper/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/build-support/cc-wrapper/default.nix')
-rw-r--r--pkgs/build-support/cc-wrapper/default.nix421
1 files changed, 258 insertions, 163 deletions
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix
index 95c6bee3cc77..489fb02dcb5d 100644
--- a/pkgs/build-support/cc-wrapper/default.nix
+++ b/pkgs/build-support/cc-wrapper/default.nix
@@ -5,65 +5,125 @@
 # script that sets up the right environment variables so that the
 # compiler and the linker just "work".
 
-{ name ? "", stdenv, nativeTools, nativeLibc, nativePrefix ? ""
-, cc ? null, libc ? null, binutils ? null, coreutils ? null, shell ? stdenv.shell
+{ name ? "", stdenvNoCC, nativeTools, noLibc ? false, nativeLibc, nativePrefix ? ""
+, cc ? null, libc ? null, binutils ? null, coreutils ? null, shell ? stdenvNoCC.shell
 , zlib ? null, extraPackages ? [], extraBuildCommands ? ""
-, dyld ? null # TODO: should this be a setup-hook on dyld?
 , isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null
+, buildPackages ? {}
+, useMacosReexportHack ? false
 }:
 
-with stdenv.lib;
+with stdenvNoCC.lib;
 
 assert nativeTools -> nativePrefix != "";
 assert !nativeTools ->
   cc != null && binutils != null && coreutils != null && gnugrep != null;
-assert !nativeLibc -> libc != null;
+assert !(nativeLibc && noLibc);
+assert (noLibc || nativeLibc) == (libc == null);
 
 # For ghdl (the vhdl language provider to gcc) we need zlib in the wrapper.
 assert cc.langVhdl or false -> zlib != null;
 
 let
+  stdenv = stdenvNoCC;
+  inherit (stdenv) hostPlatform targetPlatform;
+
+  # Prefix for binaries. Customarily ends with a dash separator.
+  #
+  # TODO(@Ericson2314) Make unconditional, or optional but always true by
+  # default.
+  prefix = stdenv.lib.optionalString (targetPlatform != hostPlatform)
+                                     (targetPlatform.config + "-");
 
   ccVersion = (builtins.parseDrvName cc.name).version;
   ccName = (builtins.parseDrvName cc.name).name;
 
-  libc_bin = if nativeLibc then null else getBin libc;
-  libc_dev = if nativeLibc then null else getDev libc;
-  libc_lib = if nativeLibc then null else getLib libc;
+  libc_bin = if libc == null then null else getBin libc;
+  libc_dev = if libc == null then null else getDev libc;
+  libc_lib = if libc == null then null else getLib libc;
   cc_solib = getLib cc;
   binutils_bin = if nativeTools then "" else getBin binutils;
   # The wrapper scripts use 'cat' and 'grep', so we may need coreutils.
   coreutils_bin = if nativeTools then "" else getBin coreutils;
+
+  default_cxx_stdlib_compile=optionalString (targetPlatform.isLinux && !(cc.isGNU or false))
+    "-isystem $(echo -n ${cc.gcc}/include/c++/*) -isystem $(echo -n ${cc.gcc}/include/c++/*)/$(${cc.gcc}/bin/gcc -dumpmachine)";
+
+  dashlessTarget = stdenv.lib.replaceStrings ["-"] ["_"] targetPlatform.config;
+
+  # The "infix salt" is a arbitrary string added in the middle of env vars
+  # defined by cc-wrapper's hooks so that multiple cc-wrappers can be used
+  # without interfering. For the moment, it is defined as the target triple,
+  # adjusted to be a valid bash identifier. This should be considered an
+  # unstable implementation detail, however.
+  infixSalt = dashlessTarget;
+
+  # The dynamic linker has different names on different platforms. This is a
+  # shell glob that ought to match it.
+  dynamicLinker =
+    /**/ if libc == null then null
+    else if targetPlatform.system == "i686-linux"     then "${libc_lib}/lib/ld-linux.so.2"
+    else if targetPlatform.system == "x86_64-linux"   then "${libc_lib}/lib/ld-linux-x86-64.so.2"
+    # ARM with a wildcard, which can be "" or "-armhf".
+    else if (with targetPlatform; isArm && isLinux)   then "${libc_lib}/lib/ld-linux*.so.3"
+    else if targetPlatform.system == "aarch64-linux"  then "${libc_lib}/lib/ld-linux-aarch64.so.1"
+    else if targetPlatform.system == "powerpc-linux"  then "${libc_lib}/lib/ld.so.1"
+    else if targetPlatform.system == "mips64el-linux" then "${libc_lib}/lib/ld.so.1"
+    else if targetPlatform.isDarwin                   then "/usr/lib/dyld"
+    else if stdenv.lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1"
+    else null;
+
+  expand-response-params =
+    if buildPackages.stdenv.cc or null != null && buildPackages.stdenv.cc != "/dev/null"
+    then import ../expand-response-params { inherit (buildPackages) stdenv; }
+    else "";
+
 in
 
 stdenv.mkDerivation {
-  name =
-    (if name != "" then name else ccName + "-wrapper") +
-    (if cc != null && ccVersion != "" then "-" + ccVersion else "");
+  name = prefix
+    + (if name != "" then name else "${ccName}-wrapper")
+    + (stdenv.lib.optionalString (cc != null && ccVersion != "") "-${ccVersion}");
 
   preferLocalBuild = true;
 
-  inherit cc shell libc_bin libc_dev libc_lib binutils_bin coreutils_bin;
+  inherit cc libc_bin libc_dev libc_lib binutils_bin coreutils_bin;
+  shell = getBin shell + shell.shellPath or "";
   gnugrep_bin = if nativeTools then "" else gnugrep;
 
+  binPrefix = prefix;
+  inherit infixSalt;
+
+  outputs = [ "out" "man" ];
+
   passthru = {
-    inherit libc nativeTools nativeLibc nativePrefix isGNU isClang;
+    inherit libc nativeTools nativeLibc nativePrefix isGNU isClang default_cxx_stdlib_compile
+            prefix;
 
     emacsBufferSetup = pkgs: ''
       ; We should handle propagation here too
       (mapc (lambda (arg)
         (when (file-directory-p (concat arg "/include"))
-          (setenv "NIX_CFLAGS_COMPILE" (concat (getenv "NIX_CFLAGS_COMPILE") " -isystem " arg "/include")))
+          (setenv "NIX_${infixSalt}_CFLAGS_COMPILE" (concat (getenv "NIX_${infixSalt}_CFLAGS_COMPILE") " -isystem " arg "/include")))
         (when (file-directory-p (concat arg "/lib"))
-          (setenv "NIX_LDFLAGS" (concat (getenv "NIX_LDFLAGS") " -L" arg "/lib")))
+          (setenv "NIX_${infixSalt}_LDFLAGS" (concat (getenv "NIX_${infixSalt}_LDFLAGS") " -L" arg "/lib")))
         (when (file-directory-p (concat arg "/lib64"))
-          (setenv "NIX_LDFLAGS" (concat (getenv "NIX_LDFLAGS") " -L" arg "/lib64")))) '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
+          (setenv "NIX_${infixSalt}_LDFLAGS" (concat (getenv "NIX_${infixSalt}_LDFLAGS") " -L" arg "/lib64")))) '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
     '';
   };
 
-  buildCommand =
+  dontBuild = true;
+  dontConfigure = true;
+
+  unpackPhase = ''
+    src=$PWD
+  '';
+
+  installPhase =
     ''
-      mkdir -p $out/bin $out/nix-support
+      set -u
+
+      mkdir -p $out/bin $out/nix-support $man/nix-support
 
       wrap() {
         local dst="$1"
@@ -74,25 +134,122 @@ stdenv.mkDerivation {
       }
     ''
 
-    + optionalString (!nativeLibc) (if (!stdenv.isDarwin) then ''
-      dynamicLinker="${libc_lib}/lib/$dynamicLinker"
-      echo $dynamicLinker > $out/nix-support/dynamic-linker
+    + (if nativeTools then ''
+      echo ${if targetPlatform.isDarwin then cc else nativePrefix} > $out/nix-support/orig-cc
+
+      ccPath="${if targetPlatform.isDarwin then cc else nativePrefix}/bin"
+      ldPath="${nativePrefix}/bin"
+    '' else ''
+      echo $cc > $out/nix-support/orig-cc
+
+      ccPath="${cc}/bin"
+      ldPath="${binutils_bin}/bin"
+    ''
+
+    + optionalString (targetPlatform.isSunOS && nativePrefix != "") ''
+      # Solaris needs an additional ld wrapper.
+      ldPath="${nativePrefix}/bin"
+      exec="$ldPath/${prefix}ld"
+      wrap ld-solaris ${./ld-solaris-wrapper.sh}
+    '')
 
-      if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then
-        echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32
+    + ''
+      # Create a symlink to as (the assembler).  This is useful when a
+      # cc-wrapper is installed in a user environment, as it ensures that
+      # the right assembler is called.
+      if [ -e $ldPath/${prefix}as ]; then
+        ln -s $ldPath/${prefix}as $out/bin/${prefix}as
       fi
 
-      # The dynamic linker is passed in `ldflagsBefore' to allow
-      # explicit overrides of the dynamic linker by callers to gcc/ld
-      # (the *last* value counts, so ours should come first).
-      echo "-dynamic-linker" $dynamicLinker > $out/nix-support/libc-ldflags-before
+    '' + (if !useMacosReexportHack then ''
+      wrap ${prefix}ld ${./ld-wrapper.sh} ''${ld:-$ldPath/${prefix}ld}
     '' else ''
-      echo $dynamicLinker > $out/nix-support/dynamic-linker
+      ldInner="${prefix}ld-reexport-delegate"
+      wrap "$ldInner" ${./macos-sierra-reexport-hack.bash} ''${ld:-$ldPath/${prefix}ld}
+      wrap "${prefix}ld" ${./ld-wrapper.sh} "$out/bin/$ldInner"
+      unset ldInner
+    '') + ''
+
+      if [ -e ${binutils_bin}/bin/${prefix}ld.gold ]; then
+        wrap ${prefix}ld.gold ${./ld-wrapper.sh} ${binutils_bin}/bin/${prefix}ld.gold
+      fi
 
-      echo "export LD_DYLD_PATH=\"$dynamicLinker\"" >> $out/nix-support/setup-hook
-    '')
+      if [ -e ${binutils_bin}/bin/ld.bfd ]; then
+        wrap ${prefix}ld.bfd ${./ld-wrapper.sh} ${binutils_bin}/bin/${prefix}ld.bfd
+      fi
+
+      # We export environment variables pointing to the wrapped nonstandard
+      # cmds, lest some lousy configure script use those to guess compiler
+      # version.
+      export named_cc=${prefix}cc
+      export named_cxx=${prefix}c++
+
+      export default_cxx_stdlib_compile="${default_cxx_stdlib_compile}"
+
+      if [ -e $ccPath/${prefix}gcc ]; then
+        wrap ${prefix}gcc ${./cc-wrapper.sh} $ccPath/${prefix}gcc
+        ln -s ${prefix}gcc $out/bin/${prefix}cc
+        export named_cc=${prefix}gcc
+        export named_cxx=${prefix}g++
+      elif [ -e $ccPath/clang ]; then
+        wrap ${prefix}clang ${./cc-wrapper.sh} $ccPath/clang
+        ln -s ${prefix}clang $out/bin/${prefix}cc
+        export named_cc=${prefix}clang
+        export named_cxx=${prefix}clang++
+      fi
+
+      if [ -e $ccPath/${prefix}g++ ]; then
+        wrap ${prefix}g++ ${./cc-wrapper.sh} $ccPath/${prefix}g++
+        ln -s ${prefix}g++ $out/bin/${prefix}c++
+      elif [ -e $ccPath/clang++ ]; then
+        wrap ${prefix}clang++ ${./cc-wrapper.sh} $ccPath/clang++
+        ln -s ${prefix}clang++ $out/bin/${prefix}c++
+      fi
+
+      if [ -e $ccPath/cpp ]; then
+        wrap ${prefix}cpp ${./cc-wrapper.sh} $ccPath/cpp
+      fi
+    ''
+
+    + optionalString cc.langFortran or false ''
+      wrap ${prefix}gfortran ${./cc-wrapper.sh} $ccPath/${prefix}gfortran
+      ln -sv ${prefix}gfortran $out/bin/${prefix}g77
+      ln -sv ${prefix}gfortran $out/bin/${prefix}f77
+    ''
+
+    + optionalString cc.langJava or false ''
+      wrap ${prefix}gcj ${./cc-wrapper.sh} $ccPath/${prefix}gcj
+    ''
+
+    + optionalString cc.langGo or false ''
+      wrap ${prefix}gccgo ${./cc-wrapper.sh} $ccPath/${prefix}gccgo
+    ''
+
+    + optionalString cc.langAda or false ''
+      wrap ${prefix}gnatgcc ${./cc-wrapper.sh} $ccPath/${prefix}gnatgcc
+      wrap ${prefix}gnatmake ${./gnat-wrapper.sh} $ccPath/${prefix}gnatmake
+      wrap ${prefix}gnatbind ${./gnat-wrapper.sh} $ccPath/${prefix}gnatbind
+      wrap ${prefix}gnatlink ${./gnatlink-wrapper.sh} $ccPath/${prefix}gnatlink
+    ''
+
+    + optionalString cc.langVhdl or false ''
+      ln -s $ccPath/${prefix}ghdl $out/bin/${prefix}ghdl
+    '';
+
+  propagatedBuildInputs = extraPackages;
+
+  setupHook = ./setup-hook.sh;
+
+  postFixup =
+    ''
+      set -u
+    ''
+
+    + optionalString (libc != null) (''
+      ##
+      ## General libc support
+      ##
 
-    + optionalString (!nativeLibc) ''
       # The "-B${libc_lib}/lib/" flag is a quick hack to force gcc to link
       # against the crt1.o from our own glibc, rather than the one in
       # /usr/lib.  (This is only an issue when using an `impure'
@@ -110,13 +267,50 @@ stdenv.mkDerivation {
 
       echo "${libc_lib}" > $out/nix-support/orig-libc
       echo "${libc_dev}" > $out/nix-support/orig-libc-dev
-    ''
 
-    + (if nativeTools then ''
-      ccPath="${if stdenv.isDarwin then cc else nativePrefix}/bin"
-      ldPath="${nativePrefix}/bin"
+      ##
+      ## Dynamic linker support
+      ##
+
+      if [[ -z ''${dynamicLinker+x} ]]; then
+        echo "Don't know the name of the dynamic linker for platform '${targetPlatform.config}', so guessing instead." >&2
+        local dynamicLinker="${libc_lib}/lib/ld*.so.?"
+      fi
+
+      # Expand globs to fill array of options
+      dynamicLinker=($dynamicLinker)
+
+      case ''${#dynamicLinker[@]} in
+        0) echo "No dynamic linker found for platform '${targetPlatform.config}'." >&2;;
+        1) echo "Using dynamic linker: '$dynamicLinker'" >&2;;
+        *) echo "Multiple dynamic linkers found for platform '${targetPlatform.config}'." >&2;;
+      esac
+
+      if [ -n "$dynamicLinker" ]; then
+        echo $dynamicLinker > $out/nix-support/dynamic-linker
+
+    '' + (if targetPlatform.isDarwin then ''
+        printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook
     '' else ''
-      echo $cc > $out/nix-support/orig-cc
+        if [ -e ${libc_lib}/lib/32/ld-linux.so.2 ]; then
+          echo ${libc_lib}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32
+        fi
+
+        local ldflagsBefore=(-dynamic-linker "$dynamicLinker")
+    '') + ''
+      fi
+
+      # The dynamic linker is passed in `ldflagsBefore' to allow
+      # explicit overrides of the dynamic linker by callers to gcc/ld
+      # (the *last* value counts, so ours should come first).
+      printWords "''${ldflagsBefore[@]}" > $out/nix-support/libc-ldflags-before
+    '')
+
+    + optionalString (!nativeTools) ''
+
+      ##
+      ## Initial CFLAGS
+      ##
 
       # GCC shows ${cc_solib}/lib in `gcc -print-search-dirs', but not
       # ${cc_solib}/lib64 (even though it does actually search there...)..
@@ -141,157 +335,56 @@ stdenv.mkDerivation {
         echo "$gnatCFlags" > $out/nix-support/gnat-cflags
       ''}
 
-      if [ -e $ccPath/clang ]; then
-        # Need files like crtbegin.o from gcc
-        # It's unclear if these will ever be provided by an LLVM project
-        ccCFlags="$ccCFlags -B$basePath"
-        ccCFlags="$ccCFlags -isystem$cc/lib/clang/$ccVersion/include"
-      fi
-
       echo "$ccLDFlags" > $out/nix-support/cc-ldflags
       echo "$ccCFlags" > $out/nix-support/cc-cflags
 
-      ccPath="${cc}/bin"
-      ldPath="${binutils_bin}/bin"
+      ##
+      ## User env support
+      ##
 
       # Propagate the wrapped cc so that if you install the wrapper,
       # you get tools like gcov, the manpages, etc. as well (including
       # for binutils and Glibc).
-      echo ${cc} ${cc.man or ""} ${binutils_bin} ${libc_bin} > $out/nix-support/propagated-user-env-packages
-
-      echo ${toString extraPackages} > $out/nix-support/propagated-native-build-inputs
+      printWords ${cc} ${binutils_bin} ${if libc == null then "" else libc_bin} > $out/nix-support/propagated-user-env-packages
+      printWords ${cc.man or ""}  > $man/nix-support/propagated-user-env-packages
     ''
 
-    + optionalString (stdenv.isSunOS && nativePrefix != "") ''
-      # Solaris needs an additional ld wrapper.
-      ldPath="${nativePrefix}/bin"
-      exec="$ldPath/ld"
-      wrap ld-solaris ${./ld-solaris-wrapper.sh}
-    '')
-
     + ''
-      # Create a symlink to as (the assembler).  This is useful when a
-      # cc-wrapper is installed in a user environment, as it ensures that
-      # the right assembler is called.
-      if [ -e $ldPath/as ]; then
-        ln -s $ldPath/as $out/bin/as
-      fi
-
-      wrap ld ${./ld-wrapper.sh} ''${ld:-$ldPath/ld}
-
-      if [ -e ${binutils_bin}/bin/ld.gold ]; then
-        wrap ld.gold ${./ld-wrapper.sh} ${binutils_bin}/bin/ld.gold
-      fi
-
-      if [ -e ${binutils_bin}/bin/ld.bfd ]; then
-        wrap ld.bfd ${./ld-wrapper.sh} ${binutils_bin}/bin/ld.bfd
-      fi
 
-      export real_cc=cc
-      export real_cxx=c++
-      export default_cxx_stdlib_compile="${
-        if stdenv.isLinux && !(cc.isGNU or false)
-          then "-isystem $(echo -n ${cc.gcc}/include/c++/*) -isystem $(echo -n ${cc.gcc}/include/c++/*)/$(${cc.gcc}/bin/gcc -dumpmachine)"
-          else ""
-      }"
-
-      if [ -e $ccPath/gcc ]; then
-        wrap gcc ${./cc-wrapper.sh} $ccPath/gcc
-        ln -s gcc $out/bin/cc
-        export real_cc=gcc
-        export real_cxx=g++
-      elif [ -e $ccPath/clang ]; then
-        wrap clang ${./cc-wrapper.sh} $ccPath/clang
-        ln -s clang $out/bin/cc
-        export real_cc=clang
-        export real_cxx=clang++
-      fi
+      ##
+      ## Hardening support
+      ##
 
-      if [ -e $ccPath/g++ ]; then
-        wrap g++ ${./cc-wrapper.sh} $ccPath/g++
-        ln -s g++ $out/bin/c++
-      elif [ -e $ccPath/clang++ ]; then
-        wrap clang++ ${./cc-wrapper.sh} $ccPath/clang++
-        ln -s clang++ $out/bin/c++
+      # some linkers on some platforms don't support specific -z flags
+      export hardening_unsupported_flags=""
+      if [[ "$($ldPath/${prefix}ld -z now 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
+        hardening_unsupported_flags+=" bindnow"
       fi
-
-      if [ -e $ccPath/cpp ]; then
-        wrap cpp ${./cc-wrapper.sh} $ccPath/cpp
+      if [[ "$($ldPath/${prefix}ld -z relro 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
+        hardening_unsupported_flags+=" relro"
       fi
     ''
 
-    + optionalString cc.langFortran or false ''
-      wrap gfortran ${./cc-wrapper.sh} $ccPath/gfortran
-      ln -sv gfortran $out/bin/g77
-      ln -sv gfortran $out/bin/f77
-    ''
-
-    + optionalString cc.langJava or false ''
-      wrap gcj ${./cc-wrapper.sh} $ccPath/gcj
-    ''
-
-    + optionalString cc.langGo or false ''
-      wrap gccgo ${./cc-wrapper.sh} $ccPath/gccgo
-    ''
-
-    + optionalString cc.langAda or false ''
-      wrap gnatgcc ${./cc-wrapper.sh} $ccPath/gnatgcc
-      wrap gnatmake ${./gnat-wrapper.sh} $ccPath/gnatmake
-      wrap gnatbind ${./gnat-wrapper.sh} $ccPath/gnatbind
-      wrap gnatlink ${./gnatlink-wrapper.sh} $ccPath/gnatlink
-    ''
-
-    + optionalString cc.langVhdl or false ''
-      ln -s $ccPath/ghdl $out/bin/ghdl
+    + optionalString hostPlatform.isCygwin ''
+      hardening_unsupported_flags+=" pic"
     ''
 
     + ''
-      substituteAll ${./setup-hook.sh} $out/nix-support/setup-hook.tmp
-      cat $out/nix-support/setup-hook.tmp >> $out/nix-support/setup-hook
-      rm $out/nix-support/setup-hook.tmp
-
-      # some linkers on some platforms don't support specific -z flags
-      hardening_unsupported_flags=""
-      if [[ "$($ldPath/ld -z now 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
-        hardening_unsupported_flags+=" bindnow"
-      fi
-      if [[ "$($ldPath/ld -z relro 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
-        hardening_unsupported_flags+=" relro"
-      fi
-
       substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh
       substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh
-      cp -p ${./utils.sh} $out/nix-support/utils.sh
+      substituteAll ${./utils.sh} $out/nix-support/utils.sh
+
+      ##
+      ## Extra custom steps
+      ##
+
     ''
     + extraBuildCommands;
 
-  # The dynamic linker has different names on different Linux platforms.
-  dynamicLinker =
-    if !nativeLibc then
-      (if stdenv.system == "i686-linux" then "ld-linux.so.2" else
-       if stdenv.system == "x86_64-linux" then "ld-linux-x86-64.so.2" else
-       # ARM with a wildcard, which can be "" or "-armhf".
-       if stdenv.isArm then "ld-linux*.so.3" else
-       if stdenv.system == "aarch64-linux" then "ld-linux-aarch64.so.1" else
-       if stdenv.system == "powerpc-linux" then "ld.so.1" else
-       if stdenv.system == "mips64el-linux" then "ld.so.1" else
-       if stdenv.system == "x86_64-darwin" then "/usr/lib/dyld" else
-       abort "Don't know the name of the dynamic linker for this platform.")
-    else "";
+  inherit dynamicLinker expand-response-params;
 
-  crossAttrs = {
-    shell = shell.crossDrv + shell.crossDrv.shellPath;
-    libc = stdenv.ccCross.libc;
-    #
-    # This is not the best way to do this. I think the reference should be
-    # the style in the gcc-cross-wrapper, but to keep a stable stdenv now I
-    # do this sufficient if/else.
-    dynamicLinker =
-      (if stdenv.cross.arch == "arm" then "ld-linux.so.3" else
-       if stdenv.cross.arch == "mips" then "ld.so.1" else
-       if stdenv.lib.hasSuffix "pc-gnu" stdenv.cross.config then "ld.so.1" else
-       abort "don't know the name of the dynamic linker for this platform");
-  };
+  # for substitution in utils.sh
+  expandResponseParams = "${expand-response-params}/bin/expand-response-params";
 
   meta =
     let cc_ = if cc != null then cc else {}; in
@@ -299,5 +392,7 @@ stdenv.mkDerivation {
     { description =
         stdenv.lib.attrByPath ["meta" "description"] "System C compiler" cc_
         + " (wrapper script)";
-    };
+  } // optionalAttrs useMacosReexportHack {
+    platforms = stdenv.lib.platforms.darwin;
+  };
 }