Skip to content

Commit bc8ad50

Browse files
XcodeBuild: pass deployment target from profile (#18496)
* pass deployment target based on profile to xcodebuild * quote project path * quote target param * add tests --------- Co-authored-by: Carlos Zoido <[email protected]>
1 parent 009cf68 commit bc8ad50

File tree

5 files changed

+62
-14
lines changed

5 files changed

+62
-14
lines changed

conan/tools/apple/apple.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ def resolve_apple_flags(conanfile, is_cross_building=False):
108108
return min_version_flag, apple_arch_flag, apple_isysroot_flag
109109

110110

111+
def xcodebuild_deployment_target_key(os_name):
112+
return {
113+
"Macos": "MACOSX_DEPLOYMENT_TARGET",
114+
"iOS": "IPHONEOS_DEPLOYMENT_TARGET",
115+
"tvOS": "TVOS_DEPLOYMENT_TARGET",
116+
"watchOS": "WATCHOS_DEPLOYMENT_TARGET",
117+
"visionOS": "XROS_DEPLOYMENT_TARGET",
118+
}.get(os_name) if os_name else None
119+
120+
111121
class XCRun:
112122
"""
113123
XCRun is a wrapper for the Apple **xcrun** tool used to get information for building.

conan/tools/apple/xcodebuild.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from conan.tools.apple import to_apple_arch
1+
from conan.tools.apple.apple import to_apple_arch, xcodebuild_deployment_target_key
22

33

44
class XcodeBuild(object):
@@ -8,6 +8,8 @@ def __init__(self, conanfile):
88
self._arch = to_apple_arch(self._conanfile)
99
self._sdk = conanfile.settings.get_safe("os.sdk") or ""
1010
self._sdk_version = conanfile.settings.get_safe("os.sdk_version") or ""
11+
self._os = conanfile.settings.get_safe("os")
12+
self._os_version = conanfile.settings.get_safe("os.version")
1113

1214
@property
1315
def _verbosity(self):
@@ -36,8 +38,13 @@ def build(self, xcodeproj, target=None):
3638
will build all the targets passing the ``-alltargets`` argument instead.
3739
:return: the return code for the launched ``xcodebuild`` command.
3840
"""
39-
target = "-target {}".format(target) if target else "-alltargets"
40-
cmd = "xcodebuild -project {} -configuration {} -arch {} " \
41+
target = "-target '{}'".format(target) if target else "-alltargets"
42+
cmd = "xcodebuild -project '{}' -configuration {} -arch {} " \
4143
"{} {} {}".format(xcodeproj, self._build_type, self._arch, self._sdkroot,
4244
self._verbosity, target)
45+
46+
deployment_target_key = xcodebuild_deployment_target_key(self._os)
47+
if deployment_target_key and self._os_version:
48+
cmd += f" {deployment_target_key}={self._os_version}"
49+
4350
self._conanfile.run(cmd)

conan/tools/apple/xcodetoolchain.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import textwrap
22

33
from conan.internal import check_duplicated_generator
4-
from conan.tools.apple.apple import to_apple_arch
4+
from conan.tools.apple.apple import to_apple_arch, xcodebuild_deployment_target_key
55
from conan.tools.apple.xcodedeps import GLOBAL_XCCONFIG_FILENAME, GLOBAL_XCCONFIG_TEMPLATE, \
66
_add_includes_to_file_or_create, _xcconfig_settings_filename, _xcconfig_conditional
77
from conan.internal.util.files import save
@@ -64,16 +64,10 @@ def _cppstd(self):
6464

6565
@property
6666
def _apple_deployment_target(self):
67-
deployment_target_key = {
68-
"Macos": "MACOSX_DEPLOYMENT_TARGET",
69-
"iOS": "IPHONEOS_DEPLOYMENT_TARGET",
70-
"tvOS": "TVOS_DEPLOYMENT_TARGET",
71-
"watchOS": "WATCHOS_DEPLOYMENT_TARGET",
72-
"visionOS": "XROS_DEPLOYMENT_TARGET",
73-
}.get(str(self._conanfile.settings.get_safe("os")))
67+
deployment_target_key = xcodebuild_deployment_target_key(self._conanfile.settings.get_safe("os"))
7468
return '{}{}={}'.format(deployment_target_key,
7569
_xcconfig_conditional(self._conanfile.settings, self.configuration),
76-
self.os_version) if self.os_version else ""
70+
self.os_version) if deployment_target_key and self.os_version else ""
7771

7872
@property
7973
def _clang_cxx_library(self):

test/functional/toolchains/apple/test_xcodebuild.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,12 @@ def package_info(self):
9191
client.run("install . --build=missing")
9292
client.run("install . -s build_type=Debug --build=missing")
9393
client.run_command("xcodegen generate")
94-
client.run("create . --build=missing -c tools.build:verbosity=verbose -c tools.compilation:verbosity=verbose")
94+
client.run("create . --build=missing -s os.version=15.0 -c tools.build:verbosity=verbose -c tools.compilation:verbosity=verbose")
95+
assert "MACOSX_DEPLOYMENT_TARGET=15.0" in client.out
9596
assert "xcodebuild: error: invalid option" not in client.out
9697
assert "hello/0.1: Hello World Release!" in client.out
9798
assert "App Release!" in client.out
98-
client.run("create . -s build_type=Debug --build=missing")
99+
client.run("create . -s build_type=Debug -s os.version=15.0 --build=missing")
99100
assert "hello/0.1: Hello World Debug!" in client.out
100101
assert "App Debug!" in client.out
101102

test/unittests/client/tools/apple/test_xcodebuild.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,39 @@ def test_sdk():
6464
xcodebuild = XcodeBuild(conanfile)
6565
xcodebuild.build("app.xcodeproj")
6666
assert "SDKROOT" not in conanfile.command
67+
68+
69+
@pytest.mark.parametrize("os_name, os_version, expected_key", [
70+
("Macos", "14.0", "MACOSX_DEPLOYMENT_TARGET"),
71+
("iOS", "15.1", "IPHONEOS_DEPLOYMENT_TARGET"),
72+
("watchOS", "8.0", "WATCHOS_DEPLOYMENT_TARGET"),
73+
("tvOS", "15.0", "TVOS_DEPLOYMENT_TARGET"),
74+
("visionOS", "1.0", "XROS_DEPLOYMENT_TARGET")
75+
])
76+
def test_deployment_target_and_quoting(os_name, os_version, expected_key):
77+
"""
78+
Checks that the correct deployment target is passed and that paths are quoted.
79+
"""
80+
conanfile = ConanFileMock()
81+
conanfile.settings = MockSettings({"os": os_name, "os.version": os_version})
82+
xcodebuild = XcodeBuild(conanfile)
83+
84+
xcodebuild.build("My Project.xcodeproj", target="My Target")
85+
86+
expected_arg = f" {expected_key}={os_version}"
87+
assert expected_arg in conanfile.command
88+
89+
assert "-project 'My Project.xcodeproj'" in conanfile.command
90+
assert "-target 'My Target'" in conanfile.command
91+
92+
93+
def test_no_deployment_target_if_version_is_missing():
94+
"""
95+
Checks that the deployment target argument is not added if os.version is missing.
96+
"""
97+
conanfile = ConanFileMock()
98+
conanfile.settings = MockSettings({"os": "Macos"})
99+
xcodebuild = XcodeBuild(conanfile)
100+
xcodebuild.build("app.xcodeproj")
101+
102+
assert "MACOSX_DEPLOYMENT_TARGET" not in conanfile.command

0 commit comments

Comments
 (0)