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 +++++++++++ var/spack/repos/builtin/packages/perl/package.py | 27 ++++---------- .../repos/builtin/packages/py-scipy/package.py | 9 ----- var/spack/repos/builtin/packages/python/package.py | 4 -- 8 files changed, 83 insertions(+), 38 deletions(-) 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)) diff --git a/var/spack/repos/builtin/packages/perl/package.py b/var/spack/repos/builtin/packages/perl/package.py index 73471a382a..e049d58198 100644 --- a/var/spack/repos/builtin/packages/perl/package.py +++ b/var/spack/repos/builtin/packages/perl/package.py @@ -15,10 +15,10 @@ import os import re from contextlib import contextmanager -from llnl.util import tty from llnl.util.lang import match_predicate from spack import * +from spack.operating_systems.mac_os import macos_version class Perl(Package): # Perl doesn't use Autotools, it should subclass Package @@ -297,24 +297,13 @@ class Perl(Package): # Perl doesn't use Autotools, it should subclass Package def setup_build_environment(self, env): spec = self.spec - # This is to avoid failures when using -mmacosx-version-min=11.1 - # since not all Apple Clang compilers support that version range - # See https://eclecticlight.co/2020/07/21/big-sur-is-both-10-16-and-11-0-its-official/ - # It seems that this is only necessary for older versions of the - # command line tools rather than the xcode/clang version. - if spec.satisfies('os=bigsur'): - pkgutil = Executable('pkgutil') - output = pkgutil('--pkg-info=com.apple.pkg.CLTools_Executables', - output=str, error=str, fail_on_error=False) - match = re.search(r'version:\s*([0-9.]+)', output) - if not match: - tty.warn('Failed to detect macOS command line tools version: ' - + output) - else: - if Version(match.group(1)) < Version('12'): - tty.warn("Setting SYSTEM_VERSION_COMPAT=1 due to older " - "command line tools version") - env.set('SYSTEM_VERSION_COMPAT', 1) + if (spec.version <= Version('5.34.0') + and spec.platform == 'darwin' + and macos_version() >= Version('10.16')): + # Older perl versions reject MACOSX_DEPLOYMENT_TARGET=11 or higher + # as "unexpected"; override the environment variable set by spack's + # platforms.darwin . + env.set('MACOSX_DEPLOYMENT_TARGET', '10.16') # This is how we tell perl the locations of bzip and zlib. env.set('BUILD_BZIP2', 0) diff --git a/var/spack/repos/builtin/packages/py-scipy/package.py b/var/spack/repos/builtin/packages/py-scipy/package.py index 027de106d2..3df0b39318 100644 --- a/var/spack/repos/builtin/packages/py-scipy/package.py +++ b/var/spack/repos/builtin/packages/py-scipy/package.py @@ -3,9 +3,6 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) -import platform - - class PyScipy(PythonPackage): """SciPy (pronounced "Sigh Pie") is a Scientific Library for Python. It provides many user-friendly and efficient numerical routines such @@ -104,12 +101,6 @@ class PyScipy(PythonPackage): if self.spec.satisfies('@:1.4 %gcc@10:'): env.set('FFLAGS', '-fallow-argument-mismatch') - # Kluge to get the gfortran linker to work correctly on Big - # Sur, at least until a gcc release > 10.2 is out with a fix. - # (There is a fix in their development tree.) - if platform.mac_ver()[0][0:2] == '11': - env.set('MACOSX_DEPLOYMENT_TARGET', '10.15') - def install_options(self, spec, prefix): args = [] if spec.satisfies('%fj'): diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py index a9103aca6d..b22d745176 100644 --- a/var/spack/repos/builtin/packages/python/package.py +++ b/var/spack/repos/builtin/packages/python/package.py @@ -6,7 +6,6 @@ import glob import json import os -import platform import re import sys @@ -416,9 +415,6 @@ class Python(AutotoolsPackage): 'errors may occur when installing Python modules w/ ' 'mixed C/C++ source files.').format(self.version)) - # Need this to allow python build to find the Python installation. - env.set('MACOSX_DEPLOYMENT_TARGET', platform.mac_ver()[0]) - env.unset('PYTHONPATH') env.unset('PYTHONHOME') -- cgit v1.2.3-70-g09d2