55import argparse
66import os
77import platform
8+ import re
89import shutil
910import subprocess
1011import 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
7377def 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,10 @@ 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+
141+ if not args .install_prefixes :
142+ args .install_prefixes = [args .toolchain ]
143+ install (bin_path , args .install_prefixes , args .toolchain )
135144 else :
136145 assert False , 'unknown action \' {}\' ' .format (args .action )
137146
@@ -148,6 +157,8 @@ def add_common_args(parser):
148157 parser .add_argument ('--sanitize' , action = 'append' , help = 'build using the given sanitizer(s) (address|thread|undefined)' )
149158 parser .add_argument ('--sanitize-all' , action = 'store_true' , help = 'build using every available sanitizer in sub-directories of build path' )
150159 parser .add_argument ('--verbose' , '-v' , action = 'store_true' , help = 'enable verbose output' )
160+ parser .add_argument ('--cross-compile-host' , help = 'cross-compile for another host instead' )
161+ parser .add_argument ('--cross-compile-config' , help = 'an SPM JSON destination file containing Swift cross-compilation flags' )
151162
152163 subparsers = parser .add_subparsers (title = 'subcommands' , dest = 'action' , metavar = 'action' )
153164 build_parser = subparsers .add_parser ('build' , help = 'build the package' )
@@ -159,6 +170,7 @@ def add_common_args(parser):
159170
160171 install_parser = subparsers .add_parser ('install' , help = 'build the package' )
161172 add_common_args (install_parser )
173+ install_parser .add_argument ('--prefix' , dest = 'install_prefixes' , nargs = '*' , metavar = 'PATHS' , help = "paths to install sourcekit-lsp, default: 'toolchain/bin'" )
162174
163175 args = parser .parse_args (sys .argv [1 :])
164176
@@ -175,6 +187,11 @@ def add_common_args(parser):
175187 else :
176188 swift_exec = 'swift'
177189
190+ if args .cross_compile_host and re .match ('android-' , args .cross_compile_host ):
191+ print ('Cross-compiling for %s' % args .cross_compile_host )
192+ elif args .cross_compile_host :
193+ error ("cannot cross-compile for %s" % args .cross_compile_host )
194+
178195 handle_invocation (swift_exec , args )
179196 if args .sanitize_all :
180197 base = args .build_path
0 commit comments