From 287fce6402100c40317233de6b4f749f2b79b0a5 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 23 Aug 2017 16:23:30 -0400 Subject: [PATCH 1/4] expand-response-params: Pull out of cc-wrapper No hashes were changed --- pkgs/build-support/cc-wrapper/default.nix | 16 ++++------------ .../expand-response-params/default.nix | 13 +++++++++++++ .../expand-response-params.c | 0 3 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 pkgs/build-support/expand-response-params/default.nix rename pkgs/build-support/{cc-wrapper => expand-response-params}/expand-response-params.c (100%) diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 525cb07ac32aa..d5ae64c9c5ff1 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -74,18 +74,10 @@ let 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 buildPackages.stdenv.mkDerivation { - name = "expand-response-params"; - src = ./expand-response-params.c; - buildCommand = '' - # Work around "stdenv-darwin-boot-2 is not allowed to refer to path /nix/store/...-expand-response-params.c" - cp "$src" expand-response-params.c - "$CC" -std=c99 -O3 -o "$out" expand-response-params.c - strip -S $out - ${optionalString hostPlatform.isLinux "patchelf --shrink-rpath $out"} - ''; - } else ""; + 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 diff --git a/pkgs/build-support/expand-response-params/default.nix b/pkgs/build-support/expand-response-params/default.nix new file mode 100644 index 0000000000000..7afbb727fc3ee --- /dev/null +++ b/pkgs/build-support/expand-response-params/default.nix @@ -0,0 +1,13 @@ +{ stdenv }: + +stdenv.mkDerivation { + name = "expand-response-params"; + src = ./expand-response-params.c; + buildCommand = '' + # Work around "stdenv-darwin-boot-2 is not allowed to refer to path /nix/store/...-expand-response-params.c" + cp "$src" expand-response-params.c + "$CC" -std=c99 -O3 -o "$out" expand-response-params.c + strip -S $out + ${stdenv.lib.optionalString stdenv.hostPlatform.isLinux "patchelf --shrink-rpath $out"} + ''; +} diff --git a/pkgs/build-support/cc-wrapper/expand-response-params.c b/pkgs/build-support/expand-response-params/expand-response-params.c similarity index 100% rename from pkgs/build-support/cc-wrapper/expand-response-params.c rename to pkgs/build-support/expand-response-params/expand-response-params.c From a470be5a16e54ebdda7d1e61ca1e74f82aed3199 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 23 Aug 2017 16:39:15 -0400 Subject: [PATCH 2/4] expand-response-params: Build more normally --- pkgs/build-support/cc-wrapper/default.nix | 3 ++- pkgs/build-support/cc-wrapper/utils.sh | 2 +- .../expand-response-params/default.nix | 16 +++++++++++----- pkgs/stdenv/linux/default.nix | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index d5ae64c9c5ff1..bb95c1807ab9e 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -342,7 +342,8 @@ stdenv.mkDerivation { inherit dynamicLinker expand-response-params; - expandResponseParams = expand-response-params; # for substitution in utils.sh + # for substitution in utils.sh + expandResponseParams = "${expand-response-params}/bin/expand-response-params"; crossAttrs = { shell = shell.crossDrv + shell.crossDrv.shellPath; diff --git a/pkgs/build-support/cc-wrapper/utils.sh b/pkgs/build-support/cc-wrapper/utils.sh index 7e9979f10ae8a..c84a094e26b0f 100644 --- a/pkgs/build-support/cc-wrapper/utils.sh +++ b/pkgs/build-support/cc-wrapper/utils.sh @@ -30,7 +30,7 @@ expandResponseParams() { if [[ "$arg" == @* ]]; then # phase separation makes this look useless # shellcheck disable=SC2157 - if [ -n "@expandResponseParams@" ]; then + if [ -x "@expandResponseParams@" ]; then # params is used by caller #shellcheck disable=SC2034 readarray -d '' params < <("@expandResponseParams@" "$@") diff --git a/pkgs/build-support/expand-response-params/default.nix b/pkgs/build-support/expand-response-params/default.nix index 7afbb727fc3ee..2a4bee74197b2 100644 --- a/pkgs/build-support/expand-response-params/default.nix +++ b/pkgs/build-support/expand-response-params/default.nix @@ -3,11 +3,17 @@ stdenv.mkDerivation { name = "expand-response-params"; src = ./expand-response-params.c; - buildCommand = '' - # Work around "stdenv-darwin-boot-2 is not allowed to refer to path /nix/store/...-expand-response-params.c" + # Work around "stdenv-darwin-boot-2 is not allowed to refer to path + # /nix/store/...-expand-response-params.c" + unpackPhase = '' cp "$src" expand-response-params.c - "$CC" -std=c99 -O3 -o "$out" expand-response-params.c - strip -S $out - ${stdenv.lib.optionalString stdenv.hostPlatform.isLinux "patchelf --shrink-rpath $out"} + src=$PWD + ''; + buildPhase = '' + "$CC" -std=c99 -O3 -o "expand-response-params" expand-response-params.c + ''; + installPhase = '' + mkdir -p $prefix/bin + mv expand-response-params $prefix/bin/ ''; } diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index 48deb9a5c02cf..fab1985b9765c 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -310,7 +310,7 @@ in # More complicated cases ++ [ glibc.out glibc.dev glibc.bin/*propagated from .dev*/ linuxHeaders - gcc gcc.cc gcc.cc.lib gcc.expandResponseParams + gcc gcc.cc gcc.cc.lib gcc.expand-response-params ] ++ lib.optionals (system == "aarch64-linux") [ prevStage.updateAutotoolsGnuConfigScriptsHook prevStage.gnu-config ]; From dc47e763c15b54ece609e08d0496462a11862cd6 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 23 Aug 2017 17:30:56 -0400 Subject: [PATCH 3/4] cc-wrapper: Use `set -u` for better maintainability --- pkgs/build-support/cc-wrapper/default.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index bb95c1807ab9e..696e43369a7ac 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -114,6 +114,8 @@ stdenv.mkDerivation { buildCommand = '' + set -u + mkdir -p $out/bin $out/nix-support $man/nix-support wrap() { @@ -320,7 +322,7 @@ stdenv.mkDerivation { rm $out/nix-support/setup-hook.tmp # some linkers on some platforms don't support specific -z flags - hardening_unsupported_flags="" + export hardening_unsupported_flags="" if [[ "$($ldPath/${prefix}ld -z now 2>&1 || true)" =~ un(recognized|known)\ option ]]; then hardening_unsupported_flags+=" bindnow" fi From df7c305c4cba1c69f61086be64ff9bbdacb5a31b Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 23 Aug 2017 16:55:55 -0400 Subject: [PATCH 4/4] cc-wrapper: Leverage the setup script instead of `buildCommand` --- pkgs/build-support/cc-wrapper/default.nix | 225 +++++++++++++--------- 1 file changed, 132 insertions(+), 93 deletions(-) diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 696e43369a7ac..0114170b8ebc2 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -112,7 +112,14 @@ stdenv.mkDerivation { ''; }; - buildCommand = + dontBuild = true; + dontConfigure = true; + + unpackPhase = '' + src=$PWD + ''; + + installPhase = '' set -u @@ -127,103 +134,16 @@ stdenv.mkDerivation { } '' - + optionalString (libc != null) ('' - if [[ -z ''${dynamicLinker+x} ]]; then - echo "Don't know the name of the dynamic linker for platform '${targetPlatform.config}', so guessing instead." >&2 - 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 '' - 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 - - 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 (libc != null) '' - # 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' - # compiler/linker, i.e., one that searches /usr/lib and so on.) - # - # Unfortunately, setting -B appears to override the default search - # path. Thus, the gcc-specific "../includes-fixed" directory is - # now longer searched and glibc's header fails to - # compile, because it uses "#include_next " to find the - # limits.h file in ../includes-fixed. To remedy the problem, - # another -idirafter is necessary to add that directory again. - echo "-B${libc_lib}/lib/ -idirafter ${libc_dev}/include -idirafter ${cc}/lib/gcc/*/*/include-fixed" > $out/nix-support/libc-cflags - - echo "-L${libc_lib}/lib" > $out/nix-support/libc-ldflags - - echo "${libc_lib}" > $out/nix-support/orig-libc - echo "${libc_dev}" > $out/nix-support/orig-libc-dev - '' - + (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 - # GCC shows ${cc_solib}/lib in `gcc -print-search-dirs', but not - # ${cc_solib}/lib64 (even though it does actually search there...).. - # This confuses libtool. So add it to the compiler tool search - # path explicitly. - if [ -e "${cc_solib}/lib64" -a ! -L "${cc_solib}/lib64" ]; then - ccLDFlags+=" -L${cc_solib}/lib64" - ccCFlags+=" -B${cc_solib}/lib64" - fi - ccLDFlags+=" -L${cc_solib}/lib" - ccCFlags+=" -B${cc_solib}/lib" - - ${optionalString cc.langVhdl or false '' - ccLDFlags+=" -L${zlib.out}/lib" - ''} - - # Find the gcc libraries path (may work only without multilib). - ${optionalString cc.langAda or false '' - basePath=`echo ${cc_solib}/lib/*/*/*` - ccCFlags+=" -B$basePath -I$basePath/adainclude" - gnatCFlags="-aI$basePath/adainclude -aO$basePath/adalib" - echo "$gnatCFlags" > $out/nix-support/gnat-cflags - ''} - - echo "$ccLDFlags" > $out/nix-support/cc-ldflags - echo "$ccCFlags" > $out/nix-support/cc-cflags - ccPath="${cc}/bin" ldPath="${binutils_bin}/bin" - - # 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). - 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 - - printWords ${toString extraPackages} > $out/nix-support/propagated-native-build-inputs '' + optionalString (targetPlatform.isSunOS && nativePrefix != "") '' @@ -314,12 +234,126 @@ stdenv.mkDerivation { + 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 + ## + + # 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' + # compiler/linker, i.e., one that searches /usr/lib and so on.) + # + # Unfortunately, setting -B appears to override the default search + # path. Thus, the gcc-specific "../includes-fixed" directory is + # now longer searched and glibc's header fails to + # compile, because it uses "#include_next " to find the + # limits.h file in ../includes-fixed. To remedy the problem, + # another -idirafter is necessary to add that directory again. + echo "-B${libc_lib}/lib/ -idirafter ${libc_dev}/include -idirafter ${cc}/lib/gcc/*/*/include-fixed" > $out/nix-support/libc-cflags + + echo "-L${libc_lib}/lib" > $out/nix-support/libc-ldflags + + echo "${libc_lib}" > $out/nix-support/orig-libc + echo "${libc_dev}" > $out/nix-support/orig-libc-dev + + ## + ## 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 '' + 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...).. + # This confuses libtool. So add it to the compiler tool search + # path explicitly. + if [ -e "${cc_solib}/lib64" -a ! -L "${cc_solib}/lib64" ]; then + ccLDFlags+=" -L${cc_solib}/lib64" + ccCFlags+=" -B${cc_solib}/lib64" + fi + ccLDFlags+=" -L${cc_solib}/lib" + ccCFlags+=" -B${cc_solib}/lib" + + ${optionalString cc.langVhdl or false '' + ccLDFlags+=" -L${zlib.out}/lib" + ''} + + # Find the gcc libraries path (may work only without multilib). + ${optionalString cc.langAda or false '' + basePath=`echo ${cc_solib}/lib/*/*/*` + ccCFlags+=" -B$basePath -I$basePath/adainclude" + gnatCFlags="-aI$basePath/adainclude -aO$basePath/adalib" + echo "$gnatCFlags" > $out/nix-support/gnat-cflags + ''} + + echo "$ccLDFlags" > $out/nix-support/cc-ldflags + echo "$ccCFlags" > $out/nix-support/cc-cflags + + ## + ## 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). + 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 '' + '' - 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 + + ## + ## Hardening support + ## # some linkers on some platforms don't support specific -z flags export hardening_unsupported_flags="" @@ -339,6 +373,11 @@ stdenv.mkDerivation { substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh substituteAll ${./utils.sh} $out/nix-support/utils.sh + + ## + ## Extra custom steps + ## + '' + extraBuildCommands;