Skip to content

Commit 72a027a

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 de60ad2 commit 72a027a

File tree

1 file changed

+54
-23
lines changed

1 file changed

+54
-23
lines changed

Utilities/bootstrap

Lines changed: 54 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,12 @@ 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(args.build_dir, get_build_target(args,cross_compile=True))
201211
else:
202212
args.target_dir = os.path.join(args.build_dir, get_build_target(args))
203213
args.bootstrap_dir = os.path.join(args.target_dir, "bootstrap")
@@ -271,10 +281,13 @@ def get_ninja_path(args):
271281
else:
272282
return call_output(["which", "ninja"], verbose=args.verbose)
273283

274-
def get_build_target(args):
284+
def get_build_target(args, cross_compile=False):
275285
"""Returns the target-triple of the current machine."""
276286
try:
277-
target_info_json = subprocess.check_output([args.swiftc_path, '-print-target-info'], stderr=subprocess.PIPE, universal_newlines=True).strip()
287+
if cross_compile:
288+
target_info_json = subprocess.check_output([args.swiftc_path, '-print-target-info'] + args.cross_compile_flags.split(), stderr=subprocess.PIPE, universal_newlines=True).strip()
289+
else:
290+
target_info_json = subprocess.check_output([args.swiftc_path, '-print-target-info'], stderr=subprocess.PIPE, universal_newlines=True).strip()
278291
args.target_info = json.loads(target_info_json)
279292
return args.target_info["target"]["unversionedTriple"]
280293
except Exception as e:
@@ -309,8 +322,11 @@ def build(args):
309322
build_swift_argument_parser(args)
310323
build_swift_driver(args)
311324
build_swift_crypto(args)
325+
build_swiftpm_with_cmake(args)
326+
327+
if args.cross_compile_flags:
328+
build_packagedescription_libs_with_cmake(args)
312329

313-
build_swiftpm_with_cmake(args)
314330
build_swiftpm_with_swiftpm(args,integrated_swift_driver=False)
315331

316332
def test(args):
@@ -459,11 +475,15 @@ def install_binary(args, binary, dest_dir):
459475
# Build functions
460476
# -----------------------------------------------------------
461477

462-
def build_with_cmake(args, cmake_args, source_path, build_dir, targets=[]):
478+
def build_with_cmake(args, cmake_args, source_path, build_dir, targets=[], cross_compile=False):
463479
"""Runs CMake if needed, then builds with Ninja."""
464480
cache_path = os.path.join(build_dir, "CMakeCache.txt")
465481
if args.reconfigure or not os.path.isfile(cache_path) or not args.swiftc_path in open(cache_path).read():
466-
swift_flags = ""
482+
if cross_compile:
483+
swift_flags = args.cross_compile_flags
484+
else:
485+
swift_flags = ""
486+
467487
if args.sysroot:
468488
swift_flags = "-sdk %s" % args.sysroot
469489

@@ -593,30 +613,38 @@ def add_rpath_for_cmake_build(args, rpath):
593613
note(' '.join(add_rpath_cmd))
594614
subprocess.call(add_rpath_cmd, stderr=subprocess.PIPE)
595615

616+
def build_packagedescription_libs_with_cmake(args):
617+
"""Builds the PackageDescription libraries using CMake."""
618+
note("Building PackageDescription libraries (with CMake)")
619+
620+
cmake_flags = ["-DFIND_PM_DEPS:BOOL=NO"]
621+
targets = ["PD4", "PD4_2", "PackagePlugin"]
622+
if re.match('android-', args.cross_compile_hosts):
623+
cmake_flags.append("-DCMAKE_SYSTEM_NAME=Android")
624+
cmake_flags.append("-DCMAKE_SYSTEM_VERSION=1")
625+
626+
build_with_cmake(args, cmake_flags, args.project_root, args.bootstrap_dir,
627+
targets, cross_compile=True)
628+
596629
def build_swiftpm_with_cmake(args):
597630
"""Builds SwiftPM using CMake."""
598631
note("Building SwiftPM (with CMake)")
599632

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" ]
633+
cmake_flags = [
634+
get_llbuild_cmake_arg(args),
635+
"-DTSC_DIR=" + os.path.join(args.tsc_build_dir, "cmake/modules"),
636+
"-DYams_DIR=" + os.path.join(args.yams_build_dir, "cmake/modules"),
637+
"-DArgumentParser_DIR=" + os.path.join(args.swift_argument_parser_build_dir, "cmake/modules"),
638+
"-DSwiftDriver_DIR=" + os.path.join(args.swift_driver_build_dir, "cmake/modules"),
639+
"-DSwiftCrypto_DIR=" + os.path.join(args.swift_crypto_build_dir, "cmake/modules"),
640+
"-DFIND_PM_DEPS:BOOL=YES",
641+
]
612642

613643
if platform.system() == 'Darwin':
614644
cmake_flags.append("-DCMAKE_C_FLAGS=-target %s%s" % (get_build_target(args), g_macos_deployment_target))
615645
cmake_flags.append("-DCMAKE_OSX_DEPLOYMENT_TARGET=%s" % g_macos_deployment_target)
616646

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

621649
if args.llbuild_link_framework:
622650
add_rpath_for_cmake_build(args, args.llbuild_build_dir)
@@ -792,7 +820,8 @@ def get_swiftpm_flags(args):
792820
)
793821

794822
# Don't use GNU strerror_r on Android.
795-
if 'ANDROID_DATA' in os.environ:
823+
if 'ANDROID_DATA' in os.environ or re.match(
824+
'android-', args.cross_compile_hosts):
796825
build_flags.extend(["-Xswiftc", "-Xcc", "-Xswiftc", "-U_GNU_SOURCE"])
797826

798827
# On ELF platforms, remove the host toolchain's stdlib absolute rpath from
@@ -804,6 +833,8 @@ def get_swiftpm_flags(args):
804833
cross_compile_hosts = args.cross_compile_hosts
805834
if build_target == 'x86_64-apple-macosx' and "macosx-arm64" in cross_compile_hosts:
806835
build_flags += ["--arch", "x86_64", "--arch", "arm64"]
836+
elif cross_compile_hosts and re.match('android-', cross_compile_hosts):
837+
build_flags.extend(["--destination", args.cross_compile_config])
807838
elif cross_compile_hosts:
808839
error("cannot cross-compile for %s" % cross_compile_hosts)
809840

0 commit comments

Comments
 (0)