cc-wrapper, bintools-wrapper: support MACOSX_DEPLOYMENT_TARGET with roles

In a typical build environment the toolchain will use the value of the
MACOSX_DEPLOYMENT_TARGET environment variable to determine the version
of macOS to support. When cross compiling there are two distinct
toolchains, but they will look at this single environment variable. To
avoid contamination, we always set the equivalent command line flag
which effectively disables the toolchain's internal handling.

Prior to this change, the MACOSX_DEPLOYMENT_TARGET variable was
ignored, and the toolchains always used the Nix platform
definition (`darwinMinVersion`) unless overridden with command line
arguments.

This change restores support for MACOSX_DEPLOYMENT_TARGET, and adds
nix-specific MACOSX_DEPLOYMENT_TARGET_FOR_BUILD and
MACOSX_DEPLOYMENT_TARGET_FOR_TARGET for cross compilation.
This commit is contained in:
Andrew Childs 2021-04-10 13:11:28 +09:00
parent 8b59d52ca3
commit 2a9b3b4943
4 changed files with 55 additions and 12 deletions

View File

@ -21,6 +21,8 @@ havePlatformVersionFlag=
haveDarwinSDKVersion= haveDarwinSDKVersion=
haveDarwinPlatformVersion= haveDarwinPlatformVersion=
mangleVarSingle MACOSX_DEPLOYMENT_TARGET ${role_suffixes[@]+"${role_suffixes[@]}"}
n=0 n=0
nParams=${#params[@]} nParams=${#params[@]}
while (( n < nParams )); do while (( n < nParams )); do
@ -59,12 +61,12 @@ done
if [ ! "$havePlatformVersionFlag" ]; then if [ ! "$havePlatformVersionFlag" ]; then
if [ ! "$haveDarwinSDKVersion" ] && [ ! "$haveDarwinPlatformVersion" ]; then if [ ! "$haveDarwinSDKVersion" ] && [ ! "$haveDarwinPlatformVersion" ]; then
# Nothing provided. Use the modern "-platform_version" to set both. # Nothing provided. Use the modern "-platform_version" to set both.
extraBefore+=(-platform_version @darwinPlatform@ @darwinMinVersion@ @darwinSdkVersion@) extraBefore+=(-platform_version @darwinPlatform@ "${MACOSX_DEPLOYMENT_TARGET_@suffixSalt@:-@darwinMinVersion@}" @darwinSdkVersion@)
elif [ ! "$haveDarwinSDKVersion" ]; then elif [ ! "$haveDarwinSDKVersion" ]; then
# Add missing sdk version # Add missing sdk version
extraBefore+=(-sdk_version @darwinSdkVersion@) extraBefore+=(-sdk_version @darwinSdkVersion@)
elif [ ! "$haveDarwinPlatformVersion" ]; then elif [ ! "$haveDarwinPlatformVersion" ]; then
# Add missing platform version # Add missing platform version
extraBefore+=(-@darwinPlatform@_version_min @darwinMinVersion@) extraBefore+=(-@darwinPlatform@_version_min "${MACOSX_DEPLOYMENT_TARGET_@suffixSalt@:-@darwinMinVersion@}")
fi fi
fi fi

View File

@ -65,5 +65,13 @@ 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@" NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@="$(< @out@/nix-support/cc-cflags-before) $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@"
fi fi
# 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 MACOSX_DEPLOYMENT_TARGET ${role_suffixes[@]+"${role_suffixes[@]}"}
NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@="-m@darwinPlatformForCC@-version-min=${MACOSX_DEPLOYMENT_TARGET_@suffixSalt@:-@darwinMinVersion@} $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@"
fi
# That way forked processes will not extend these environment variables again. # That way forked processes will not extend these environment variables again.
export NIX_CC_WRAPPER_FLAGS_SET_@suffixSalt@=1 export NIX_CC_WRAPPER_FLAGS_SET_@suffixSalt@=1

View File

@ -100,6 +100,15 @@ let
else else
false; false;
darwinPlatformForCC = optionalString stdenv.targetPlatform.isDarwin (
if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx"
else targetPlatform.darwinPlatform
);
darwinMinVersion = optionalString stdenv.targetPlatform.isDarwin (
stdenv.targetPlatform.darwinMinVersion
);
in in
# Ensure bintools matches # Ensure bintools matches
@ -122,6 +131,7 @@ stdenv.mkDerivation {
gnugrep_bin = if nativeTools then "" else gnugrep; gnugrep_bin = if nativeTools then "" else gnugrep;
inherit targetPrefix suffixSalt; inherit targetPrefix suffixSalt;
inherit darwinPlatformForCC darwinMinVersion;
outputs = [ "out" ] ++ optionals propagateDoc [ "man" "info" ]; outputs = [ "out" ] ++ optionals propagateDoc [ "man" "info" ];
@ -473,6 +483,10 @@ stdenv.mkDerivation {
done done
'' ''
+ optionalString stdenv.targetPlatform.isDarwin ''
echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/cc-cflags
''
# There are a few tools (to name one libstdcxx5) which do not work # 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 # well with multi line flags, so make the flags single line again
+ '' + ''
@ -485,16 +499,6 @@ stdenv.mkDerivation {
substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash
'' ''
+ optionalString stdenv.targetPlatform.isDarwin (
let darwinPlatformForCC =
if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx"
else targetPlatform.darwinPlatform;
in ''
echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/cc-cflags
echo "-m${darwinPlatformForCC}-version-min=${targetPlatform.darwinMinVersion}" >> $out/nix-support/cc-cflags-before
''
)
## ##
## Extra custom steps ## Extra custom steps
## ##

View File

@ -49,6 +49,35 @@ mangleVarBool() {
done done
} }
# Combine a singular value from all roles. If multiple roles are being served,
# and the value differs in these roles then the request is impossible to
# satisfy and we abort immediately.
mangleVarSingle() {
local var="$1"
shift
local -a role_suffixes=("$@")
local outputVar="${var}_@suffixSalt@"
for suffix in "${role_suffixes[@]}"; do
local inputVar="${var}${suffix}"
if [ -v "$inputVar" ]; then
if [ -v "$outputVar" ]; then
if [ "${!outputVar}" != "${!inputVar}" ]; then
{
echo "Multiple conflicting values defined for $outputVar"
echo "Existing value is ${!outputVar}"
echo "Attempting to set to ${!inputVar} via $inputVar"
} >&2
exit 1
fi
else
declare -gx ${outputVar}="${!inputVar}"
fi
fi
done
}
skip () { skip () {
if (( "${NIX_DEBUG:-0}" >= 1 )); then if (( "${NIX_DEBUG:-0}" >= 1 )); then
echo "skipping impure path $1" >&2 echo "skipping impure path $1" >&2