Skip to content

Commit e39b21f

Browse files
committed
[build-script-helper] Add support for Android cross-compilation
Add new flags '--cross-compile-host' and '--cross-compile-config' and use them to cross-compile, gated only for Android for now. Add a '--prefix' flag to install to a cross-compiled toolchain instead and set 'SWIFT_EXEC' when using SPM, so it uses the right Swift toolchain.
1 parent 9f7bfc0 commit e39b21f

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

Utilities/build-script-helper.py

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import argparse
66
import os
77
import platform
8+
import re
89
import shutil
910
import subprocess
1011
import sys
@@ -50,25 +51,28 @@ def get_swiftpm_options(args):
5051
os.path.join(args.toolchain, 'lib', 'swift', 'Block'),
5152
]
5253

53-
if 'ANDROID_DATA' in os.environ:
54-
swiftpm_args += [
55-
'-Xlinker', '-rpath', '-Xlinker', '$ORIGIN/../lib/swift/android',
56-
# SwiftPM will otherwise try to compile against GNU strerror_r on
57-
# Android and fail.
58-
'-Xswiftc', '-Xcc', '-Xswiftc', '-U_GNU_SOURCE',
59-
]
60-
else:
61-
# Library rpath for swift, dispatch, Foundation, etc. when installing
62-
swiftpm_args += [
63-
'-Xlinker', '-rpath', '-Xlinker', '$ORIGIN/../lib/swift/linux',
64-
]
54+
if 'ANDROID_DATA' in os.environ or (args.cross_compile_host and re.match(
55+
'android-', args.cross_compile_host)):
56+
swiftpm_args += [
57+
'-Xlinker', '-rpath', '-Xlinker', '$ORIGIN/../lib/swift/android',
58+
# SwiftPM will otherwise try to compile against GNU strerror_r on
59+
# Android and fail.
60+
'-Xswiftc', '-Xcc', '-Xswiftc', '-U_GNU_SOURCE',
61+
]
62+
elif platform.system() == 'Linux':
63+
# Library rpath for swift, dispatch, Foundation, etc. when installing
64+
swiftpm_args += [
65+
'-Xlinker', '-rpath', '-Xlinker', '$ORIGIN/../lib/swift/linux',
66+
]
67+
68+
if args.cross_compile_host:
69+
swiftpm_args += ['--destination', args.cross_compile_config]
6570

6671
return swiftpm_args
6772

68-
def install(swiftpm_bin_path, toolchain):
69-
toolchain_bin = os.path.join(toolchain, 'bin')
70-
for exe in ['sourcekit-lsp']:
71-
install_binary(exe, swiftpm_bin_path, toolchain_bin, toolchain)
73+
def install(swiftpm_bin_path, prefixes, toolchain):
74+
for prefix in prefixes:
75+
install_binary('sourcekit-lsp', swiftpm_bin_path, os.path.join(prefix, 'bin'), toolchain)
7276

7377
def install_binary(exe, source_dir, install_dir, toolchain):
7478
cmd = ['rsync', '-a', os.path.join(source_dir, exe), install_dir]
@@ -112,6 +116,8 @@ def handle_invocation(swift_exec, args):
112116
print('Cleaning ' + args.build_path)
113117
shutil.rmtree(args.build_path, ignore_errors=True)
114118

119+
env['SWIFT_EXEC'] = '%sc' % (swift_exec)
120+
115121
if args.action == 'build':
116122
swiftpm('build', swift_exec, swiftpm_args, env)
117123
elif args.action == 'test':
@@ -131,7 +137,7 @@ def handle_invocation(swift_exec, args):
131137
bin_path = swiftpm_bin_path(swift_exec, swiftpm_args, env)
132138
swiftpm_args += ['-Xswiftc', '-no-toolchain-stdlib-rpath']
133139
swiftpm('build', swift_exec, swiftpm_args, env)
134-
install(bin_path, args.toolchain)
140+
install(bin_path, args.install_prefixes if not None else [args.toolchain], args.toolchain)
135141
else:
136142
assert False, 'unknown action \'{}\''.format(args.action)
137143

@@ -148,6 +154,8 @@ def add_common_args(parser):
148154
parser.add_argument('--sanitize', action='append', help='build using the given sanitizer(s) (address|thread|undefined)')
149155
parser.add_argument('--sanitize-all', action='store_true', help='build using every available sanitizer in sub-directories of build path')
150156
parser.add_argument('--verbose', '-v', action='store_true', help='enable verbose output')
157+
parser.add_argument('--cross-compile-host', help='cross-compile for another host instead')
158+
parser.add_argument('--cross-compile-config', help='an SPM JSON destination file containing Swift cross-compilation flags')
151159

152160
subparsers = parser.add_subparsers(title='subcommands', dest='action', metavar='action')
153161
build_parser = subparsers.add_parser('build', help='build the package')
@@ -159,6 +167,7 @@ def add_common_args(parser):
159167

160168
install_parser = subparsers.add_parser('install', help='build the package')
161169
add_common_args(install_parser)
170+
install_parser.add_argument('--prefix', dest='install_prefixes', nargs='*', metavar='PATHS', help="paths to install sourcekit-lsp, default: 'toolchain/bin'")
162171

163172
args = parser.parse_args(sys.argv[1:])
164173

@@ -175,6 +184,11 @@ def add_common_args(parser):
175184
else:
176185
swift_exec = 'swift'
177186

187+
if args.cross_compile_host and re.match('android-', args.cross_compile_host):
188+
print('Cross-compiling for %s' % args.cross_compile_host)
189+
elif args.cross_compile_host:
190+
error("cannot cross-compile for %s" % args.cross_compile_host)
191+
178192
handle_invocation(swift_exec, args)
179193
if args.sanitize_all:
180194
base = args.build_path

0 commit comments

Comments
 (0)