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.
This commit is contained in:
		| @@ -15,8 +15,10 @@ | |||||||
| 
 | 
 | ||||||
| from spack.build_environment import InstallError | from spack.build_environment import InstallError | ||||||
| from spack.directives import depends_on | 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.package import PackageBase, run_after, run_before | ||||||
| from spack.util.executable import Executable | from spack.util.executable import Executable | ||||||
|  | from spack.version import Version | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class AutotoolsPackage(PackageBase): | class AutotoolsPackage(PackageBase): | ||||||
| @@ -415,6 +417,13 @@ def configure(self, spec, prefix): | |||||||
|         with working_dir(self.build_directory, create=True): |         with working_dir(self.build_directory, create=True): | ||||||
|             inspect.getmodule(self).configure(*options) |             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): |     def build(self, spec, prefix): | ||||||
|         """Makes the build targets specified by |         """Makes the build targets specified by | ||||||
|         :py:attr:``~.AutotoolsPackage.build_targets`` |         :py:attr:``~.AutotoolsPackage.build_targets`` | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| # SPDX-License-Identifier: (Apache-2.0 OR MIT) | # SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||||||
| 
 | 
 | ||||||
| import platform as py_platform | import platform as py_platform | ||||||
|  | import re | ||||||
| 
 | 
 | ||||||
| from spack.util.executable import Executable | from spack.util.executable import Executable | ||||||
| from spack.version import Version | from spack.version import Version | ||||||
| @@ -18,11 +19,49 @@ def macos_version(): | |||||||
|     return Version(py_platform.mac_ver()[0]) |     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(): | def macos_sdk_path(): | ||||||
|     """Return SDK path |     """Return path to the active macOS SDK. | ||||||
|     """ |     """ | ||||||
|     xcrun = Executable('xcrun') |     xcrun = Executable('xcrun') | ||||||
|     return xcrun('--show-sdk-path', output=str, error=str).rstrip() |     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 Version(xcrun('--show-sdk-version', output=str).rstrip()) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class MacOs(OperatingSystem): | class MacOs(OperatingSystem): | ||||||
|   | |||||||
| @@ -104,11 +104,11 @@ def operating_system(self, name): | |||||||
| 
 | 
 | ||||||
|         return self.operating_sys.get(name, None) |         return self.operating_sys.get(name, None) | ||||||
| 
 | 
 | ||||||
|     @classmethod |     def setup_platform_environment(self, pkg, env): | ||||||
|     def setup_platform_environment(cls, pkg, env): |  | ||||||
|         """Subclass can override this method if it requires any |         """Subclass can override this method if it requires any | ||||||
|         platform-specific build environment modifications. |         platform-specific build environment modifications. | ||||||
|         """ |         """ | ||||||
|  |         pass | ||||||
| 
 | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def detect(cls): |     def detect(cls): | ||||||
|   | |||||||
| @@ -84,8 +84,7 @@ def __init__(self): | |||||||
|         if self.front_os != self.back_os: |         if self.front_os != self.back_os: | ||||||
|             self.add_operating_system(self.front_os, front_distro) |             self.add_operating_system(self.front_os, front_distro) | ||||||
| 
 | 
 | ||||||
|     @classmethod |     def setup_platform_environment(self, pkg, env): | ||||||
|     def setup_platform_environment(cls, pkg, env): |  | ||||||
|         """ Change the linker to default dynamic to be more |         """ Change the linker to default dynamic to be more | ||||||
|             similar to linux/standard linker behavior |             similar to linux/standard linker behavior | ||||||
|         """ |         """ | ||||||
|   | |||||||
| @@ -39,3 +39,25 @@ def __init__(self): | |||||||
|     @classmethod |     @classmethod | ||||||
|     def detect(cls): |     def detect(cls): | ||||||
|         return 'darwin' in platform.system().lower() |         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)) | ||||||
|   | |||||||
| @@ -15,10 +15,10 @@ | |||||||
| import re | import re | ||||||
| from contextlib import contextmanager | from contextlib import contextmanager | ||||||
| 
 | 
 | ||||||
