Skip to content

Commit a4ff4db

Browse files
committed
[build] Add the flags to enable cross-compiling the corelibs
Pass the Swift and CMake flags needed to cross-compile Foundation and so on, with the first example of Android. Add a new flag, --cross-compile-deps-path, which is used to search for cross-compiled libraries, like libcurl, that the corelibs depend on. Also add a new flag, --common-swift-flags, to pass additional Swift flags to the corelibs.
1 parent 89418c6 commit a4ff4db

File tree

6 files changed

+120
-6
lines changed

6 files changed

+120
-6
lines changed

CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,9 @@ endif()
480480

481481
set(SWIFT_BUILD_HOST_DISPATCH FALSE)
482482
if(SWIFT_ENABLE_DISPATCH AND NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
483-
if(SWIFT_BUILD_SYNTAXPARSERLIB OR SWIFT_BUILD_SOURCEKIT)
483+
# Only build libdispatch for the host if the host tools are being built and
484+
# specifically if these two libraries that depend on it are built.
485+
if(SWIFT_INCLUDE_TOOLS AND (SWIFT_BUILD_SYNTAXPARSERLIB OR SWIFT_BUILD_SOURCEKIT))
484486
set(SWIFT_BUILD_HOST_DISPATCH TRUE)
485487
endif()
486488

utils/build-script

+3
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,7 @@ class BuildScriptInvocation(object):
841841
"""
842842

843843
args = self.args
844+
args.build_root = self.workspace.build_root
844845

845846
options = {}
846847
for host_target in [args.host_target] + args.cross_compile_hosts:
@@ -862,6 +863,8 @@ class BuildScriptInvocation(object):
862863
config.swift_benchmark_run_targets),
863864
"SWIFT_TEST_TARGETS": " ".join(
864865
config.swift_test_run_targets),
866+
"SWIFT_FLAGS": config.swift_flags,
867+
"SWIFT_TARGET_CMAKE_OPTIONS": config.cmake_options,
865868
}
866869

867870
return options

utils/build-script-impl

+60-5
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ KNOWN_SETTINGS=(
139139
common-cmake-options "" "CMake options used for all targets, including LLVM/Clang"
140140
extra-cmake-options "" "Extra options to pass to CMake for all targets"
141141
ninja-cmake-options "" "CMake options used for all ninja targets"
142-
ninja-cmake-options "" "CMake options used for all ninja targets"
143142

144143
## Build ...
145144
build-llvm "1" "set to 1 to build LLVM and Clang"
@@ -205,6 +204,7 @@ KNOWN_SETTINGS=(
205204
swift-stdlib-os-versioning "1" "whether to build stdlib with availability based on OS versions (Darwin only)"
206205
swift-stdlib-stable-abi "" "should stdlib be built with stable ABI, if not set defaults to true on Darwin, false otherwise"
207206
swift-disable-dead-stripping "0" "turns off Darwin-specific dead stripping for Swift host tools"
207+
common-swift-flags "" "Flags used for Swift targets other than the stdlib, like the corelibs"
208208

209209
## FREESTANDING Stdlib Options
210210
swift-freestanding-sdk "" "which SDK to use when building the FREESTANDING stdlib"
@@ -229,6 +229,7 @@ KNOWN_SETTINGS=(
229229
cross-compile-hosts "" "space-separated list of targets to cross-compile host Swift tools for"
230230
cross-compile-with-host-tools "" "set to use the clang we build for the host to then build the cross-compile hosts"
231231
cross-compile-install-prefixes "" "semicolon-separated list of install prefixes to use for the cross-compiled hosts. The list expands, so if there are more cross-compile hosts than prefixes, unmatched hosts use the last prefix in the list"
232+
cross-compile-deps-path "" "path for CMake to look for cross-compiled library dependencies, such as libXML2"
232233
skip-merge-lipo-cross-compile-tools "" "set to skip running merge-lipo after installing cross-compiled host Swift tools"
233234
coverage-db "" "If set, coverage database to use when prioritizing testing"
234235
skip-local-host-install "" "If we are cross-compiling multiple targets, skip an install pass locally if the hosts match"
@@ -1249,6 +1250,8 @@ function calculate_targets_for_host() {
12491250
SWIFT_BENCHMARK_TARGETS=($(get_host_specific_variable ${host} SWIFT_BENCHMARK_TARGETS))
12501251
SWIFT_RUN_BENCHMARK_TARGETS=($(get_host_specific_variable ${host} SWIFT_RUN_BENCHMARK_TARGETS))
12511252
SWIFT_TEST_TARGETS=($(get_host_specific_variable ${host} SWIFT_TEST_TARGETS))
1253+
SWIFT_FLAGS=($(get_host_specific_variable ${host} SWIFT_FLAGS))
1254+
SWIFT_TARGET_CMAKE_OPTIONS=($(get_host_specific_variable ${host} SWIFT_TARGET_CMAKE_OPTIONS))
12521255
}
12531256

12541257

@@ -1390,6 +1393,14 @@ function swift_c_flags() {
13901393
fi
13911394
}
13921395

1396+
function common_swift_flags() {
1397+
if [ "${module_cache}" == "" ] ; then
1398+
echo "error: a module cache path has not been set"
1399+
exit 1
1400+
fi
1401+
echo -n "${SWIFT_FLAGS[@]} ${COMMON_SWIFT_FLAGS} -module-cache-path \"${module_cache}\" "
1402+
}
1403+
13931404
function cmake_config_opt() {
13941405
product=$1
13951406
if [[ "${CMAKE_GENERATOR}" == "Xcode" ]] ; then
@@ -1666,6 +1677,9 @@ for host in "${ALL_HOSTS[@]}"; do
16661677
-DCMAKE_BUILD_TYPE:STRING="${CMARK_BUILD_TYPE}"
16671678
"${cmark_cmake_options[@]}"
16681679
)
1680+
if [[ $(is_cross_tools_host ${host}) ]] ; then
1681+
cmake_options+=("${SWIFT_TARGET_CMAKE_OPTIONS[@]}")
1682+
fi
16691683
build_targets=(all)
16701684
;;
16711685

@@ -1793,6 +1807,7 @@ for host in "${ALL_HOSTS[@]}"; do
17931807
-DCLANG_TABLEGEN=$(build_directory "${LOCAL_HOST}" llvm)/bin/clang-tblgen
17941808
-DLLVM_NATIVE_BUILD=$(build_directory "${LOCAL_HOST}" llvm)
17951809
)
1810+
cmake_options+=("${SWIFT_TARGET_CMAKE_OPTIONS[@]}")
17961811
fi
17971812

17981813
;;
@@ -2205,7 +2220,7 @@ for host in "${ALL_HOSTS[@]}"; do
22052220
-DCMAKE_CXX_COMPILER:PATH="${CLANG_BIN}/clang++"
22062221
-DCMAKE_INSTALL_PREFIX:PATH="$(get_host_install_prefix ${host})"
22072222
-DCMAKE_Swift_COMPILER:PATH=${SWIFTC_BIN}
2208-
-DCMAKE_Swift_FLAGS:STRING="-module-cache-path \"${module_cache}\""
2223+
-DCMAKE_Swift_FLAGS:STRING="$(common_swift_flags)"
22092224

22102225
-DLLBUILD_ENABLE_ASSERTIONS:BOOL=$(true_false "${LLBUILD_ENABLE_ASSERTIONS}")
22112226
-DLLBUILD_SUPPORT_BINDINGS:=Swift
@@ -2221,6 +2236,22 @@ for host in "${ALL_HOSTS[@]}"; do
22212236
-DFoundation_DIR:PATH=$(build_directory ${host} foundation)/cmake/modules
22222237
)
22232238

2239+
if [[ $(is_cross_tools_host ${host}) ]] ; then
2240+
cmake_options+=("${SWIFT_TARGET_CMAKE_OPTIONS[@]}")
2241+
2242+
# llbuild looks for the SQlite3 library using find_package(),
2243+
# so search for it in CROSS_COMPILE_DEPS_PATH using the CMake
2244+
# process for doing so and don't use cross-compiled
2245+
# executables, see the linked CMake docs for more info:
2246+
#
2247+
# https://cmake.org/cmake/help/latest/command/find_package.html
2248+
# https://cmake.org/cmake/help/latest/command/find_program.html
2249+
cmake_options+=(
2250+
-DCMAKE_FIND_ROOT_PATH:PATH="${CROSS_COMPILE_DEPS_PATH}"
2251+
-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER
2252+
)
2253+
fi
2254+
22242255
# Ensure on Darwin platforms that we consider only the SQLite headers
22252256
# from the SDK instead of picking ones found elsewhere
22262257
# (e.g. in /usr/include )
@@ -2287,7 +2318,7 @@ for host in "${ALL_HOSTS[@]}"; do
22872318
-DCMAKE_C_COMPILER:PATH="${CLANG_BIN}/clang"
22882319
-DCMAKE_CXX_COMPILER:PATH="${CLANG_BIN}/clang++"
22892320
-DCMAKE_Swift_COMPILER:PATH=${SWIFTC_BIN}
2290-
-DCMAKE_Swift_FLAGS:STRING="-module-cache-path \"${module_cache}\""
2321+
-DCMAKE_Swift_FLAGS:STRING="$(common_swift_flags)"
22912322
-DCMAKE_INSTALL_PREFIX:PATH="$(get_host_install_prefix ${host})"
22922323
-DCMAKE_INSTALL_LIBDIR:PATH="lib"
22932324

@@ -2303,6 +2334,9 @@ for host in "${ALL_HOSTS[@]}"; do
23032334

23042335
-DENABLE_TESTING=YES
23052336
)
2337+
if [[ $(is_cross_tools_host ${host}) ]] ; then
2338+
cmake_options+=("${SWIFT_TARGET_CMAKE_OPTIONS[@]}")
2339+
fi
23062340
;;
23072341
esac
23082342

@@ -2356,7 +2390,7 @@ for host in "${ALL_HOSTS[@]}"; do
23562390
-DCMAKE_CXX_COMPILER:PATH=${CLANG_BIN}/clang++
23572391
-DCMAKE_SWIFT_COMPILER:PATH=${SWIFTC_BIN}
23582392
-DCMAKE_Swift_COMPILER:PATH=${SWIFTC_BIN}
2359-
-DCMAKE_Swift_FLAGS:STRING="-module-cache-path \"${module_cache}\""
2393+
-DCMAKE_Swift_FLAGS:STRING="$(common_swift_flags)"
23602394
-DCMAKE_INSTALL_PREFIX:PATH=$(get_host_install_prefix ${host})
23612395

23622396
${LIBICU_BUILD_ARGS[@]}
@@ -2372,6 +2406,24 @@ for host in "${ALL_HOSTS[@]}"; do
23722406
-DBUILD_SHARED_LIBS=$([[ ${product} == foundation_static ]] && echo "NO" || echo "YES")
23732407
)
23742408

2409+
if [[ $(is_cross_tools_host ${host}) ]] ; then
2410+
cmake_options+=("${SWIFT_TARGET_CMAKE_OPTIONS[@]}")
2411+
2412+
# Foundation looks for the ICU, libXML2 and libcurl libraries
2413+
# using find_package(), so search for them in
2414+
# CROSS_COMPILE_DEPS_PATH using the CMake process for doing
2415+
# so, see the linked CMake docs for more info:
2416+
#
2417+
# https://cmake.org/cmake/help/latest/command/find_package.html
2418+
cmake_options+=(
2419+
-DCMAKE_FIND_ROOT_PATH:PATH="${CROSS_COMPILE_DEPS_PATH}"
2420+
)
2421+
fi
2422+
if [[ "${host}" == "android-"* ]]; then
2423+
cmake_options+=(
2424+
-DCMAKE_HAVE_LIBC_PTHREAD=True
2425+
)
2426+
fi
23752427
;;
23762428
libdispatch|libdispatch_static)
23772429
LIBDISPATCH_BUILD_DIR=$(build_directory ${host} ${product})
@@ -2398,7 +2450,7 @@ for host in "${ALL_HOSTS[@]}"; do
23982450
-DCMAKE_CXX_COMPILER:PATH="${CLANG_BIN}/clang++"
23992451
-DCMAKE_SWIFT_COMPILER:PATH="${SWIFTC_BIN}"
24002452
-DCMAKE_Swift_COMPILER:PATH="${SWIFTC_BIN}"
2401-
-DCMAKE_Swift_FLAGS:STRING="-module-cache-path \"${module_cache}\""
2453+
-DCMAKE_Swift_FLAGS:STRING="$(common_swift_flags)"
24022454
-DCMAKE_INSTALL_PREFIX:PATH="$(get_host_install_prefix ${host})"
24032455
-DCMAKE_INSTALL_LIBDIR:PATH="lib"
24042456

@@ -2407,6 +2459,9 @@ for host in "${ALL_HOSTS[@]}"; do
24072459
-DENABLE_TESTING=YES
24082460
-DBUILD_SHARED_LIBS=$([[ ${product} == libdispatch_static ]] && echo "NO" || echo "YES")
24092461
)
2462+
if [[ $(is_cross_tools_host ${host}) ]] ; then
2463+
cmake_options+=("${SWIFT_TARGET_CMAKE_OPTIONS[@]}")
2464+
fi
24102465
;;
24112466
esac
24122467

utils/swift_build_support/swift_build_support/host_specific_configuration.py

+12
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ def __init__(self, host_target, args):
7272
self.swift_test_run_targets = []
7373
self.swift_benchmark_build_targets = []
7474
self.swift_benchmark_run_targets = []
75+
self.swift_flags = ''
76+
self.cmake_options = ''
7577
for deployment_target_name in stdlib_targets_to_configure:
7678
# Get the target object.
7779
deployment_target = StdlibDeploymentTarget.get_target_for_name(
@@ -203,6 +205,16 @@ def __init__(self, host_target, args):
203205
"check-swift{}-optimize_none_with_implicit_dynamic-{}"
204206
.format(subset_suffix, name))
205207

208+
# Only pull in these flags when cross-compiling with
209+
# --cross-compile-hosts.
210+
if deployment_target_name != args.host_target and \
211+
host_target != args.host_target:
212+
self.add_flags_for_cross_compilation(args, deployment_target)
213+
214+
def add_flags_for_cross_compilation(self, args, deployment_target):
215+
self.swift_flags = deployment_target.platform.swift_flags(args)
216+
self.cmake_options = deployment_target.platform.cmake_options(args)
217+
206218
def __platforms_to_skip_build(self, args):
207219
platforms_to_skip_build = set()
208220
if not args.build_linux:

utils/swift_build_support/swift_build_support/targets.py

+35
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ def contains(self, target_name):
6868
return True
6969
return False
7070

71+
def swift_flags(self, args):
72+
"""
73+
Swift compiler flags for a platform, useful for cross-compiling
74+
"""
75+
return ''
76+
77+
def cmake_options(self, args):
78+
"""
79+
CMake flags to build for a platform, useful for cross-compiling
80+
"""
81+
return ''
82+
7183

7284
class DarwinPlatform(Platform):
7385
def __init__(self, name, archs, sdk_name=None, is_simulator=False):
@@ -136,6 +148,29 @@ def uses_host_tests(self):
136148
"""
137149
return True
138150

151+
def swift_flags(self, args):
152+
flags = '-target %s-unknown-linux-android%s ' % (args.android_arch,
153+
args.android_api_level)
154+
155+
flags += '-resource-dir %s/swift-%s-%s/lib/swift ' % (
156+
args.build_root, self.name, args.android_arch)
157+
158+
android_toolchain_path = '%s/toolchains/llvm/prebuilt/%s' % (
159+
args.android_ndk, StdlibDeploymentTarget.host_target().name)
160+
161+
flags += '-sdk %s/sysroot ' % (android_toolchain_path)
162+
flags += '-tools-directory %s/bin' % (android_toolchain_path)
163+
return flags
164+
165+
def cmake_options(self, args):
166+
options = '-DCMAKE_SYSTEM_NAME=Android '
167+
options += '-DCMAKE_SYSTEM_VERSION=%s ' % (args.android_api_level)
168+
options += '-DCMAKE_SYSTEM_PROCESSOR=%s ' % (args.android_arch if not
169+
args.android_arch == 'armv7'
170+
else 'armv7-a')
171+
options += '-DCMAKE_ANDROID_NDK:PATH=%s' % (args.android_ndk)
172+
return options
173+
139174

140175
class Target(object):
141176
"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# REQUIRES: standalone_build
2+
3+
# RUN: %empty-directory(%t)
4+
# RUN: SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --cmake %cmake --libdispatch --cross-compile-hosts=android-aarch64 --skip-local-build --android --android-ndk %t/ndk/ --android-arch aarch64 --android-icu-uc %t/lib/libicuuc.so --android-icu-uc-include %t/include/ --android-icu-i18n %t/lib/libicui18n.so --android-icu-i18n-include %t/include/ --android-icu-data %t/lib/libicudata.so 2>&1 | %FileCheck %s
5+
6+
# CHECK: -DCMAKE_Swift_FLAGS{{.*}}-target {{.*}}unknown-linux-android{{.*}} -sdk
7+
# CHECK: -DCMAKE_SYSTEM_NAME=Android {{.*}} -DCMAKE_ANDROID_NDK

0 commit comments

Comments
 (0)