From 9142a070307ca6f18eb6e02aa2bca4855406680e Mon Sep 17 00:00:00 2001 From: Emily Date: Fri, 25 Oct 2024 19:41:08 +0100 Subject: [PATCH 1/2] {bintools-wrapper,cc-wrapper}: factor out Darwin SDK logic This reduces code duplication, makes the SDK variables available earlier in the wrappers, and makes the behaviour between the two wrappers more consistent. --- .../add-darwin-ldflags-before.sh | 6 ----- .../bintools-wrapper/default.nix | 22 ++++++++----------- .../bintools-wrapper/ld-wrapper.sh | 2 ++ pkgs/build-support/cc-wrapper/add-flags.sh | 13 +---------- pkgs/build-support/cc-wrapper/cc-wrapper.sh | 2 ++ pkgs/build-support/cc-wrapper/default.nix | 13 +++++------ .../wrapper-common/darwin-sdk-setup.bash | 16 ++++++++++++++ 7 files changed, 35 insertions(+), 39 deletions(-) create mode 100644 pkgs/build-support/wrapper-common/darwin-sdk-setup.bash diff --git a/pkgs/build-support/bintools-wrapper/add-darwin-ldflags-before.sh b/pkgs/build-support/bintools-wrapper/add-darwin-ldflags-before.sh index 127f83e303a33..75d9484846a8c 100644 --- a/pkgs/build-support/bintools-wrapper/add-darwin-ldflags-before.sh +++ b/pkgs/build-support/bintools-wrapper/add-darwin-ldflags-before.sh @@ -79,9 +79,3 @@ if [ ! "$havePlatformVersionFlag" ]; then extraBefore+=(-@darwinPlatform@_version_min "${@darwinMinVersionVariable@_@suffixSalt@:-@darwinMinVersion@}") fi fi - -mangleVarSingle DEVELOPER_DIR ${role_suffixes[@]+"${role_suffixes[@]}"} - -# Allow wrapped bintools to do something useful when no `DEVELOPER_DIR` is set, which can happen when -# the compiler is run outside of a stdenv or intentionally in an environment with no environment variables set. -DEVELOPER_DIR=${DEVELOPER_DIR_@suffixSalt@:-@fallback_sdk@} diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index a2a0736c2221b..fc04462741618 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -372,24 +372,15 @@ stdenvNoCC.mkDerivation { substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash + substituteAll ${../wrapper-common/darwin-sdk-setup.bash} $out/nix-support/darwin-sdk-setup.bash '' ### ### Ensure consistent LC_VERSION_MIN_MACOSX ### - + optionalString targetPlatform.isDarwin ( - let - inherit (targetPlatform) - darwinPlatform darwinSdkVersion - darwinMinVersion darwinMinVersionVariable; - in '' - export darwinPlatform=${darwinPlatform} - export darwinMinVersion=${darwinMinVersion} - export darwinSdkVersion=${darwinSdkVersion} - export darwinMinVersionVariable=${darwinMinVersionVariable} - substituteAll ${./add-darwin-ldflags-before.sh} $out/nix-support/add-local-ldflags-before.sh - '' - ) + + optionalString targetPlatform.isDarwin '' + substituteAll ${./add-darwin-ldflags-before.sh} $out/nix-support/add-local-ldflags-before.sh + '' ## ## Extra custom steps @@ -407,6 +398,11 @@ stdenvNoCC.mkDerivation { inherit dynamicLinker targetPrefix suffixSalt coreutils_bin; inherit bintools_bin libc_bin libc_dev libc_lib; default_hardening_flags_str = builtins.toString defaultHardeningFlags; + } // lib.mapAttrs (_: lib.optionalString targetPlatform.isDarwin) { + # These will become empty strings when not targeting Darwin. + inherit (targetPlatform) + darwinPlatform darwinSdkVersion + darwinMinVersion darwinMinVersionVariable; } // lib.optionalAttrs (apple-sdk != null && stdenvNoCC.targetPlatform.isDarwin) { # Wrapped compilers should do something useful even when no SDK is provided at `DEVELOPER_DIR`. fallback_sdk = apple-sdk.__spliced.buildTarget or apple-sdk; diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh index 7e00d02b03742..1c5b08541ac26 100644 --- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh +++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh @@ -16,6 +16,8 @@ fi source @out@/nix-support/utils.bash +source @out@/nix-support/darwin-sdk-setup.bash + if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then source @out@/nix-support/add-flags.sh fi diff --git a/pkgs/build-support/cc-wrapper/add-flags.sh b/pkgs/build-support/cc-wrapper/add-flags.sh index 838b963ead7b0..2c3dc8884023b 100644 --- a/pkgs/build-support/cc-wrapper/add-flags.sh +++ b/pkgs/build-support/cc-wrapper/add-flags.sh @@ -78,23 +78,12 @@ if [ -e @out@/nix-support/cc-cflags-before ]; then NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@="$(< @out@/nix-support/cc-cflags-before) $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@" fi -# Only add darwin min version flag and set up `DEVELOPER_DIR` if a default darwin min version is set, +# Only add darwin min version flag if a default darwin min version is set, # which is a signal that we're targetting darwin. if [ "@darwinMinVersion@" ]; then mangleVarSingle @darwinMinVersionVariable@ ${role_suffixes[@]+"${role_suffixes[@]}"} NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@="-m@darwinPlatformForCC@-version-min=${@darwinMinVersionVariable@_@suffixSalt@:-@darwinMinVersion@} $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@" - - # `DEVELOPER_DIR` is used to dynamically locate libSystem (and the SDK frameworks) based on the SDK at that path. - mangleVarSingle DEVELOPER_DIR ${role_suffixes[@]+"${role_suffixes[@]}"} - - # Allow wrapped compilers to do something useful when no `DEVELOPER_DIR` is set, which can happen when - # the compiler is run outside of a stdenv or intentionally in an environment with no environment variables set. - DEVELOPER_DIR=${DEVELOPER_DIR_@suffixSalt@:-@fallback_sdk@} - - # xcbuild needs `SDKROOT` to be the name of the SDK, which it sets in its own wrapper, - # but compilers expect it to point to the absolute path. - SDKROOT="$DEVELOPER_DIR/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" fi # That way forked processes will not extend these environment variables again. diff --git a/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/pkgs/build-support/cc-wrapper/cc-wrapper.sh index a539f9da43186..5d338a0dd0dca 100644 --- a/pkgs/build-support/cc-wrapper/cc-wrapper.sh +++ b/pkgs/build-support/cc-wrapper/cc-wrapper.sh @@ -17,6 +17,8 @@ fi source @out@/nix-support/utils.bash +source @out@/nix-support/darwin-sdk-setup.bash + # Parse command line options and set several variables. # For instance, figure out if linker flags should be passed. diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index b9def8632615e..001123fe3d857 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -284,13 +284,6 @@ let if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx" else targetPlatform.darwinPlatform ); - - darwinMinVersion = optionalString targetPlatform.isDarwin ( - targetPlatform.darwinMinVersion - ); - - darwinMinVersionVariable = optionalString targetPlatform.isDarwin - targetPlatform.darwinMinVersionVariable; in assert includeFortifyHeaders' -> fortify-headers != null; @@ -707,6 +700,7 @@ stdenvNoCC.mkDerivation { substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash + substituteAll ${../wrapper-common/darwin-sdk-setup.bash} $out/nix-support/darwin-sdk-setup.bash '' + optionalString cc.langAda or false '' @@ -751,8 +745,11 @@ stdenvNoCC.mkDerivation { wrapperName = "CC_WRAPPER"; inherit suffixSalt coreutils_bin bintools; inherit libc_bin libc_dev libc_lib; - inherit darwinPlatformForCC darwinMinVersion darwinMinVersionVariable; + inherit darwinPlatformForCC; default_hardening_flags_str = builtins.toString defaultHardeningFlags; + } // lib.mapAttrs (_: lib.optionalString targetPlatform.isDarwin) { + # These will become empty strings when not targeting Darwin. + inherit (targetPlatform) darwinMinVersion darwinMinVersionVariable; } // lib.optionalAttrs (apple-sdk != null && stdenvNoCC.targetPlatform.isDarwin) { # Wrapped compilers should do something useful even when no SDK is provided at `DEVELOPER_DIR`. fallback_sdk = apple-sdk.__spliced.buildTarget or apple-sdk; diff --git a/pkgs/build-support/wrapper-common/darwin-sdk-setup.bash b/pkgs/build-support/wrapper-common/darwin-sdk-setup.bash new file mode 100644 index 0000000000000..8c6a337a8fca7 --- /dev/null +++ b/pkgs/build-support/wrapper-common/darwin-sdk-setup.bash @@ -0,0 +1,16 @@ +accumulateRoles + +# Only set up `DEVELOPER_DIR` if a default darwin min version is set, +# which is a signal that we're targetting darwin. +if [[ "@darwinMinVersion@" ]]; then + # `DEVELOPER_DIR` is used to dynamically locate libSystem (and the SDK frameworks) based on the SDK at that path. + mangleVarSingle DEVELOPER_DIR ${role_suffixes[@]+"${role_suffixes[@]}"} + + # Allow wrapped compilers to do something useful when no `DEVELOPER_DIR` is set, which can happen when + # the compiler is run outside of a stdenv or intentionally in an environment with no environment variables set. + DEVELOPER_DIR=${DEVELOPER_DIR_@suffixSalt@:-@fallback_sdk@} + + # xcbuild needs `SDKROOT` to be the name of the SDK, which it sets in its own wrapper, + # but compilers expect it to point to the absolute path. + SDKROOT="$DEVELOPER_DIR/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" +fi From e047c69ed406c834722b6ed7bb1bdd39d3e5eef0 Mon Sep 17 00:00:00 2001 From: Emily Date: Fri, 25 Oct 2024 19:41:08 +0100 Subject: [PATCH 2/2] {bintools-wrapper,cc-wrapper}: allow paths relative to the Darwin SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `-L` and `-I` are interpreted relative to the `$SDKROOT` by the Darwin toolchain, so we have to avoid filtering out such paths in the purity filter hacks in order to not break e.g. the .NET Core build system. It’s also just the correct thing to do for the platform. --- pkgs/build-support/bintools-wrapper/ld-wrapper.sh | 4 ++-- pkgs/build-support/cc-wrapper/cc-wrapper.sh | 2 +- pkgs/build-support/wrapper-common/utils.bash | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh index 1c5b08541ac26..310cbc001c8b2 100644 --- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh +++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh @@ -44,9 +44,9 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}" while (( "$n" < "$nParams" )); do p=${params[n]} p2=${params[n+1]:-} # handle `p` being last one - if [ "${p:0:3}" = -L/ ] && badPath "${p:2}"; then + if [ "${p:0:3}" = -L/ ] && badPathWithDarwinSdk "${p:2}"; then skip "${p:2}" - elif [ "$p" = -L ] && badPath "$p2"; then + elif [ "$p" = -L ] && badPathWithDarwinSdk "$p2"; then n+=1; skip "$p2" elif [ "$p" = -rpath ] && badPath "$p2"; then n+=1; skip "$p2" diff --git a/pkgs/build-support/cc-wrapper/cc-wrapper.sh b/pkgs/build-support/cc-wrapper/cc-wrapper.sh index 5d338a0dd0dca..da1a709684dac 100644 --- a/pkgs/build-support/cc-wrapper/cc-wrapper.sh +++ b/pkgs/build-support/cc-wrapper/cc-wrapper.sh @@ -103,7 +103,7 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then -[IL] | -isystem) path=$p2 skipNext=true ;; esac - if [[ -n $path ]] && badPath "$path"; then + if [[ -n $path ]] && badPathWithDarwinSdk "$path"; then skip "$path" $skipNext && n+=1 continue diff --git a/pkgs/build-support/wrapper-common/utils.bash b/pkgs/build-support/wrapper-common/utils.bash index 2faf96df15b40..c9870d1b4d410 100644 --- a/pkgs/build-support/wrapper-common/utils.bash +++ b/pkgs/build-support/wrapper-common/utils.bash @@ -118,6 +118,21 @@ badPath() { "${p#"${TEMPDIR:-/tmp}"}" = "$p" } +# Like `badPath`, but handles paths that may be interpreted relative to +# `$SDKROOT` on Darwin. For example, `-L/usr/lib/swift` is interpreted +# as `-L$SDKROOT/usr/lib/swift` when `$SDKROOT` is set and +# `$SDKROOT/usr/lib/swift` exists. +badPathWithDarwinSdk() { + path=$1 + if [[ "@darwinMinVersion@" ]]; then + sdkPath=$SDKROOT/$path + if [[ -e $sdkPath ]]; then + path=$sdkPath + fi + fi + badPath "$path" +} + expandResponseParams() { declare -ga params=("$@") local arg