1
- #!/usr/bin/env python
1
+ #!/usr/bin/env python3
2
2
3
3
"""
4
4
This source file is part of the Swift.org open source project
@@ -31,14 +31,14 @@ def parse_args(args):
31
31
32
32
parser .add_argument ('--package-path' , default = '' )
33
33
parser .add_argument ('-v' , '--verbose' , action = 'store_true' , help = 'log executed commands' )
34
- parser .add_argument ('--prefix' , help = 'install path' )
34
+ parser .add_argument ('--prefix' , dest = 'install_prefixes' , nargs = '*' , metavar = 'PATHS' , help = 'install path' )
35
35
parser .add_argument ('--configuration' , default = 'debug' )
36
36
parser .add_argument ('--build-path' , default = None )
37
37
parser .add_argument ('--multiroot-data-file' , help = 'Path to an Xcode workspace to create a unified build of SwiftSyntax with other projects.' )
38
38
parser .add_argument ('--toolchain' , required = True , help = 'the toolchain to use when building this package' )
39
39
parser .add_argument ('--update' , action = 'store_true' , help = 'update all SwiftPM dependencies' )
40
40
parser .add_argument ('--no-local-deps' , action = 'store_true' , help = 'use normal remote dependencies when building' )
41
- parser .add_argument ('build_actions' , help = "Extra actions to perform. Can be any number of the following" , choices = ['all' , 'build' , 'test' , 'generate-xcodeproj' ], nargs = "*" , default = ['build' ])
41
+ parser .add_argument ('build_actions' , help = "Extra actions to perform. Can be any number of the following" , choices = ['all' , 'build' , 'test' , 'generate-xcodeproj' , 'install' ], nargs = "*" , default = ['build' ])
42
42
43
43
parsed = parser .parse_args (args )
44
44
@@ -57,11 +57,9 @@ def parse_args(args):
57
57
def run (args ):
58
58
package_name = os .path .basename (args .package_path )
59
59
60
- env = dict ( os . environ )
60
+ env = get_swiftpm_environment_variables ( no_local_deps = args . no_local_deps )
61
61
# Use local dependencies (i.e. checked out next swift-format).
62
- if not args .no_local_deps :
63
- env ['SWIFTCI_USE_LOCAL_DEPS' ] = "1"
64
-
62
+
65
63
if args .update :
66
64
print ("** Updating dependencies of %s **" % package_name )
67
65
try :
@@ -76,7 +74,7 @@ def run(args):
76
74
sys .exit (1 )
77
75
78
76
# The test action creates its own build. No need to build if we are just testing.
79
- if should_run_action ('build' , args .build_actions ):
77
+ if should_run_action ('build' , args .build_actions ) or should_run_action ( 'install' , args . build_actions ) :
80
78
print ("** Building %s **" % package_name )
81
79
try :
82
80
invoke_swift (package_path = args .package_path ,
@@ -124,6 +122,23 @@ def run(args):
124
122
printerr ('Executing: %s' % ' ' .join (e .cmd ))
125
123
sys .exit (1 )
126
124
125
+ if should_run_action ("install" , args .build_actions ):
126
+ print ("** Installing %s **" % package_name )
127
+
128
+ swiftpm_args = get_swiftpm_options (
129
+ package_path = args .package_path ,
130
+ build_path = args .build_path ,
131
+ multiroot_data_file = args .multiroot_data_file ,
132
+ configuration = args .configuration ,
133
+ verbose = args .verbose
134
+ )
135
+ cmd = [args .swift_exec , 'build' , '--show-bin-path' ] + swiftpm_args
136
+ bin_path = check_output (cmd , env = env , caputre_stderr = False , verbose = args .verbose ).strip ()
137
+
138
+ for prefix in args .install_prefixes :
139
+ cmd = ['rsync' , '-a' , os .path .join (bin_path , 'swift-format' ), os .path .join (prefix , 'bin' )]
140
+ check_call (cmd , verbose = args .verbose )
141
+
127
142
def should_run_action (action_name , selected_actions ):
128
143
if action_name in selected_actions :
129
144
return True
@@ -142,20 +157,41 @@ def invoke_swift(package_path, swift_exec, action, products, build_path, multiro
142
157
for product in products :
143
158
invoke_swift_single_product (package_path , swift_exec , action , product , build_path , multiroot_data_file , configuration , env , verbose )
144
159
145
- def invoke_swift_single_product (package_path , swift_exec , action , product , build_path , multiroot_data_file , configuration , env , verbose ):
146
- args = [swift_exec , action , '--package-path' , package_path , '-c' , configuration , '--build-path' , build_path ]
147
- if platform .system () != "Darwin" :
148
- args .extend (["--enable-test-discovery" ])
160
+ def get_swiftpm_options (package_path , build_path , multiroot_data_file , configuration , verbose ):
161
+ args = [
162
+ '--package-path' , package_path ,
163
+ '--configuration' , configuration ,
164
+ '--scratch-path' , build_path
165
+ ]
149
166
if multiroot_data_file :
150
- args .extend (['--multiroot-data-file' , multiroot_data_file ])
151
- if action == 'test' :
152
- args .extend (['--test-product' , product ])
153
- else :
154
- args .extend (['--product' , product ])
155
-
167
+ args += ['--multiroot-data-file' , multiroot_data_file ]
168
+ if verbose :
169
+ args += ['--verbose' ]
170
+ if platform .system () == 'Darwin' :
171
+ args += [
172
+ '-Xlinker' , '-rpath' , '-Xlinker' , '/usr/lib/swift' ,
173
+ '-Xlinker' , '-rpath' , '-Xlinker' , '@executable_path/../lib/swift/macosx' ,
174
+ '-Xlinker' , '-rpath' , '-Xlinker' , '@executable_path/../lib/swift-5.5/macosx' ,
175
+ ]
176
+ return args
177
+
178
+ def get_swiftpm_environment_variables (no_local_deps ):
156
179
# Tell SwiftSyntax that we are building in a build-script environment so that
157
180
# it does not need to be rebuilt if it has already been built before.
181
+ env = dict (os .environ )
158
182
env ['SWIFT_BUILD_SCRIPT_ENVIRONMENT' ] = '1'
183
+ if not no_local_deps :
184
+ env ['SWIFTCI_USE_LOCAL_DEPS' ] = "1"
185
+ return env
186
+
187
+
188
+ def invoke_swift_single_product (package_path , swift_exec , action , product , build_path , multiroot_data_file , configuration , env , verbose ):
189
+ args = [swift_exec , action ]
190
+ args += get_swiftpm_options (package_path , build_path , multiroot_data_file , configuration , verbose )
191
+ if action == 'test' :
192
+ args += ['--test-product' , product ]
193
+ else :
194
+ args += ['--product' , product ]
159
195
160
196
check_call (args , env = env , verbose = verbose )
161
197
@@ -170,6 +206,15 @@ def check_call(cmd, verbose, env=os.environ, **kwargs):
170
206
print (' ' .join ([escape_cmd_arg (arg ) for arg in cmd ]))
171
207
return subprocess .check_call (cmd , env = env , stderr = subprocess .STDOUT , ** kwargs )
172
208
209
+ def check_output (cmd , verbose , env = os .environ , caputre_stderr = True , ** kwargs ):
210
+ if verbose :
211
+ print (' ' .join ([escape_cmd_arg (arg ) for arg in cmd ]))
212
+ if caputre_stderr :
213
+ stderr = subprocess .STDOUT
214
+ else :
215
+ stderr = subprocess .DEVNULL
216
+ return subprocess .check_output (cmd , env = env , stderr = stderr , encoding = 'utf-8' , ** kwargs )
217
+
173
218
def escape_cmd_arg (arg ):
174
219
if '"' in arg or ' ' in arg :
175
220
return '"%s"' % arg .replace ('"' , '\\ "' )
0 commit comments