Skip to content

Commit 067eb65

Browse files
committed
Android: add cross-compilation flags
In addition to '--cross-compile-hosts', add two new bootstrap flags, '--cross-compile-flags' and '--cross-compile-config', that will pass in a string with cross-compilation flags and a JSON file with the destination flags. Even though these two will be largely the same, both are needed because some PackageDescription libraries are not built by SPM itself, so the string is needed to build those with CMake.
1 parent ce50cb0 commit 067eb65

File tree

1 file changed

+62
-23
lines changed

1 file changed

+62
-23
lines changed

Utilities/bootstrap

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ def add_build_args(parser):
143143
dest="cross_compile_hosts",
144144
help="List of cross compile hosts targets.",
145145
default=[])
146+
parser.add_argument(
147+
"--cross-compile-flags",
148+
help="Swift flags to cross-compile the PackageDescription libraries with CMake")
149+
parser.add_argument(
150+
"--cross-compile-config",
151+
help="Swift flags to cross-compile SPM with itself")
146152

147153
def add_test_args(parser):
148154
"""Configures the parser with the arguments necessary for the test action."""
@@ -196,8 +202,14 @@ def parse_build_args(args):
196202
args.clang_path = get_clang_path(args)
197203
args.cmake_path = get_cmake_path(args)
198204
args.ninja_path = get_ninja_path(args)
199-
if args.cross_compile_hosts: # Use XCBuild target directory when building for multiple arches.
200-
args.target_dir = os.path.join(args.build_dir, "apple/Products")
205+
if args.cross_compile_hosts:
206+
if "macosx-arm64" in args.cross_compile_hosts:
207+
# Use XCBuild target directory when building for multiple arches.
208+
args.target_dir = os.path.join(args.build_dir, "apple/Products")
209+
elif re.match('android-', args.cross_compile_hosts):
210+
args.target_dir = os.path.join(
211+
args.build_dir,
212+
get_build_target(args,cross_compile=True))
201213
else:
202214
args.target_dir = os.path.join(args.build_dir, get_build_target(args))
203215
args.bootstrap_dir = os.path.join(args.target_dir, "bootstrap")
@@ -271,10 +283,18 @@ def get_ninja_path(args):
271283
else:
272284
return call_output(["which", "ninja"], verbose=args.verbose)
273285

274-
def get_build_target(args):
286+
def get_build_target(args, cross_compile=False):
275287
"""Returns the target-triple of the current machine."""
276288
try:
277-
target_info_json = subprocess.check_output([args.swiftc_path, '-print-target-info'], stderr=subprocess.PIPE, universal_newlines=True).strip()
289+
if cross_compile:
290+
target_info_json = subprocess.check_output(
291+
[args.swiftc_path, '-print-target-info'] +
292+
args.cross_compile_flags.split(),
293+
stderr=subprocess.PIPE, universal_newlines=True).strip()
294+
else:
295+
target_info_json = subprocess.check_output(
296+
[args.swiftc_path, '-print-target-info'],
297+
stderr=subprocess.PIPE, universal_newlines=True).strip()
278298
args.target_info = json.loads(target_info_json)
279299
return args.target_info["target"]["unversionedTriple"]
280300
except Exception as e:
@@ -309,8 +329,11 @@ def build(args):
309329
build_swift_argument_parser(args)
310330
build_swift_driver(args)
311331
build_swift_crypto(args)
332+
build_swiftpm_with_cmake(args)
333+
334+
if args.cross_compile_flags:
335+
build_packagedescription_libs_with_cmake(args)
312336

313-
build_swiftpm_with_cmake(args)
314337
build_swiftpm_with_swiftpm(args,integrated_swift_driver=False)
315338

316339
def test(args):
@@ -459,11 +482,15 @@ def install_binary(args, binary, dest_dir):
459482
# Build functions
460483
# -----------------------------------------------------------
461484

462-
def build_with_cmake(args, cmake_args, source_path, build_dir, targets=[]):
485+
def build_with_cmake(args, cmake_args, source_path, build_dir, targets=[], cross_compile=False):
463486
"""Runs CMake if needed, then builds with Ninja."""
464487
cache_path = os.path.join(build_dir, "CMakeCache.txt")
465488
if args.reconfigure or not os.path.isfile(cache_path) or not args.swiftc_path in open(cache_path).read():
466-
swift_flags = ""
489+
if cross_compile:
490+
swift_flags = args.cross_compile_flags
491+
else:
492+
swift_flags = ""
493+
467494
if args.sysroot:
468495
swift_flags = "-sdk %s" % args.sysroot
469496

