diff options
| -rw-r--r-- | mesonbuild/compilers/swift.py | 34 | ||||
| -rw-r--r-- | test cases/swift/9 sdk path from dep/foo.swift | 4 | ||||
| -rw-r--r-- | test cases/swift/9 sdk path from dep/meson.build | 12 |
3 files changed, 48 insertions, 2 deletions
diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index a2525f927..d92688231 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -3,14 +3,17 @@ from __future__ import annotations +import re import subprocess, os.path import typing as T -from ..mesonlib import EnvironmentException - +from .. import mlog +from ..mesonlib import EnvironmentException, MesonException from .compilers import Compiler, clike_debug_args + if T.TYPE_CHECKING: + from ..dependencies import Dependency from ..envconfig import MachineInfo from ..environment import Environment from ..linkers.linkers import DynamicLinker @@ -39,6 +42,17 @@ class SwiftCompiler(Compiler): is_cross=is_cross, full_version=full_version, linker=linker) self.version = version + if self.info.is_darwin(): + try: + self.sdk_path = subprocess.check_output(['xcrun', '--show-sdk-path'], + universal_newlines=True, + encoding='utf-8', stderr=subprocess.STDOUT).strip() + except subprocess.CalledProcessError as e: + mlog.error("Failed to get Xcode SDK path: " + e.output) + raise MesonException('Xcode license not accepted yet. Run `sudo xcodebuild -license`.') + except FileNotFoundError: + mlog.error('xcrun not found. Install Xcode to compile Swift code.') + raise MesonException('Could not detect Xcode. Please install it to compile Swift code.') def get_pic_args(self) -> T.List[str]: return [] @@ -55,6 +69,22 @@ class SwiftCompiler(Compiler): def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: return ['-emit-dependencies'] + def get_dependency_compile_args(self, dep: Dependency) -> T.List[str]: + args = dep.get_compile_args() + # Some deps might sneak in a hardcoded path to an older macOS SDK, which can + # cause compilation errors. Let's replace all .sdk paths with the current one. + # SwiftPM does it this way: https://github.com/swiftlang/swift-package-manager/pull/6772 + # Not tested on anything else than macOS for now. + if not self.info.is_darwin(): + return args + pattern = re.compile(r'.*\/MacOSX[^\/]*\.sdk(\/.*|$)') + for i, arg in enumerate(args): + if arg.startswith('-I'): + match = pattern.match(arg) + if match: + args[i] = '-I' + self.sdk_path + match.group(1) + return args + def depfile_for_object(self, objfile: str) -> T.Optional[str]: return os.path.splitext(objfile)[0] + '.' + self.get_depfile_suffix() diff --git a/test cases/swift/9 sdk path from dep/foo.swift b/test cases/swift/9 sdk path from dep/foo.swift new file mode 100644 index 000000000..6ca38879f --- /dev/null +++ b/test cases/swift/9 sdk path from dep/foo.swift @@ -0,0 +1,4 @@ +// This import is needed for swiftc to implictly import the FFI module +// which will in turn conflict with the dependency's include path and error out +// if we don't manually replace all SDK paths with the newest one. +import Foundation diff --git a/test cases/swift/9 sdk path from dep/meson.build b/test cases/swift/9 sdk path from dep/meson.build new file mode 100644 index 000000000..4cc44bc72 --- /dev/null +++ b/test cases/swift/9 sdk path from dep/meson.build @@ -0,0 +1,12 @@ +project('swift sdk include dir test', 'swift') + +bar_dep = declare_dependency( + # Simulates including 'libffi' from brew as a dep via pkg-config + # Without a workaround that replaces all SDK paths with the most recent one, + # a compile error will occur due to conflicting definitions of the FFI module. + compile_args: '-I/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include/ffi', +) + +foo = static_library('foo', 'foo.swift', + dependencies: [bar_dep], +) |
