diff --git a/lib/systems/default.nix b/lib/systems/default.nix index 1e38dbf531b..21b00374da4 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -112,6 +112,19 @@ rec { aarch64 = "arm64"; }.${final.parsed.cpu.name} or final.parsed.cpu.name; + darwinPlatform = + if final.isMacOS then "macos" + else if final.isiOS then "ios" + else null; + # The canonical name for this attribute is darwinSdkVersion, but some + # platforms define the old name "sdkVer". + darwinSdkVersion = final.sdkVer or "10.12"; + darwinMinVersion = final.darwinSdkVersion; + darwinMinVersionVariable = + if final.isMacOS then "MACOSX_DEPLOYMENT_TARGET" + else if final.isiOS then "IPHONEOS_DEPLOYMENT_TARGET" + else null; + emulator = pkgs: let qemu-user = pkgs.qemu.override { smartcardSupport = false; diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix index 8a43b86db70..082be8902bb 100644 --- a/lib/systems/examples.nix +++ b/lib/systems/examples.nix @@ -219,6 +219,7 @@ rec { sdkVer = "14.3"; xcodeVer = "12.3"; xcodePlatform = "iPhoneSimulator"; + darwinPlatform = "ios-simulator"; useiOSPrebuilt = true; }; @@ -228,6 +229,7 @@ rec { sdkVer = "14.3"; xcodeVer = "12.3"; xcodePlatform = "iPhoneSimulator"; + darwinPlatform = "ios-simulator"; useiOSPrebuilt = true; }; diff --git a/pkgs/build-support/bintools-wrapper/add-darwin-ldflags-before.sh b/pkgs/build-support/bintools-wrapper/add-darwin-ldflags-before.sh new file mode 100644 index 00000000000..75d9484846a --- /dev/null +++ b/pkgs/build-support/bintools-wrapper/add-darwin-ldflags-before.sh @@ -0,0 +1,81 @@ +# Unconditionally adding in platform version flags will result in warnings that +# will be treated as errors by some packages. Add any missing flags here. + +# There are two things to be configured: the "platform version" (oldest +# supported version of macos, ios, etc), and the "sdk version". +# +# The modern way of configuring these is to use: +# -platform_version $platform $platform_version $sdk_version" +# +# The old way is still supported, and uses flags like: +# -${platform}_version_min $platform_version +# -sdk_version $sdk_version +# +# If both styles are specified ld will combine them. If multiple versions are +# specified for the same platform, ld will emit an error. +# +# The following adds flags for whichever properties have not already been +# provided. + +havePlatformVersionFlag= +haveDarwinSDKVersion= +haveDarwinPlatformVersion= + +# Roles will set by add-flags.sh, but add-flags.sh can be skipped when the +# cc-wrapper has added the linker flags. Both the cc-wrapper and the binutils +# wrapper mangle the same variable (MACOSX_DEPLOYMENT_TARGET), so if roles are +# empty due to being run through the cc-wrapper then the mangle here is a no-op +# and we still do the right thing. +# +# To be robust, make sure we always have the correct set of roles. +accumulateRoles + +mangleVarSingle @darwinMinVersionVariable@ ${role_suffixes[@]+"${role_suffixes[@]}"} + +n=0 +nParams=${#params[@]} +while (( n < nParams )); do + p=${params[n]} + case "$p" in + # the current platform + -@darwinPlatform@_version_min) + haveDarwinPlatformVersion=1 + ;; + + # legacy aliases + -macosx_version_min|-iphoneos_version_min|-iosmac_version_min|-uikitformac_version_min) + haveDarwinPlatformVersion=1 + ;; + + -sdk_version) + haveDarwinSDKVersion=1 + ;; + + -platform_version) + havePlatformVersionFlag=1 + + # If clang can't determine the sdk version it will pass 0.0.0. This + # has runtime effects so we override this to use the known sdk + # version. + if [ "${params[n+3]-}" = 0.0.0 ]; then + params[n+3]=@darwinSdkVersion@ + fi + ;; + esac + n=$((n + 1)) +done + +# If the caller has set -platform_version, trust they're doing the right thing. +# This will be the typical case for clang in nixpkgs. +if [ ! "$havePlatformVersionFlag" ]; then + if [ ! "$haveDarwinSDKVersion" ] && [ ! "$haveDarwinPlatformVersion" ]; then + # Nothing provided. Use the modern "-platform_version" to set both. + extraBefore+=(-platform_version @darwinPlatform@ "${@darwinMinVersionVariable@_@suffixSalt@:-@darwinMinVersion@}" @darwinSdkVersion@) + elif [ ! "$haveDarwinSDKVersion" ]; then + # Add missing sdk version + extraBefore+=(-sdk_version @darwinSdkVersion@) + elif [ ! "$haveDarwinPlatformVersion" ]; then + # Add missing platform version + extraBefore+=(-@darwinPlatform@_version_min "${@darwinMinVersionVariable@_@suffixSalt@:-@darwinMinVersion@}") + fi +fi diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index dac1f3bd7c1..859e3790594 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -252,11 +252,6 @@ stdenv.mkDerivation { fi '') - # Ensure consistent LC_VERSION_MIN_MACOSX and remove LC_UUID. - + optionalString stdenv.targetPlatform.isMacOS '' - echo "-sdk_version 10.12 -no_uuid" >> $out/nix-support/libc-ldflags-before - '' - ## ## User env support ## @@ -310,6 +305,13 @@ stdenv.mkDerivation { echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/libc-ldflags '' + ### + ### Remove LC_UUID + ### + + optionalString (stdenv.targetPlatform.isDarwin && !(stdenv.cc.bintools.bintools.isGNU or false)) '' + echo "-no_uuid" >> $out/nix-support/libc-ldflags-before + '' + + '' for flags in "$out/nix-support"/*flags*; do substituteInPlace "$flags" --replace $'\n' ' ' @@ -320,6 +322,23 @@ stdenv.mkDerivation { substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash '' + ### + ### Ensure consistent LC_VERSION_MIN_MACOSX + ### + + optionalString stdenv.targetPlatform.isDarwin ( + let + inherit (stdenv.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 + '' + ) + ## ## Extra custom steps ## diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh index 9d02f99851a..7ccf5510c88 100644 --- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh +++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh @@ -78,6 +78,14 @@ fi extraAfter+=($NIX_LDFLAGS_AFTER_@suffixSalt@) +# These flags *must not* be pulled up to -Wl, flags, so they can't go in +# add-flags.sh. They must always be set, so must not be disabled by +# NIX_LDFLAGS_SET. +if [ -e @out@/nix-support/add-local-ldflags-before.sh ]; then + source @out@/nix-support/add-local-ldflags-before.sh +fi + + # Specify the target emulation if nothing is passed in ("-m" overrides this # environment variable). Ensures we never blindly fallback on targeting the host # platform. diff --git a/pkgs/build-support/cc-wrapper/add-flags.sh b/pkgs/build-support/cc-wrapper/add-flags.sh index 94589131b70..a6e991914e6 100644 --- a/pkgs/build-support/cc-wrapper/add-flags.sh +++ b/pkgs/build-support/cc-wrapper/add-flags.sh @@ -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@" 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 @darwinMinVersionVariable@ ${role_suffixes[@]+"${role_suffixes[@]}"} + + NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@="-m@darwinPlatformForCC@-version-min=${@darwinMinVersionVariable@_@suffixSalt@:-@darwinMinVersion@} $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@" +fi + # That way forked processes will not extend these environment variables again. export NIX_CC_WRAPPER_FLAGS_SET_@suffixSalt@=1 diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 31689022b32..db751593701 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -100,6 +100,18 @@ let else false; + + darwinPlatformForCC = optionalString stdenv.targetPlatform.isDarwin ( + if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx" + else targetPlatform.darwinPlatform + ); + + darwinMinVersion = optionalString stdenv.targetPlatform.isDarwin ( + stdenv.targetPlatform.darwinMinVersion + ); + + darwinMinVersionVariable = optionalString stdenv.targetPlatform.isDarwin + stdenv.targetPlatform.darwinMinVersionVariable; in # Ensure bintools matches @@ -122,6 +134,7 @@ stdenv.mkDerivation { gnugrep_bin = if nativeTools then "" else gnugrep; inherit targetPrefix suffixSalt; + inherit darwinPlatformForCC darwinMinVersion darwinMinVersionVariable; outputs = [ "out" ] ++ optionals propagateDoc [ "man" "info" ]; @@ -473,6 +486,10 @@ stdenv.mkDerivation { 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 # well with multi line flags, so make the flags single line again + '' @@ -485,10 +502,6 @@ stdenv.mkDerivation { substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash '' - + optionalString stdenv.targetPlatform.isDarwin '' - echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/cc-cflags - '' - ## ## Extra custom steps ## diff --git a/pkgs/build-support/wrapper-common/utils.bash b/pkgs/build-support/wrapper-common/utils.bash index d164982b434..66b7c3f3e83 100644 --- a/pkgs/build-support/wrapper-common/utils.bash +++ b/pkgs/build-support/wrapper-common/utils.bash @@ -49,6 +49,35 @@ mangleVarBool() { 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 () { if (( "${NIX_DEBUG:-0}" >= 1 )); then echo "skipping impure path $1" >&2 diff --git a/pkgs/development/tools/misc/binutils/default.nix b/pkgs/development/tools/misc/binutils/default.nix index 37ba3420b18..995f3f7430c 100644 --- a/pkgs/development/tools/misc/binutils/default.nix +++ b/pkgs/development/tools/misc/binutils/default.nix @@ -143,6 +143,7 @@ stdenv.mkDerivation { passthru = { inherit targetPrefix; + isGNU = true; }; meta = with lib; { diff --git a/pkgs/development/tools/misc/luarocks/darwin-3.1.3.patch b/pkgs/development/tools/misc/luarocks/darwin-3.1.3.patch index 4ba883f0113..8070af173aa 100644 --- a/pkgs/development/tools/misc/luarocks/darwin-3.1.3.patch +++ b/pkgs/development/tools/misc/luarocks/darwin-3.1.3.patch @@ -7,7 +7,7 @@ index c5af5a2..1949fdc 100644 defaults.arch = "macosx-"..target_cpu defaults.variables.LIBFLAG = "-bundle -undefined dynamic_lookup -all_load" - local version = util.popen_read("sw_vers -productVersion") -+ local version = os.getenv("MACOSX_DEPLOYMENT_TARGET") or "10.12" ++ local version = os.getenv("MACOSX_DEPLOYMENT_TARGET") or "@darwinMinVersion@" version = tonumber(version and version:match("^[^.]+%.([^.]+)")) or 3 if version >= 10 then version = 8 diff --git a/pkgs/development/tools/misc/luarocks/default.nix b/pkgs/development/tools/misc/luarocks/default.nix index 77f34cca7de..d4f2ec4ded9 100644 --- a/pkgs/development/tools/misc/luarocks/default.nix +++ b/pkgs/development/tools/misc/luarocks/default.nix @@ -19,6 +19,11 @@ stdenv.mkDerivation rec { }; patches = [ ./darwin-3.1.3.patch ]; + + postPatch = lib.optionalString stdenv.targetPlatform.isDarwin '' + substituteInPlace src/luarocks/core/cfg.lua --subst-var-by 'darwinMinVersion' '${stdenv.targetPlatform.darwinMinVersion}' + ''; + preConfigure = '' lua -e "" || { luajit -e "" && { diff --git a/pkgs/development/tools/xcbuild/wrapper.nix b/pkgs/development/tools/xcbuild/wrapper.nix index 861ef0fc847..4f74b093717 100644 --- a/pkgs/development/tools/xcbuild/wrapper.nix +++ b/pkgs/development/tools/xcbuild/wrapper.nix @@ -3,7 +3,7 @@ , runtimeShell, callPackage , xcodePlatform ? stdenv.targetPlatform.xcodePlatform or "MacOSX" , xcodeVer ? stdenv.targetPlatform.xcodeVer or "9.4.1" -, sdkVer ? stdenv.targetPlatform.sdkVer or "10.12" }: +, sdkVer ? stdenv.targetPlatform.darwinSdkVersion or "10.12" }: let diff --git a/pkgs/os-specific/darwin/xcode/sdk-pkgs.nix b/pkgs/os-specific/darwin/xcode/sdk-pkgs.nix index cabac19ba86..ab934d7eaaa 100644 --- a/pkgs/os-specific/darwin/xcode/sdk-pkgs.nix +++ b/pkgs/os-specific/darwin/xcode/sdk-pkgs.nix @@ -29,11 +29,6 @@ rec { binutils = wrapBintoolsWith { libc = targetIosSdkPkgs.libraries; bintools = binutils-unwrapped; - extraBuildCommands = lib.optionalString (sdk.platform == "iPhoneSimulator") '' - echo "-platform_version ios-sim ${minSdkVersion} ${sdk.version}" >> $out/nix-support/libc-ldflags - '' + lib.optionalString (sdk.platform == "iPhoneOS") '' - echo "-platform_version ios ${minSdkVersion} ${sdk.version}" >> $out/nix-support/libc-ldflags - ''; }; clang = (wrapCCWith { @@ -46,10 +41,6 @@ rec { mv cc-cflags.tmp $out/nix-support/cc-cflags echo "-target ${targetPlatform.config}" >> $out/nix-support/cc-cflags echo "-isystem ${sdk}/usr/include${lib.optionalString (lib.versionAtLeast "10" sdk.version) " -isystem ${sdk}/usr/include/c++/4.2.1/ -stdlib=libstdc++"}" >> $out/nix-support/cc-cflags - '' + lib.optionalString (sdk.platform == "iPhoneSimulator") '' - echo "-mios-simulator-version-min=${minSdkVersion}" >> $out/nix-support/cc-cflags - '' + lib.optionalString (sdk.platform == "iPhoneOS") '' - echo "-miphoneos-version-min=${minSdkVersion}" >> $out/nix-support/cc-cflags ''; }) // { inherit sdk; diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index a7b91a82a9d..e8b3ef6c10f 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -1,7 +1,5 @@ { lib , localSystem, crossSystem, config, overlays, crossOverlays ? [] -# Minimum required macOS version, used both for compatibility as well as reproducability. -, macosVersionMin ? "10.12" # Allow passing in bootstrap files directly so we can test the stdenv bootstrap process when changing the bootstrap tools , bootstrapFiles ? let fetch = { file, sha256, executable ? true }: import { @@ -36,8 +34,6 @@ in rec { export NIX_IGNORE_LD_THROUGH_GCC=1 unset SDKROOT - export MACOSX_DEPLOYMENT_TARGET=${macosVersionMin} - # Workaround for https://openradar.appspot.com/22671534 on 10.11. export gl_cv_func_getcwd_abort_bug=no @@ -147,9 +143,6 @@ in rec { __stdenvImpureHostDeps = commonImpureHostDeps; __extraImpureHostDeps = commonImpureHostDeps; - extraAttrs = { - inherit macosVersionMin; - }; overrides = self: super: (overrides self super) // { inherit ccNoLibcxx; fetchurl = thisStdenv.fetchurlBoot; @@ -523,7 +516,7 @@ in rec { extraAttrs = { libc = pkgs.darwin.Libsystem; shellPackage = pkgs.bash; - inherit macosVersionMin bootstrapTools; + inherit bootstrapTools; }; allowedRequisites = (with pkgs; [ diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index 476fab3eed6..8ab9d734461 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -106,6 +106,8 @@ let '' + lib.optionalString (hostPlatform.isDarwin || (hostPlatform.parsed.kernel.execFormat != lib.systems.parse.execFormats.elf && hostPlatform.parsed.kernel.execFormat != lib.systems.parse.execFormats.macho)) '' export NIX_DONT_SET_RPATH=1 export NIX_NO_SELF_RPATH=1 + '' + lib.optionalString (hostPlatform.isDarwin && hostPlatform.isMacOS) '' + export MACOSX_DEPLOYMENT_TARGET=${hostPlatform.darwinMinVersion} '' # TODO this should be uncommented, but it causes stupid mass rebuilds. I # think the best solution would just be to fixup linux RPATHs so we don't