From 2fa6cd6d23a51d22ae9d651eaba822676d068d00 Mon Sep 17 00:00:00 2001 From: "Seth R. Johnson" Date: Thu, 10 Feb 2022 18:22:30 -0500 Subject: macOS: always set `MACOSX_DEPLOYMENT_TARGET` (#28797) * core: Make platform environment an instance not class method In preparation for accessing data constructed in __init__. * macos: set consistent macosx deployment target This should silence numerous warnings from mixed gcc/macos toolchains. * perl: prevent too-new deployment target version ``` *** Unexpected MACOSX_DEPLOYMENT_TARGET=11 *** *** Please either set it to a valid macOS version number (e.g., 10.15) or to empty. ``` * Stylin' * Add deployment target overrides to failing autoconf packages * Move configure workaround to base autoconf package This reverts commit 3c119eaf8b4fb37c943d503beacf5ad2aa513d4c. * Stylin' * macos: add utility functions for SDK These aren't yet used but should probably be added to spack debug report. --- lib/spack/spack/build_systems/autotools.py | 9 ++++++ lib/spack/spack/operating_systems/mac_os.py | 43 +++++++++++++++++++++++++++-- lib/spack/spack/platforms/_platform.py | 4 +-- lib/spack/spack/platforms/cray.py | 3 +- lib/spack/spack/platforms/darwin.py | 22 +++++++++++++++ 5 files changed, 75 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/build_systems/autotools.py b/lib/spack/spack/build_systems/autotools.py index e03870d0f9..46a3ccddf7 100644 --- a/lib/spack/spack/build_systems/autotools.py +++ b/lib/spack/spack/build_systems/autotools.py @@ -15,8 +15,10 @@ from llnl.util.filesystem import force_remove, working_dir from spack.build_environment import InstallError from spack.directives import depends_on +from spack.operating_systems.mac_os import macos_version from spack.package import PackageBase, run_after, run_before from spack.util.executable import Executable +from spack.version import Version class AutotoolsPackage(PackageBase): @@ -415,6 +417,13 @@ To resolve this problem, please try the following: with working_dir(self.build_directory, create=True): inspect.getmodule(self).configure(*options) + def setup_build_environment(self, env): + if (self.spec.platform == 'darwin' + and macos_version() >= Version('11')): + # Many configure files rely on matching '10.*' for macOS version + # detection and fail to add flags if it shows as version 11. + env.set('MACOSX_DEPLOYMENT_TARGET', '10.16') + def build(self, spec, prefix): """Makes the build targets specified by :py:attr:``~.AutotoolsPackage.build_targets`` diff --git a/lib/spack/spack/operating_systems/mac_os.py b/lib/spack/spack/operating_systems/mac_os.py index 226bfccca5..cb430449f2 100644 --- a/lib/spack/spack/operating_systems/mac_os.py +++ b/lib/spack/spack/operating_systems/mac_os.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import platform as py_platform +import re from spack.util.executable import Executable from spack.version import Version @@ -18,11 +19,49 @@ def macos_version(): return Version(py_platform.mac_ver()[0]) +def macos_cltools_version(): + """Find the last installed version of the CommandLineTools. + + The CLT version might only affect the build if it's selected as the macOS + SDK path. + """ + pkgutil = Executable('pkgutil') + output = pkgutil('--pkg-info=com.apple.pkg.CLTools_Executables', + output=str, fail_on_error=False) + match = re.search(r'version:\s*([0-9.]+)', output) + if match: + return Version(match.group(1)) + + # No CLTools installed by package manager: try Xcode + output = pkgutil('--pkg-info=com.apple.pkg.Xcode', + output=str, fail_on_error=False) + match = re.search(r'version:\s*([0-9.]+)', output) + if match: + return Version(match.group(1)) + + return None + + def macos_sdk_path(): - """Return SDK path + """Return path to the active macOS SDK. + """ + xcrun = Executable('xcrun') + return xcrun('--show-sdk-path', output=str).rstrip() + + +def macos_sdk_version(): + """Return the version of the active macOS SDK. + + The SDK version usually corresponds to the installed Xcode version and can + affect how some packages (especially those that use the GUI) can fail. This + information should somehow be embedded into the future "compilers are + dependencies" feature. + + The macOS deployment target cannot be greater than the SDK version, but + usually it can be at least a few versions less. """ xcrun = Executable('xcrun') - return xcrun('--show-sdk-path', output=str, error=str).rstrip() + return Version(xcrun('--show-sdk-version', output=str).rstrip()) class MacOs(OperatingSystem): diff --git a/lib/spack/spack/platforms/_platform.py b/lib/spack/spack/platforms/_platform.py index 61845eb430..b68b7f1299 100644 --- a/lib/spack/spack/platforms/_platform.py +++ b/lib/spack/spack/platforms/_platform.py @@ -104,11 +104,11 @@ class Platform(object): return self.operating_sys.get(name, None) - @classmethod - def setup_platform_environment(cls, pkg, env): + def setup_platform_environment(self, pkg, env): """Subclass can override this method if it requires any platform-specific build environment modifications. """ + pass @classmethod def detect(cls): diff --git a/lib/spack/spack/platforms/cray.py b/lib/spack/spack/platforms/cray.py index 133c29940e..23724dffbe 100644 --- a/lib/spack/spack/platforms/cray.py +++ b/lib/spack/spack/platforms/cray.py @@ -84,8 +84,7 @@ class Cray(Platform): if self.front_os != self.back_os: self.add_operating_system(self.front_os, front_distro) - @classmethod - def setup_platform_environment(cls, pkg, env): + def setup_platform_environment(self, pkg, env): """ Change the linker to default dynamic to be more similar to linux/standard linker behavior """ diff --git a/lib/spack/spack/platforms/darwin.py b/lib/spack/spack/platforms/darwin.py index 7f38cad42e..b4b542cb98 100644 --- a/lib/spack/spack/platforms/darwin.py +++ b/lib/spack/spack/platforms/darwin.py @@ -39,3 +39,25 @@ class Darwin(Platform): @classmethod def detect(cls): return 'darwin' in platform.system().lower() + + def setup_platform_environment(self, pkg, env): + """Specify deployment target based on target OS version. + + The ``MACOSX_DEPLOYMENT_TARGET`` environment variable provides a + default ``-mmacosx-version-min`` argument for GCC and Clang compilers, + as well as the default value of ``CMAKE_OSX_DEPLOYMENT_TARGET`` for + CMake-based build systems. The default value for the deployment target + is usually the major version (11, 10.16, ...) for CMake and Clang, but + some versions of GCC specify a minor component as well (11.3), leading + to numerous link warnings about inconsistent or incompatible target + versions. Setting the environment variable ensures consistent versions + for an install toolchain target, even when the host macOS version + changes. + + TODO: it may be necessary to add SYSTEM_VERSION_COMPAT for older + versions of the macosx developer tools; see + https://github.com/spack/spack/pull/26290 for discussion. + """ + + os = self.operating_sys[pkg.spec.os] + env.set('MACOSX_DEPLOYMENT_TARGET', str(os.version)) -- cgit v1.2.3-70-g09d2