| from llnl.util import tty |  | ||||||
| from llnl.util.lang import match_predicate | from llnl.util.lang import match_predicate | ||||||
| 
 | 
 | ||||||
| from spack import * | from spack import * | ||||||
|  | from spack.operating_systems.mac_os import macos_version | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Perl(Package):  # Perl doesn't use Autotools, it should subclass Package | class Perl(Package):  # Perl doesn't use Autotools, it should subclass Package | ||||||
| @@ -297,24 +297,13 @@ def setup_dependent_package(self, module, dependent_spec): | |||||||
|     def setup_build_environment(self, env): |     def setup_build_environment(self, env): | ||||||
|         spec = self.spec |         spec = self.spec | ||||||
| 
 | 
 | ||||||
|         # This is to avoid failures when using -mmacosx-version-min=11.1 |         if (spec.version <= Version('5.34.0') | ||||||
|         # since not all Apple Clang compilers support that version range |             and spec.platform == 'darwin' | ||||||
|         # See https://eclecticlight.co/2020/07/21/big-sur-is-both-10-16-and-11-0-its-official/ |             and macos_version() >= Version('10.16')): | ||||||
|         # It seems that this is only necessary for older versions of the |             # Older perl versions reject MACOSX_DEPLOYMENT_TARGET=11 or higher | ||||||
|         # command line tools rather than the xcode/clang version. |             # as "unexpected"; override the environment variable set by spack's | ||||||
|         if spec.satisfies('os=bigsur'): |             # platforms.darwin . | ||||||
|             pkgutil = Executable('pkgutil') |             env.set('MACOSX_DEPLOYMENT_TARGET', '10.16') | ||||||
|             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) |  | ||||||
| 
 | 
 | ||||||
|         # This is how we tell perl the locations of bzip and zlib. |         # This is how we tell perl the locations of bzip and zlib. | ||||||
|         env.set('BUILD_BZIP2', 0) |         env.set('BUILD_BZIP2', 0) | ||||||
|   | |||||||
| @@ -3,9 +3,6 @@ | |||||||
| # | # | ||||||
| # SPDX-License-Identifier: (Apache-2.0 OR MIT) | # SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||||||
| 
 | 
 | ||||||
| import platform |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class PyScipy(PythonPackage): | class PyScipy(PythonPackage): | ||||||
|     """SciPy (pronounced "Sigh Pie") is a Scientific Library for Python. |     """SciPy (pronounced "Sigh Pie") is a Scientific Library for Python. | ||||||
|     It provides many user-friendly and efficient numerical routines such |     It provides many user-friendly and efficient numerical routines such | ||||||
| @@ -104,12 +101,6 @@ def setup_build_environment(self, env): | |||||||
|         if self.spec.satisfies('@:1.4 %gcc@10:'): |         if self.spec.satisfies('@:1.4 %gcc@10:'): | ||||||
|             env.set('FFLAGS', '-fallow-argument-mismatch') |             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): |     def install_options(self, spec, prefix): | ||||||
|         args = [] |         args = [] | ||||||
|         if spec.satisfies('%fj'): |         if spec.satisfies('%fj'): | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ | |||||||
| import glob | import glob | ||||||
| import json | import json | ||||||
| import os | import os | ||||||
| import platform |  | ||||||
| import re | import re | ||||||
| import sys | import sys | ||||||
| 
 | 
 | ||||||
| @@ -416,9 +415,6 @@ def setup_build_environment(self, env): | |||||||
|                       'errors may occur when installing Python modules w/ ' |                       'errors may occur when installing Python modules w/ ' | ||||||
|                       'mixed C/C++ source files.').format(self.version)) |                       '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('PYTHONPATH') | ||||||
|         env.unset('PYTHONHOME') |         env.unset('PYTHONHOME') | ||||||
| 
 | 
 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Seth R. Johnson
					Seth R. Johnson