Skip to content

Commit 3c95bf0

Browse files
committed
Create an Android CMake toolchain file instead to cross-compile Testing
1 parent 3f36409 commit 3c95bf0

File tree

3 files changed

+146
-35
lines changed

3 files changed

+146
-35
lines changed

swift-ci/sdks/android/patches/apply-patches.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ cd ${1}
55

66
case "${BUILD_SCHEME}" in
77
swift-*-branch)
8-
git apply -v -C1 ${patches_dir}/swift-android.patch
98
git apply -v -C1 ${patches_dir}/swift-android-devel.patch
9+
git apply -v -C1 ${patches_dir}/swift-android.patch
1010
;;
1111
development)
1212
git apply -v -C1 ${patches_dir}/swift-android.patch

swift-ci/sdks/android/patches/swift-android-devel.patch

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,28 @@ index bfb69965890..b5e9f5349c2 100644
1515
define("CMAKE_Swift_COMPILER:PATH", cmake_swiftc_path)
1616
else:
1717
cmake_swiftc_path = os.getenv('CMAKE_Swift_COMPILER', toolchain.swiftc)
18+
diff --git a/swift/utils/swift_build_support/swift_build_support/products/product.py b/swift/utils/swift_build_support/swift_build_support/products/product.py
19+
index 47e7ab79905..d88c3c242ad 100644
20+
--- a/swift/utils/swift_build_support/swift_build_support/products/product.py
21+
+++ b/swift/utils/swift_build_support/swift_build_support/products/product.py
22+
@@ -389,7 +395,7 @@ class Product(object):
23+
sysroot_arch, vendor, abi = self.get_linux_target_components(arch)
24+
return '{}-{}-linux-{}'.format(sysroot_arch, vendor, abi)
25+
26+
- def generate_linux_toolchain_file(self, platform, arch):
27+
+ def generate_linux_toolchain_file(self, platform, arch, crosscompiling=True):
28+
"""
29+
Generates a new CMake tolchain file that specifies Linux as a target
30+
platform.
31+
@@ -402,8 +408,9 @@ class Product(object):
32+
33+
toolchain_args = {}
34+
35+
- toolchain_args['CMAKE_SYSTEM_NAME'] = 'Linux'
36+
- toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = arch
37+
+ if crosscompiling:
38+
+ toolchain_args['CMAKE_SYSTEM_NAME'] = 'Linux'
39+
+ toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = arch
40+
41+
# We only set the actual sysroot if we are actually cross
42+
# compiling. This is important since otherwise cmake seems to change the

swift-ci/sdks/android/patches/swift-android.patch

Lines changed: 120 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,43 +22,129 @@ index 16e05052609..7ab8cebfab8 100755
2222

2323
cmake_options=(
2424
-DENABLE_SWIFT=YES
25-
diff --git a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py
26-
index 324d1a77eea..e88601a8701 100644
27-
--- a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py
28-
+++ b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py
29-
@@ -13,6 +13,9 @@
30-
import os
25+
diff --git a/swift/utils/swift_build_support/swift_build_support/products/product.py b/swift/utils/swift_build_support/swift_build_support/products/product.py
26+
index d88c3c242ad..dad4a539075 100644
27+
--- a/swift/utils/swift_build_support/swift_build_support/products/product.py
28+
+++ b/swift/utils/swift_build_support/swift_build_support/products/product.py
29+
@@ -409,18 +409,33 @@ class Product(object):
30+
toolchain_args = {}
3131

32-
from build_swift.build_swift.versions import Version
33-
+from ..host_specific_configuration \
34-
+ import HostSpecificConfiguration
35-
+from ..targets import StdlibDeploymentTarget
32+
if crosscompiling:
33+
- toolchain_args['CMAKE_SYSTEM_NAME'] = 'Linux'
34+
- toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = arch
35+
+ if platform == "linux":
36+
+ toolchain_args['CMAKE_SYSTEM_NAME'] = 'Linux'
37+
+ toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = arch
38+
+ elif platform == "android":
39+
+ toolchain_args['CMAKE_SYSTEM_NAME'] = 'Android'
40+
+ toolchain_args['CMAKE_SYSTEM_VERSION'] = self.args.android_api_level
41+
+ toolchain_args['CMAKE_SYSTEM_PROCESSOR'] = arch if not arch == 'armv7' \
42+
+ else 'armv7-a'
43+
+ toolchain_args['CMAKE_ANDROID_NDK'] = self.args.android_ndk
44+
+ toolchain_args['CMAKE_FIND_ROOT_PATH'] = self.args.cross_compile_deps_path
45+
+ # This is a workaround for a CMake 3.30+ bug,
46+
+ # https://gitlab.kitware.com/cmake/cmake/-/issues/26154, and can
47+
+ # be removed once that is fixed.
48+
+ toolchain_args['CMAKE_SHARED_LINKER_FLAGS'] = '\"\"'
3649

37-
from . import cmake_product
38-
from . import product
39-
@@ -115,6 +117,25 @@ class SwiftTestingCMakeShim(cmake_product.CMakeProduct):
40-
# FIXME: If we build macros for the builder, specify the path.
41-
self.cmake_options.define('SwiftTesting_MACRO', 'NO')
50+
# We only set the actual sysroot if we are actually cross
51+
# compiling. This is important since otherwise cmake seems to change the
52+
# RUNPATH to be a relative rather than an absolute path, breaking
53+
# certain cmark tests (and maybe others).
54+
- maybe_sysroot = self.get_linux_sysroot(platform, arch)
55+
- if maybe_sysroot is not None:
56+
- toolchain_args['CMAKE_SYSROOT'] = maybe_sysroot
57+
-
58+
- target = self.get_linux_target(platform, arch)
59+
+ if platform == "linux":
60+
+ maybe_sysroot = self.get_linux_sysroot(platform, arch)
61+
+ if maybe_sysroot is not None:
62+
+ toolchain_args['CMAKE_SYSROOT'] = maybe_sysroot
63+
+
64+
+ target = self.get_linux_target(platform, arch)
65+
+ elif platform == "android":
66+
+ target = '%s-unknown-linux-android%s' % (arch, self.args.android_api_level)
67+
if self.toolchain.cc.endswith('clang'):
68+
toolchain_args['CMAKE_C_COMPILER_TARGET'] = target
69+
if self.toolchain.cxx.endswith('clang++'):
70+
@@ -466,10 +481,30 @@ class Product(object):
71+
platform, arch,
72+
macos_deployment_version=override_macos_deployment_version)
73+
self.cmake_options.define('CMAKE_TOOLCHAIN_FILE:PATH', toolchain_file)
74+
- elif platform == "linux":
75+
- toolchain_file = self.generate_linux_toolchain_file(platform, arch)
76+
+ elif platform == "linux" or platform == "android":
77+
+ # Always cross-compile for linux, but not on Android, as a native
78+
+ # compile on Android does not use the NDK and its CMake config.
79+
+ cross_compile = platform == "linux" or \
80+
+ self.is_cross_compile_target(host_target)
81+
+ toolchain_file = self.generate_linux_toolchain_file(platform, arch,
82+
+ cross_compile)
83+
self.cmake_options.define('CMAKE_TOOLCHAIN_FILE:PATH', toolchain_file)
4284

43-
+ if host_target.startswith('android') and self.is_cross_compile_target(host_target):
44-
+ host_config = HostSpecificConfiguration(host_target, self.args)
45-
+ self.cmake_options.extend(host_config.cmake_options)
46-
+ triple = '%s-unknown-linux-android%s' % (self.args.android_arch,
47-
+ self.args.android_api_level)
48-
+ flags = '-target %s ' % (triple)
85+
+ if cross_compile and platform == "android":
86+
+ resource_dir = None
87+
+ # build-script-impl products build before the install and use
88+
+ # the Swift stdlib from the compiler build directory instead,
89+
+ # while products built even before that currently do not support
90+
+ # cross-compiling Swift.
91+
+ if not self.is_before_build_script_impl_product() and \
92+
+ not self.is_build_script_impl_product():
93+
+ install_path = self.host_install_destdir(host_target) + \
94+
+ self.args.install_prefix
95+
+ resource_dir = '%s/lib/swift' % install_path
96+
+ flags = targets.StdlibDeploymentTarget.get_target_for_name(
97+
+ host_target).platform.swift_flags(self.args, resource_dir)
98+
+ self.cmake_options.define('CMAKE_Swift_FLAGS', flags)
4999
+
50-
+ flags += '-resource-dir %s/lib/swift ' % (
51-
+ self.host_install_destdir(host_target) + self.args.install_prefix)
100+
return toolchain_file
101+
102+
def get_openbsd_toolchain_file(self):
103+
diff --git a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py
104+
index 417056efdd0..177ea9f0623 100644
105+
--- a/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py
106+
+++ b/swift/utils/swift_build_support/swift_build_support/products/swift_testing.py
107+
@@ -127,3 +127,11 @@ class SwiftTestingCMakeShim(cmake_product.CMakeProduct):
108+
install_prefix = install_destdir + self.args.install_prefix
109+
110+
self.install_with_cmake(['install'], install_prefix)
52111
+
53-
+ ndk_path = StdlibDeploymentTarget.get_target_for_name(host_target).platform.ndk_toolchain_path(self.args)
54-
+ flags += '-sdk %s/sysroot ' % (ndk_path)
55-
+ flags += '-tools-directory %s/bin' % (ndk_path)
56-
+ self.cmake_options.define('CMAKE_Swift_FLAGS', flags)
57-
+ self.cmake_options.define('CMAKE_Swift_COMPILER_TARGET', triple)
58-
+ self.cmake_options.define('CMAKE_CXX_COMPILER_WORKS', 'True')
59-
+ self.cmake_options.define('CMAKE_SHARED_LINKER_FLAGS', '')
60-
+ self.cmake_options.define('CMAKE_FIND_ROOT_PATH', self.args.cross_compile_deps_path)
112+
+ @classmethod
113+
+ def is_build_script_impl_product(cls):
114+
+ return False
61115
+
62-
self.generate_toolchain_file_for_darwin_or_linux(
63-
host_target, override_macos_deployment_version=override_deployment_version)
64-
self.build_with_cmake([], self.args.build_variant, [],
116+
+ @classmethod
117+
+ def is_before_build_script_impl_product(cls):
118+
+ return False
119+
diff --git a/swift/utils/swift_build_support/swift_build_support/targets.py b/swift/utils/swift_build_support/swift_build_support/targets.py
120+
index fba09416ddb..67b81daba12 100644
121+
--- a/swift/utils/swift_build_support/swift_build_support/targets.py
122+
+++ b/swift/utils/swift_build_support/swift_build_support/targets.py
123+
@@ -72,7 +72,7 @@ class Platform(object):
124+
return True
125+
return False
126+
127+
- def swift_flags(self, args):
128+
+ def swift_flags(self, args, resource_path=None):
129+
"""
130+
Swift compiler flags for a platform, useful for cross-compiling
131+
"""
132+
@@ -154,12 +154,15 @@ class AndroidPlatform(Platform):
133+
"""
134+
return True
135+
136+
- def swift_flags(self, args):
137+
+ def swift_flags(self, args, resource_path=None):
138+
flags = '-target %s-unknown-linux-android%s ' % (args.android_arch,
139+
args.android_api_level)
140+
141+
- flags += '-resource-dir %s/swift-%s-%s/lib/swift ' % (
142+
- args.build_root, self.name, args.android_arch)
143+
+ if resource_path is not None:
144+
+ flags += '-resource-dir %s ' % (resource_path)
145+
+ else:
146+
+ flags += '-resource-dir %s/swift-%s-%s/lib/swift ' % (
147+
+ args.build_root, self.name, args.android_arch)
148+
149+
android_toolchain_path = self.ndk_toolchain_path(args)
150+

0 commit comments

Comments
 (0)