diff options
Diffstat (limited to 'pkgs/build-support')
14 files changed, 323 insertions, 65 deletions
diff --git a/pkgs/build-support/bintools-wrapper/darwin-install_name_tool-wrapper.sh b/pkgs/build-support/bintools-wrapper/darwin-install_name_tool-wrapper.sh new file mode 100755 index 000000000000..376a7abfe41c --- /dev/null +++ b/pkgs/build-support/bintools-wrapper/darwin-install_name_tool-wrapper.sh @@ -0,0 +1,49 @@ +#! @shell@ +# shellcheck shell=bash + +set -eu -o pipefail +o posix +shopt -s nullglob + +if (( "${NIX_DEBUG:-0}" >= 7 )); then + set -x +fi + +source @signingUtils@ + +extraAfter=() +extraBefore=() +params=("$@") + +input= + +pprev= +prev= +for p in \ + ${extraBefore+"${extraBefore[@]}"} \ + ${params+"${params[@]}"} \ + ${extraAfter+"${extraAfter[@]}"} +do + if [ "$pprev" != "-change" ] && [[ "$prev" != -* ]] && [[ "$p" != -* ]]; then + input="$p" + fi + pprev="$prev" + prev="$p" +done + +# Optionally print debug info. +if (( "${NIX_DEBUG:-0}" >= 1 )); then + # Old bash workaround, see above. + echo "extra flags before to @prog@:" >&2 + printf " %q\n" ${extraBefore+"${extraBefore[@]}"} >&2 + echo "original flags to @prog@:" >&2 + printf " %q\n" ${params+"${params[@]}"} >&2 + echo "extra flags after to @prog@:" >&2 + printf " %q\n" ${extraAfter+"${extraAfter[@]}"} >&2 +fi + +@prog@ \ + ${extraBefore+"${extraBefore[@]}"} \ + ${params+"${params[@]}"} \ + ${extraAfter+"${extraAfter[@]}"} + +sign "$input" diff --git a/pkgs/build-support/bintools-wrapper/darwin-strip-wrapper.sh b/pkgs/build-support/bintools-wrapper/darwin-strip-wrapper.sh new file mode 100755 index 000000000000..a67699547a6f --- /dev/null +++ b/pkgs/build-support/bintools-wrapper/darwin-strip-wrapper.sh @@ -0,0 +1,78 @@ +#! @shell@ +# shellcheck shell=bash + +set -eu -o pipefail +o posix +shopt -s nullglob + +if (( "${NIX_DEBUG:-0}" >= 7 )); then + set -x +fi + +source @signingUtils@ + +extraAfter=() +extraBefore=() +params=("$@") + +output= +inputs=() + +restAreFiles= +prev= +for p in \ + ${extraBefore+"${extraBefore[@]}"} \ + ${params+"${params[@]}"} \ + ${extraAfter+"${extraAfter[@]}"} +do + if [ "$restAreFiles" ]; then + inputs+=("$p") + else + case "$prev" in + -s|-R|-d|-arch) + # Unrelated arguments with values + ;; + -o) + # Explicit output + output="$p" + ;; + *) + # Any other orgument either takes no value, or is a file. + if [[ "$p" != -* ]]; then + inputs+=("$p") + fi + ;; + esac + + if [ "$p" == - ]; then + restAreFiles=1 + fi + fi + + prev="$p" +done + +# Optionally print debug info. +if (( "${NIX_DEBUG:-0}" >= 1 )); then + # Old bash workaround, see above. + echo "extra flags before to @prog@:" >&2 + printf " %q\n" ${extraBefore+"${extraBefore[@]}"} >&2 + echo "original flags to @prog@:" >&2 + printf " %q\n" ${params+"${params[@]}"} >&2 + echo "extra flags after to @prog@:" >&2 + printf " %q\n" ${extraAfter+"${extraAfter[@]}"} >&2 +fi + +@prog@ \ + ${extraBefore+"${extraBefore[@]}"} \ + ${params+"${params[@]}"} \ + ${extraAfter+"${extraAfter[@]}"} + +if [ "$output" ]; then + # Single explicit output + signIfRequired "$output" +else + # Multiple inputs, rewritten in place + for input in "${inputs[@]}"; do + signIfRequired "$input" + done +fi diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index 859e37905949..b2b47901981d 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -14,6 +14,9 @@ , extraPackages ? [], extraBuildCommands ? "" , buildPackages ? {} , useMacosReexportHack ? false + +# Darwin code signing support utilities +, postLinkSignHook ? null, signingUtils ? null }: with lib; @@ -340,6 +343,24 @@ stdenv.mkDerivation { ) ## + ## Code signing on Apple Silicon + ## + + optionalString (targetPlatform.isDarwin && targetPlatform.isAarch64) '' + echo 'source ${postLinkSignHook}' >> $out/nix-support/post-link-hook + + export signingUtils=${signingUtils} + + wrap \ + ${targetPrefix}install_name_tool \ + ${./darwin-install_name_tool-wrapper.sh} \ + "${bintools_bin}/bin/${targetPrefix}install_name_tool" + + wrap \ + ${targetPrefix}strip ${./darwin-strip-wrapper.sh} \ + "${bintools_bin}/bin/${targetPrefix}strip" + '' + + ## ## Extra custom steps ## + extraBuildCommands; diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh index 7ccf5510c880..e54dd6f47146 100644 --- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh +++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh @@ -102,6 +102,8 @@ declare -a libDirs declare -A libs declare -i relocatable=0 link32=0 +linkerOutput="a.out" + if [ "$NIX_DONT_SET_RPATH_@suffixSalt@" != 1 ] \ || [ "$NIX_SET_BUILD_ID_@suffixSalt@" = 1 ] \ @@ -153,6 +155,24 @@ then done fi +# Determine linkerOutput +prev= +for p in \ + ${extraBefore+"${extraBefore[@]}"} \ + ${params+"${params[@]}"} \ + ${extraAfter+"${extraAfter[@]}"} +do + case "$prev" in + -o) + # Informational for post-link-hook + linkerOutput="$p" + ;; + *) + ;; + esac + prev="$p" +done + if [[ "$link32" = "1" && "$setDynamicLinker" = 1 && -e "@out@/nix-support/dynamic-linker-m32" ]]; then # We have an alternate 32-bit linker and we're producing a 32-bit ELF, let's # use it. @@ -223,7 +243,11 @@ fi PATH="$path_backup" # Old bash workaround, see above. -exec @prog@ \ +@prog@ \ ${extraBefore+"${extraBefore[@]}"} \ ${params+"${params[@]}"} \ ${extraAfter+"${extraAfter[@]}"} + +if [ -e "@out@/nix-support/post-link-hook" ]; then + source @out@/nix-support/post-link-hook +fi diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 36a98a180b3e..235d244a7c0d 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -64,6 +64,7 @@ let useGccForLibs = isClang && libcxx == null + && !stdenv.targetPlatform.isDarwin && !(stdenv.targetPlatform.useLLVM or false) && !(stdenv.targetPlatform.useAndroidPrebuilt or false) && !(stdenv.targetPlatform.isiOS or false) @@ -432,14 +433,16 @@ stdenv.mkDerivation { # Always add -march based on cpu in triple. Sometimes there is a # discrepency (x86_64 vs. x86-64), so we provide an "arch" arg in # that case. - + optionalString ((targetPlatform ? gcc.arch) && + # TODO: aarch64-darwin has mcpu incompatible with gcc + + optionalString ((targetPlatform ? gcc.arch) && (isClang || !(stdenv.isDarwin && stdenv.isAarch64)) && isGccArchSupported targetPlatform.gcc.arch) '' echo "-march=${targetPlatform.gcc.arch}" >> $out/nix-support/cc-cflags-before '' # -mcpu is not very useful. You should use mtune and march # instead. It’s provided here for backwards compatibility. - + optionalString (targetPlatform ? gcc.cpu) '' + # TODO: aarch64-darwin has mcpu incompatible with gcc + + optionalString ((targetPlatform ? gcc.cpu) && (isClang || !(stdenv.isDarwin && stdenv.isAarch64))) '' echo "-mcpu=${targetPlatform.gcc.cpu}" >> $out/nix-support/cc-cflags-before '' @@ -491,6 +494,10 @@ stdenv.mkDerivation { echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/cc-cflags '' + + optionalString targetPlatform.isAndroid '' + echo "-D__ANDROID_API__=${targetPlatform.sdkVer}" >> $out/nix-support/cc-cflags + '' + # There are a few tools (to name one libstdcxx5) which do not work # well with multi line flags, so make the flags single line again + '' diff --git a/pkgs/build-support/nuke-references/builder.sh b/pkgs/build-support/nuke-references/builder.sh deleted file mode 100644 index 7da322032185..000000000000 --- a/pkgs/build-support/nuke-references/builder.sh +++ /dev/null @@ -1,29 +0,0 @@ -source $stdenv/setup - -mkdir -p $out/bin -cat > $out/bin/nuke-refs <<EOF -#! $SHELL -e - -excludes="" -while getopts e: o; do - case "\$o" in - e) storeId=\$(echo "\$OPTARG" | $perl/bin/perl -ne "print \"\\\$1\" if m|^\Q$NIX_STORE\E/([a-z0-9]{32})-.*|") - if [ -z "\$storeId" ]; then - echo "-e argument must be a Nix store path" - exit 1 - fi - excludes="\$excludes(?!\$storeId)" - ;; - esac -done -shift \$((\$OPTIND-1)) - -for i in "\$@"; do - if test ! -L "\$i" -a -f "\$i"; then - cat "\$i" | $perl/bin/perl -pe "s|\Q$NIX_STORE\E/\$excludes[a-z0-9]{32}-|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" > "\$i.tmp" - if test -x "\$i"; then chmod +x "\$i.tmp"; fi - mv "\$i.tmp" "\$i" - fi -done -EOF -chmod +x $out/bin/nuke-refs diff --git a/pkgs/build-support/nuke-references/darwin-sign-fixup.sh b/pkgs/build-support/nuke-references/darwin-sign-fixup.sh new file mode 100644 index 000000000000..940c18e5a627 --- /dev/null +++ b/pkgs/build-support/nuke-references/darwin-sign-fixup.sh @@ -0,0 +1,5 @@ +# Fixup hook for nukeReferences, not stdenv + +source @signingUtils@ + +fixupHooks+=(signIfRequired) diff --git a/pkgs/build-support/nuke-references/default.nix b/pkgs/build-support/nuke-references/default.nix index d894b56d366a..03f6fe53b544 100644 --- a/pkgs/build-support/nuke-references/default.nix +++ b/pkgs/build-support/nuke-references/default.nix @@ -3,11 +3,35 @@ # path (/nix/store/eeee...). This is useful for getting rid of # dependencies that you know are not actually needed at runtime. -{ stdenvNoCC, perl }: +{ lib, stdenvNoCC, perl, signingUtils, shell ? stdenvNoCC.shell }: + +let + stdenv = stdenvNoCC; + + darwinCodeSign = stdenv.targetPlatform.isDarwin && stdenv.targetPlatform.isAarch64; +in stdenvNoCC.mkDerivation { name = "nuke-references"; - builder = ./builder.sh; + + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + + installPhase = '' + mkdir -p $out/bin + substituteAll ${./nuke-refs.sh} $out/bin/nuke-refs + chmod a+x $out/bin/nuke-refs + ''; + + postFixup = lib.optionalString darwinCodeSign '' + mkdir -p $out/nix-support + substituteAll ${./darwin-sign-fixup.sh} $out/nix-support/setup-hooks.sh + ''; + # FIXME: get rid of perl dependency. inherit perl; + inherit (builtins) storeDir; + shell = lib.getBin shell + (shell.shellPath or ""); + signingUtils = if darwinCodeSign then signingUtils else null; } diff --git a/pkgs/build-support/nuke-references/nuke-refs.sh b/pkgs/build-support/nuke-references/nuke-refs.sh new file mode 100644 index 000000000000..21eb855cbad9 --- /dev/null +++ b/pkgs/build-support/nuke-references/nuke-refs.sh @@ -0,0 +1,33 @@ +#! @shell@ + +fixupHooks=() + +if [ -e @out@/nix-support/setup-hooks.sh ]; then + source @out@/nix-support/setup-hooks.sh +fi + +excludes="" +while getopts e: o; do + case "$o" in + e) storeId=$(echo "$OPTARG" | @perl@/bin/perl -ne "print \"\$1\" if m|^\Q@storeDir@\E/([a-z0-9]{32})-.*|") + if [ -z "$storeId" ]; then + echo "-e argument must be a Nix store path" + exit 1 + fi + excludes="$excludes(?!$storeId)" + ;; + esac +done +shift $(($OPTIND-1)) + +for i in "$@"; do + if test ! -L "$i" -a -f "$i"; then + cat "$i" | @perl@/bin/perl -pe "s|\Q@storeDir@\E/$excludes[a-z0-9]{32}-|@storeDir@/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" > "$i.tmp" + if test -x "$i"; then chmod +x "$i.tmp"; fi + mv "$i.tmp" "$i" + + for hook in "${fixupHooks[@]}"; do + eval "$hook" "$i" + done + fi +done diff --git a/pkgs/build-support/remove-references-to/darwin-sign-fixup.sh b/pkgs/build-support/remove-references-to/darwin-sign-fixup.sh new file mode 100644 index 000000000000..940c18e5a627 --- /dev/null +++ b/pkgs/build-support/remove-references-to/darwin-sign-fixup.sh @@ -0,0 +1,5 @@ +# Fixup hook for nukeReferences, not stdenv + +source @signingUtils@ + +fixupHooks+=(signIfRequired) diff --git a/pkgs/build-support/remove-references-to/default.nix b/pkgs/build-support/remove-references-to/default.nix index 8b1d05fc2307..f022611ef913 100644 --- a/pkgs/build-support/remove-references-to/default.nix +++ b/pkgs/build-support/remove-references-to/default.nix @@ -3,32 +3,33 @@ # non-existent path (/nix/store/eeee...). This is useful for getting rid of # dependencies that you know are not actually needed at runtime. -{ stdenv, writeScriptBin }: - -writeScriptBin "remove-references-to" '' -#! ${stdenv.shell} -e - -# References to remove -targets=() -while getopts t: o; do - case "$o" in - t) storeId=$(echo "$OPTARG" | sed -n "s|^$NIX_STORE/\\([a-z0-9]\{32\}\\)-.*|\1|p") - if [ -z "$storeId" ]; then - echo "-t argument must be a Nix store path" - exit 1 - fi - targets+=("$storeId") - esac -done -shift $(($OPTIND-1)) - -# Files to remove the references from -regions=() -for i in "$@"; do - test ! -L "$i" -a -f "$i" && regions+=("$i") -done - -for target in "''${targets[@]}" ; do - sed -i -e "s|$NIX_STORE/$target-|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" "''${regions[@]}" -done -'' +{ lib, stdenvNoCC, signingUtils, shell ? stdenvNoCC.shell }: + +let + stdenv = stdenvNoCC; + + darwinCodeSign = stdenv.targetPlatform.isDarwin && stdenv.targetPlatform.isAarch64; +in + +stdenv.mkDerivation { + name = "remove-references-to"; + + dontUnpack = true; + dontConfigure = true; + dontBuild = true; + + installPhase = '' + mkdir -p $out/bin + substituteAll ${./remove-references-to.sh} $out/bin/remove-references-to + chmod a+x $out/bin/remove-references-to + ''; + + postFixup = lib.optionalString darwinCodeSign '' + mkdir -p $out/nix-support + substituteAll ${./darwin-sign-fixup.sh} $out/nix-support/setup-hooks.sh + ''; + + inherit (builtins) storeDir; + shell = lib.getBin shell + (shell.shellPath or ""); + signingUtils = if darwinCodeSign then signingUtils else null; +} diff --git a/pkgs/build-support/remove-references-to/remove-references-to.sh b/pkgs/build-support/remove-references-to/remove-references-to.sh new file mode 100644 index 000000000000..d8d38dbd80a9 --- /dev/null +++ b/pkgs/build-support/remove-references-to/remove-references-to.sh @@ -0,0 +1,37 @@ +#! @shell@ -e + +fixupHooks=() + +if [ -e @out@/nix-support/setup-hooks.sh ]; then + source @out@/nix-support/setup-hooks.sh +fi + +# References to remove +targets=() +while getopts t: o; do + case "$o" in + t) storeId=$(echo "$OPTARG" | sed -n "s|^@storeDir@/\\([a-z0-9]\{32\}\\)-.*|\1|p") + if [ -z "$storeId" ]; then + echo "-t argument must be a Nix store path" + exit 1 + fi + targets+=("$storeId") + esac +done +shift $(($OPTIND-1)) + +# Files to remove the references from +regions=() +for i in "$@"; do + test ! -L "$i" -a -f "$i" && regions+=("$i") +done + +for target in "${targets[@]}" ; do + sed -i -e "s|@storeDir@/$target-|@storeDir@/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-|g" "${regions[@]}" +done + +for region in "${regions[@]}"; do + for hook in "${fixupHooks[@]}"; do + eval "$hook" "$i" + done +done diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index ff9ca642daad..940bd09425d2 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -14,6 +14,7 @@ , git , rust , rustc +, libiconv , windows }: @@ -117,7 +118,9 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs u rustc ]; - buildInputs = buildInputs ++ lib.optional stdenv.hostPlatform.isMinGW windows.pthreads; + buildInputs = buildInputs + ++ lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ] + ++ lib.optionals stdenv.hostPlatform.isMinGW [ windows.pthreads ]; patches = cargoPatches ++ patches; diff --git a/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh b/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh index af2ff0cc9662..55e196e654df 100644 --- a/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh +++ b/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh @@ -23,7 +23,7 @@ fixDarwinDylibNames() { for fn in "$@"; do if [ -L "$fn" ]; then continue; fi echo "$fn: fixing dylib" - int_out=$(install_name_tool -id "$fn" "${flags[@]}" "$fn" 2>&1) + int_out=$(@targetPrefix@install_name_tool -id "$fn" "${flags[@]}" "$fn" 2>&1) result=$? if [ "$result" -ne 0 ] && ! grep "shared library stub file and can't be changed" <<< "$out" |