@@ -593,30 +620,38 @@ def add_rpath_for_cmake_build(args, rpath):
593620
note(' '.join(add_rpath_cmd))
594621
subprocess.call(add_rpath_cmd, stderr=subprocess.PIPE)
595622

623+
def build_packagedescription_libs_with_cmake(args):
624+
"""Builds the PackageDescription libraries using CMake."""
625+
note("Building PackageDescription libraries (with CMake)")
626+
627+
cmake_flags = ["-DFIND_PM_DEPS:BOOL=NO"]
628+
targets = ["PD4", "PD4_2", "PackagePlugin"]
629+
if re.match('android-', args.cross_compile_hosts):
630+
cmake_flags.append("-DCMAKE_SYSTEM_NAME=Android")
631+
cmake_flags.append("-DCMAKE_SYSTEM_VERSION=1")
632+
633+
build_with_cmake(args, cmake_flags, args.project_root, args.bootstrap_dir,
634+
targets, cross_compile=True)
635+
596636
def build_swiftpm_with_cmake(args):
597637
"""Builds SwiftPM using CMake."""
598638
note("Building SwiftPM (with CMake)")
599639

600-
if args.bootstrap:
601-
cmake_flags = [
602-
get_llbuild_cmake_arg(args),
603-
"-DTSC_DIR=" + os.path.join(args.tsc_build_dir, "cmake/modules"),
604-
"-DYams_DIR=" + os.path.join(args.yams_build_dir, "cmake/modules"),
605-
"-DArgumentParser_DIR=" + os.path.join(args.swift_argument_parser_build_dir, "cmake/modules"),
606-
"-DSwiftDriver_DIR=" + os.path.join(args.swift_driver_build_dir, "cmake/modules"),
607-
"-DSwiftCrypto_DIR=" + os.path.join(args.swift_crypto_build_dir, "cmake/modules"),
608-
"-DFIND_PM_DEPS:BOOL=YES",
609-
]
610-
else:
611-
cmake_flags = [ "-DFIND_PM_DEPS:BOOL=NO" ]
640+
cmake_flags = [
641+
get_llbuild_cmake_arg(args),
642+
"-DTSC_DIR=" + os.path.join(args.tsc_build_dir, "cmake/modules"),
643+
"-DYams_DIR=" + os.path.join(args.yams_build_dir, "cmake/modules"),
644+
"-DArgumentParser_DIR=" + os.path.join(args.swift_argument_parser_build_dir, "cmake/modules"),
645+
"-DSwiftDriver_DIR=" + os.path.join(args.swift_driver_build_dir, "cmake/modules"),
646+
"-DSwiftCrypto_DIR=" + os.path.join(args.swift_crypto_build_dir, "cmake/modules"),
647+
"-DFIND_PM_DEPS:BOOL=YES",
648+
]
612649

613650
if platform.system() == 'Darwin':
614651
cmake_flags.append("-DCMAKE_C_FLAGS=-target %s%s" % (get_build_target(args), g_macos_deployment_target))
615652
cmake_flags.append("-DCMAKE_OSX_DEPLOYMENT_TARGET=%s" % g_macos_deployment_target)
616653

617-
targets = [] if args.bootstrap else ["PD4", "PD4_2"]
618-
619-
build_with_cmake(args, cmake_flags, args.project_root, args.bootstrap_dir, targets)
654+
build_with_cmake(args, cmake_flags, args.project_root, args.bootstrap_dir)
620655

621656
if args.llbuild_link_framework:
622657
add_rpath_for_cmake_build(args, args.llbuild_build_dir)
@@ -792,7 +827,9 @@ def get_swiftpm_flags(args):
792827
)
793828

794829
# Don't use GNU strerror_r on Android.
795-
if 'ANDROID_DATA' in os.environ:
830+
if 'ANDROID_DATA' in os.environ or
831+
(args.cross_compile_hosts and
832+
re.match('android-', args.cross_compile_hosts)):
796833
build_flags.extend(["-Xswiftc", "-Xcc", "-Xswiftc", "-U_GNU_SOURCE"])
797834

798835
# On ELF platforms, remove the host toolchain's stdlib absolute rpath from
@@ -804,6 +841,8 @@ def get_swiftpm_flags(args):
804841
cross_compile_hosts = args.cross_compile_hosts
805842
if build_target == 'x86_64-apple-macosx' and "macosx-arm64" in cross_compile_hosts:
806843
build_flags += ["--arch", "x86_64", "--arch", "arm64"]
844+
elif cross_compile_hosts and re.match('android-', cross_compile_hosts):
845+
build_flags.extend(["--destination", args.cross_compile_config])
807846
elif cross_compile_hosts:
808847
error("cannot cross-compile for %s" % cross_compile_hosts)
809848

0 commit comments

Comments
 (0)