7
7
import subprocess
8
8
import sys
9
9
import tempfile
10
-
10
+ import errno
11
+ import platform
11
12
12
13
PACKAGE_DIR = os .path .dirname (os .path .realpath (__file__ ))
13
14
WORKSPACE_DIR = os .path .realpath (PACKAGE_DIR + '/..' )
22
23
def printerr (message ):
23
24
print (message , file = sys .stderr )
24
25
26
+ def note (message ):
27
+ print ("--- %s: note: %s" % (os .path .basename (sys .argv [0 ]), message ))
28
+ sys .stdout .flush ()
25
29
26
30
def fatal_error (message ):
27
31
printerr (message )
@@ -129,6 +133,14 @@ def generate_gyb_files(verbose, add_source_locations):
129
133
130
134
## Building swiftSyntax
131
135
136
+ def get_installed_name ():
137
+ # we have to use this name in the installed dylib so that the compiler will
138
+ # treat it as a part of stdlib to copy the dylib to the framework dir.
139
+ return 'swiftSwiftSyntax'
140
+
141
+ def get_installed_dylib_name ():
142
+ return 'lib' + get_installed_name () + '.dylib'
143
+
132
144
def get_swiftpm_invocation (spm_exec , build_dir , release ):
133
145
if spm_exec == 'swift build' :
134
146
swiftpm_call = ['swift' , 'build' ]
@@ -143,6 +155,8 @@ def get_swiftpm_invocation(spm_exec, build_dir, release):
143
155
if build_dir :
144
156
swiftpm_call .extend (['--build-path' , build_dir ])
145
157
158
+ # Swift compiler needs to know the module link name.
159
+ swiftpm_call .extend (['-Xswiftc' , '-module-link-name' , '-Xswiftc' , get_installed_name ()])
146
160
return swiftpm_call
147
161
148
162
@@ -285,6 +299,48 @@ def run_xctests(swift_test_exec, build_dir, release, swiftc_exec, verbose):
285
299
286
300
return call (swiftpm_call , env = subenv , verbose = verbose ) == 0
287
301
302
+ def delete_rpath (rpath , binary ):
303
+ if platform .system () == 'Darwin' :
304
+ cmd = ["install_name_tool" , "-delete_rpath" , rpath , binary ]
305
+ note ("removing RPATH from %s: %s" % (binary , ' ' .join (cmd )))
306
+ result = subprocess .call (cmd )
307
+ if result != 0 :
308
+ fatal_error ("command failed with exit status %d" % (result ,))
309
+ else :
310
+ fatal_error ("unable to remove RPATHs on this platform" )
311
+
312
+ def change_id_rpath (rpath , binary ):
313
+ if platform .system () == 'Darwin' :
314
+ cmd = ["install_name_tool" , "-id" , rpath , binary ]
315
+ note ("changing id in %s: %s" % (binary , ' ' .join (cmd )))
316
+ result = subprocess .call (cmd )
317
+ if result != 0 :
318
+ fatal_error ("command failed with exit status %d" % (result ,))
319
+ else :
320
+ fatal_error ("unable to invoke install_name_tool on this platform" )
321
+
322
+ def check_and_sync (file_path , install_path ):
323
+ cmd = ["rsync" , "-a" , file_path , install_path ]
324
+ note ("installing %s: %s" % (os .path .basename (file_path ), ' ' .join (cmd )))
325
+ result = subprocess .check_call (cmd )
326
+ if result != 0 :
327
+ fatal_error ("install failed with exit status %d" % (result ,))
328
+
329
+ def install (build_dir , dylib_dir , swiftmodule_dir , stdlib_rpath ):
330
+ dylibPath = build_dir + '/libSwiftSyntax.dylib'
331
+ modulePath = build_dir + '/SwiftSyntax.swiftmodule'
332
+ docPath = build_dir + '/SwiftSyntax.swiftdoc'
333
+ # users should find the dylib as if it's a part of stdlib.
334
+ change_id_rpath ('@rpath/' + get_installed_dylib_name (), dylibPath )
335
+ # we don't wanna hard-code the stdlib dylibs into rpath.
336
+ delete_rpath (stdlib_rpath , dylibPath )
337
+ check_and_sync (file_path = dylibPath ,
338
+ install_path = dylib_dir + '/' + get_installed_dylib_name ())
339
+ # Optionally install .swiftmodule
340
+ if swiftmodule_dir :
341
+ check_and_sync (file_path = modulePath ,install_path = swiftmodule_dir )
342
+ check_and_sync (file_path = docPath ,install_path = swiftmodule_dir )
343
+ return
288
344
289
345
### Main
290
346
@@ -324,7 +380,18 @@ def main():
324
380
help = '''
325
381
Insert ###sourceLocation comments in generated code for line-directive.
326
382
''' )
327
-
383
+ basic_group .add_argument ('--install' , action = 'store_true' ,
384
+ help = '''
385
+ Install the build artifact to a specified toolchain directory.
386
+ ''' )
387
+ basic_group .add_argument ('--dylib-dir' ,
388
+ help = '''
389
+ The directory to where the .dylib should be installed.
390
+ ''' )
391
+ basic_group .add_argument ('--swiftmodule-dir' ,
392
+ help = '''
393
+ The directory to where the .swiftmodule should be installed.
394
+ ''' )
328
395
testing_group = parser .add_argument_group ('Testing' )
329
396
testing_group .add_argument ('-t' , '--test' , action = 'store_true' ,
330
397
help = 'Run tests' )
@@ -355,6 +422,21 @@ def main():
355
422
356
423
args = parser .parse_args (sys .argv [1 :])
357
424
425
+ if args .install :
426
+ if not args .dylib_dir :
427
+ fatal_error ('Must specify directory to install' )
428
+ if not args .build_dir :
429
+ fatal_error ('Must specify build directory to copy from' )
430
+ if args .release :
431
+ build_dir = args .build_dir + '/release'
432
+ else :
433
+ # will this ever happen?
434
+ build_dir = args .build_dir + '/debug'
435
+ stdlib_rpath = realpath (os .path .dirname (args .swiftc_exec ) + '/../lib/swift/macosx/' )
436
+ install (build_dir = build_dir , dylib_dir = args .dylib_dir ,
437
+ swiftmodule_dir = args .swiftmodule_dir ,
438
+ stdlib_rpath = stdlib_rpath )
439
+ sys .exit (0 )
358
440
359
441
try :
360
442
generate_gyb_files (verbose = args .verbose ,
0 commit comments