summaryrefslogtreecommitdiff
path: root/mesonbuild/compilers/swift.py
diff options
context:
space:
mode:
authorPiotr BrzeziƄski <piotr@centricular.com>2024-07-01 18:55:13 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2025-01-29 22:46:34 +0200
commit01584101b7e66c37fa5963eb7d7057e3301ea06e (patch)
treead06c1bd912f9b5a09ae0e1ae0b505763edfade6 /mesonbuild/compilers/swift.py
parentae1bb2f87b88a66591a152038f4271b83d575a92 (diff)
downloadmeson-01584101b7e66c37fa5963eb7d7057e3301ea06e.tar.gz
swift: Fix duplicate SDK include paths causing a compile error
Some dependencies can bring include paths pointing to older macOS SDK's. In this case, it was libffi pointing to SDK from 12.0. When the Foundation framework is imported in Swift, swiftc attempts to import the FFI module from the most recent version of the SDK, which causes a compilation error because of conflicting definitions between the two SDK versions. SwiftPM also had this problem: https://github.com/swiftlang/swift-package-manager/pull/6772 The solution on our side is a simplified version of what SwiftPM did. Let's naively look for .sdk paths in the compile args of our dependencies and replace them with the most recent one. I included a test which is confirmed to fail without the workaround added in this patch. This was not tested on anything else than macOS, but I don't expect it to make the situation worse in any case.
Diffstat (limited to 'mesonbuild/compilers/swift.py')
-rw-r--r--mesonbuild/compilers/swift.py34
1 files changed, 32 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()