darwin: robust macos version detection (#28991)
Prefer `sw_vers` to `platform.mac_ver`. In anaconda3 installation, for example, the latter reports 10.16 on Monterey -- I think this is affected by how and where the python instance was built. Use MACOSX_DEPLOYMENT_TARGET if present to override the operating system choice.
This commit is contained in:
parent
b768fb85c6
commit
6c61c2695a
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
import os
|
||||||
import platform as py_platform
|
import platform as py_platform
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -12,10 +13,49 @@
|
|||||||
from ._operating_system import OperatingSystem
|
from ._operating_system import OperatingSystem
|
||||||
|
|
||||||
|
|
||||||
# FIXME: store versions inside OperatingSystem as a Version instead of string
|
|
||||||
def macos_version():
|
def macos_version():
|
||||||
"""temporary workaround to return a macOS version as a Version object
|
"""Get the current macOS version as a version object.
|
||||||
|
|
||||||
|
This has three mechanisms for determining the macOS version, which is used
|
||||||
|
for spack identification (the ``os`` in the spec's ``arch``) and indirectly
|
||||||
|
for setting the value of ``MACOSX_DEPLOYMENT_TARGET``, which affects the
|
||||||
|
``minos`` value of the ``LC_BUILD_VERSION`` macho header. Mixing ``minos``
|
||||||
|
values can lead to lots of linker warnings, and using a consistent version
|
||||||
|
(pinned to the major OS version) allows distribution across clients that
|
||||||
|
might be slightly behind.
|
||||||
|
|
||||||
|
The version determination is made with three mechanisms in decreasing
|
||||||
|
priority:
|
||||||
|
|
||||||
|
1. The ``MACOSX_DEPLOYMENT_TARGET`` variable overrides the actual operating
|
||||||
|
system version, just like the value can be used to build for older macOS
|
||||||
|
targets on newer systems. Spack currently will truncate this value when
|
||||||
|
building packages, but at least the major version will be the same.
|
||||||
|
|
||||||
|
2. The system ``sw_vers`` command reports the actual operating system
|
||||||
|
version.
|
||||||
|
|
||||||
|
3. The Python ``platform.mac_ver`` function is a fallback if the operating
|
||||||
|
system identification fails, because some Python versions and/or
|
||||||
|
installations report the OS
|
||||||
|
on which Python was *built* rather than the one on which it is running.
|
||||||
"""
|
"""
|
||||||
|
env_ver = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None)
|
||||||
|
if env_ver:
|
||||||
|
return Version(env_ver)
|
||||||
|
|
||||||
|
try:
|
||||||
|
output = Executable('sw_vers')(output=str, fail_on_error=False)
|
||||||
|
except Exception:
|
||||||
|
# FileNotFoundError, or spack.util.executable.ProcessError
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
match = re.search(r'ProductVersion:\s*([0-9.]+)', output)
|
||||||
|
if match:
|
||||||
|
return Version(match.group(1))
|
||||||
|
|
||||||
|
# Fall back to python-reported version, which can be inaccurate around
|
||||||
|
# macOS 11 (e.g. showing 10.16 for macOS 12)
|
||||||
return Version(py_platform.mac_ver()[0])
|
return Version(py_platform.mac_ver()[0])
|
||||||
|
|
||||||
|
|
||||||
@ -26,7 +66,7 @@ def macos_cltools_version():
|
|||||||
SDK path.
|
SDK path.
|
||||||
"""
|
"""
|
||||||
pkgutil = Executable('pkgutil')
|
pkgutil = Executable('pkgutil')
|
||||||
output = pkgutil('--pkg-info=com.apple.pkg.CLTools_Executables',
|
output = pkgutil('--pkg-info=com.apple.pkg.cltools_executables',
|
||||||
output=str, fail_on_error=False)
|
output=str, fail_on_error=False)
|
||||||
match = re.search(r'version:\s*([0-9.]+)', output)
|
match = re.search(r'version:\s*([0-9.]+)', output)
|
||||||
if match:
|
if match:
|
||||||
@ -99,11 +139,13 @@ def __init__(self):
|
|||||||
'12': 'monterey',
|
'12': 'monterey',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version = macos_version()
|
||||||
|
|
||||||
# Big Sur versions go 11.0, 11.0.1, 11.1 (vs. prior versions that
|
# Big Sur versions go 11.0, 11.0.1, 11.1 (vs. prior versions that
|
||||||
# only used the minor component)
|
# only used the minor component)
|
||||||
part = 1 if macos_version() >= Version('11') else 2
|
part = 1 if version >= Version('11') else 2
|
||||||
|
|
||||||
mac_ver = str(macos_version().up_to(part))
|
mac_ver = str(version.up_to(part))
|
||||||
name = mac_releases.get(mac_ver, "macos")
|
name = mac_releases.get(mac_ver, "macos")
|
||||||
super(MacOs, self).__init__(name, mac_ver)
|
super(MacOs, self).__init__(name, mac_ver)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
import platform
|
import platform as py_platform
|
||||||
|
|
||||||
import archspec.cpu
|
import archspec.cpu
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ def __init__(self):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def detect(cls):
|
def detect(cls):
|
||||||
return 'darwin' in platform.system().lower()
|
return 'darwin' in py_platform.system().lower()
|
||||||
|
|
||||||
def setup_platform_environment(self, pkg, env):
|
def setup_platform_environment(self, pkg, env):
|
||||||
"""Specify deployment target based on target OS version.
|
"""Specify deployment target based on target OS version.
|
||||||
|
Loading…
Reference in New Issue
Block a user