From 58cb456b3d178775c519c51f18880708cb93ba86 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 15 Apr 2025 10:18:42 +0200 Subject: [PATCH 1/5] environment: handle all iOS variants as xnu All of iOS, tvOS, visionOS, watchOS use the XNU kernel. Report that and also make them return true for is_darwin() which is really more like "is_xnu()". Co-authored-by: Russell Keith-Magee Signed-off-by: Paolo Bonzini --- docs/markdown/Reference-tables.md | 2 ++ mesonbuild/envconfig.py | 4 ++-- mesonbuild/environment.py | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md index 2357ff459af4..9f5e39a06ece 100644 --- a/docs/markdown/Reference-tables.md +++ b/docs/markdown/Reference-tables.md @@ -202,6 +202,8 @@ Meson natively. | ios-simulator | | | tvos | Apple tvOS | | tvos-simulator | | +| visionos | Apple visionOS | +| visionos-simulator | | | watchos | Apple watchOS | | watchos-simulator | | diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index 86bad9be23ee..ffd7a51c250b 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -310,9 +310,9 @@ def is_linux(self) -> bool: def is_darwin(self) -> bool: """ - Machine is Darwin (iOS/tvOS/OS X)? + Machine is Darwin (macOS/iOS/tvOS/visionOS/watchOS)? """ - return self.system in {'darwin', 'ios', 'tvos'} + return self.system in {'darwin', 'ios', 'tvos', 'visionos', 'watchos'} def is_android(self) -> bool: """ diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 484ef45d478d..0c0324c18cf1 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -447,6 +447,10 @@ def detect_cpu(compilers: CompilersDict) -> str: 'linux': 'linux', 'cygwin': 'nt', 'darwin': 'xnu', + 'ios': 'xnu', + 'tvos': 'xnu', + 'visionos': 'xnu', + 'watchos': 'xnu', 'dragonfly': 'dragonfly', 'haiku': 'haiku', } From fde7200386b2f7122181a5605071b6815618152a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 15 Apr 2025 10:27:20 +0200 Subject: [PATCH 2/5] linkers: pass system to DynamicLinker.__init__ for Darwin linkers Apple linkers need to use different arguments on macOS and iOS-like platforms. Pass the system to the constructor so that it can be examined. Co-authored-by: Russell Keith-Magee Signed-off-by: Paolo Bonzini --- mesonbuild/compilers/detect.py | 4 ++-- mesonbuild/linkers/detect.py | 13 ++++++++++--- mesonbuild/linkers/linkers.py | 4 +++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index c8b67f479471..fda6c07bc22f 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -1062,8 +1062,8 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust version=cc.linker.version, **extra_args) # type: ignore else: linker = type(cc.linker)(compiler, for_machine, cc.LINKER_PREFIX, - always_args=always_args, version=cc.linker.version, - **extra_args) + always_args=always_args, system=cc.linker.system, + version=cc.linker.version, **extra_args) elif 'link' in override[0]: linker = guess_win_linker(env, override, cls, version, for_machine, use_linker_prefix=False) diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py index 1bbe7b2e1520..87c738bee174 100644 --- a/mesonbuild/linkers/detect.py +++ b/mesonbuild/linkers/detect.py @@ -122,6 +122,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env) extra_args = extra_args or [] + system = env.machines[for_machine].system ldflags = env.coredata.get_external_link_args(for_machine, comp_class.language) extra_args += comp_class._unix_args_to_native(ldflags, env.machines[for_machine]) @@ -155,7 +156,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty lld_cls = linkers.LLVMDynamicLinker linker = lld_cls( - compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) + compiler, for_machine, comp_class.LINKER_PREFIX, override, system=system, version=v) elif 'Snapdragon' in e and 'LLVM' in e: linker = linkers.QualcommLLVMDynamicLinker( compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) @@ -213,7 +214,10 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty elif 'xtools-' in o.split('\n', maxsplit=1)[0]: xtools = o.split(' ', maxsplit=1)[0] v = xtools.split('-', maxsplit=2)[1] - linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) + linker = linkers.AppleDynamicLinker( + compiler, for_machine, comp_class.LINKER_PREFIX, override, + system=system, version=v + ) # detect linker on MacOS - must be after other platforms because the # "(use -v to see invocation)" will match clang on other platforms, # but the rest of the checks will fail and call __failed_to_detect_linker. @@ -232,7 +236,10 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty break else: __failed_to_detect_linker(compiler, check_args, o, e) - linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) + linker = linkers.AppleDynamicLinker( + compiler, for_machine, comp_class.LINKER_PREFIX, override, + system=system, version=v + ) else: __failed_to_detect_linker(compiler, check_args, o, e) return linker diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index 4eec82edd177..095cb025b08f 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -130,9 +130,11 @@ def _apply_prefix(self, arg: T.Union[str, T.List[str]]) -> T.List[str]: def __init__(self, exelist: T.List[str], for_machine: mesonlib.MachineChoice, prefix_arg: T.Union[str, T.List[str]], - always_args: T.List[str], *, version: str = 'unknown version'): + always_args: T.List[str], *, system: str = 'unknown system', + version: str = 'unknown version'): self.exelist = exelist self.for_machine = for_machine + self.system = system self.version = version self.prefix_arg = prefix_arg self.always_args = always_args From ff91d5c369cc94a665ebc5a3afa6e3eb3731b2cf Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 15 Apr 2025 10:32:37 +0200 Subject: [PATCH 3/5] linkers: apple: fix shared module args iOS should not use -undefined,dynamic_lookup; whereas macOS should revert from -dynamiclib to -bundle, as was the case before commit cfb5a48e0 ("linkers: darwin: do not use -bundle for shared_modules", 2025-03-24), because Postgres wants to use -bundle_loader and that is only possible together with -bundle. Co-authored-by: Russell Keith-Magee Signed-off-by: Paolo Bonzini --- mesonbuild/linkers/linkers.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index 095cb025b08f..2d02771a68bf 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -760,10 +760,17 @@ def get_asneeded_args(self) -> T.List[str]: return self._apply_prefix('-dead_strip_dylibs') def get_allow_undefined_args(self) -> T.List[str]: - return self._apply_prefix('-undefined,dynamic_lookup') + # iOS doesn't allow undefined symbols when linking + if self.system == 'ios': + return [] + else: + return self._apply_prefix('-undefined,dynamic_lookup') - def get_std_shared_module_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - return ['-bundle'] + self._apply_prefix('-undefined,dynamic_lookup') + def get_std_shared_module_args(self, target: 'BuildTarget') -> T.List[str]: + if self.system == 'ios': + return ['-dynamiclib'] + else: + return ['-bundle'] + self.get_allow_undefined_args() def get_pie_args(self) -> T.List[str]: return [] From 18f795870381a50e897de5084a6c9076795d6904 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 16 Apr 2025 16:50:46 -0400 Subject: [PATCH 4/5] linkers: fix regression when using lld after iOS changes ``` $ LDFLAGS="-fuse-ld=lld" meson setup builddir/ [...] linker = lld_cls( compiler, for_machine, comp_class.LINKER_PREFIX, override, system=system, version=v) TypeError: LLVMDynamicLinker.__init__() got an unexpected keyword argument 'system' ``` Fixes regression in commit cece1a7e9992a3bbcc35f90777ba22ba9d62b538. We pass system=system to the linker construction, which worked fine for Apple LLVM LD64 as that inherited `__init__` from DynamicLinker. But non-Apple LLD had an overridden `__init__` which wasn't adapted. Even if it is thrown away and never used, since LLVM isn't an Apple linker, we still need to obey the argument contract. --- mesonbuild/linkers/linkers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index 2d02771a68bf..efe9e7e2e82b 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -897,8 +897,9 @@ class LLVMDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, Dyna def __init__(self, exelist: T.List[str], for_machine: mesonlib.MachineChoice, prefix_arg: T.Union[str, T.List[str]], - always_args: T.List[str], *, version: str = 'unknown version'): - super().__init__(exelist, for_machine, prefix_arg, always_args, version=version) + always_args: T.List[str], *, system: str = 'unknown system', + version: str = 'unknown version'): + super().__init__(exelist, for_machine, prefix_arg, always_args, system=system, version=version) # Some targets don't seem to support this argument (windows, wasm, ...) self.has_allow_shlib_undefined = self._supports_flag('--allow-shlib-undefined', always_args) From 6fa5876dfe33878188cde944dded8732782af0df Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Wed, 2 Apr 2025 14:51:36 +0800 Subject: [PATCH 5/5] Add numpy specific extensions for iOS builds. --- docs/markdown/Dependencies.md | 9 +++++---- mesonbuild/dependencies/blas_lapack.py | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md index 6f975c456d9a..ca51947007ae 100644 --- a/docs/markdown/Dependencies.md +++ b/docs/markdown/Dependencies.md @@ -462,10 +462,11 @@ TODO Supports the BLAS and LAPACK components of macOS Accelerate, also referred to as the vecLib framework. ILP64 support is only available on macOS 13.3 and up. -From macOS 13.3, Accelerate ships with two different builds of 32-bit (LP64) -BLAS and LAPACK. Meson will default to the newer of those builds, by defining -`ACCELERATE_NEW_LAPACK`, unless `MACOS_DEPLOYMENT_TARGET` is set to a version -lower than 13.3. +From macOS 13.3 and iOS 16.4, Accelerate ships with two different builds of +32-bit (LP64) BLAS and LAPACK. Meson will default to the newer of those builds, +by defining `ACCELERATE_NEW_LAPACK`, unless `MACOS_DEPLOYMENT_TARGET` is set to +a version lower than 13.3, or `IPHONEOS_DEPLOYMENT_TARGET` is set to a version +lower than 16.4. ```meson accelerate_dep = dependency('accelerate', diff --git a/mesonbuild/dependencies/blas_lapack.py b/mesonbuild/dependencies/blas_lapack.py index 3bd4ae8425bd..a7e4656b4d1e 100644 --- a/mesonbuild/dependencies/blas_lapack.py +++ b/mesonbuild/dependencies/blas_lapack.py @@ -738,7 +738,10 @@ def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T. self.parse_modules(kwargs) for_machine = MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST - if environment.machines[for_machine].is_darwin() and self.check_macOS_recent_enough(): + if ( + (environment.machines[for_machine].system == 'darwin' and self.check_macOS_recent_enough()) + or (environment.machines[for_machine].system == 'ios' and self.check_iOS_recent_enough()) + ): self.detect(kwargs) def check_macOS_recent_enough(self) -> bool: @@ -752,6 +755,18 @@ def check_macOS_recent_enough(self) -> bool: sdk_version = subprocess.run(cmd, capture_output=True, check=True, text=True).stdout.strip() return mesonlib.version_compare(sdk_version, '>=13.3') + def check_iOS_recent_enough(self) -> bool: + ios_version = platform.ios_ver().system + deploy_target = os.environ.get('IPHONEOS_DEPLOYMENT_TARGET', ios_version) + if not mesonlib.version_compare(deploy_target, '>=16.4'): + return False + + # We also need the SDK to be >=16.4 + sdk = "iphonesimulator" if platform.ios_ver().is_simulator else "iphoneos" + cmd = ['xcrun', '-sdk', sdk, '--show-sdk-version'] + sdk_version = subprocess.run(cmd, capture_output=True, check=True, text=True).stdout.strip() + return mesonlib.version_compare(sdk_version, '>=16.4') + def detect(self, kwargs: T.Dict[str, T.Any]) -> None: from .framework import ExtraFrameworkDependency dep = ExtraFrameworkDependency('Accelerate', self.env, kwargs)