@@ -17,13 +17,31 @@ from __future__ import print_function
17
17
18
18
import argparse
19
19
import json
20
+ import logging
20
21
import os
22
+ import pathlib
21
23
import platform
22
24
import re
23
25
import shutil
24
26
import subprocess
25
- from helpers import note , error , symlink_force , mkdir_p , call , call_output , log_timestamp
26
-
27
+ import sys
28
+ from helpers import symlink_force , mkdir_p , call , call_output
29
+
30
+
31
+ logging .basicConfig (
32
+ stream = sys .stdout ,
33
+ format = " | " .join ([
34
+ f"--- { pathlib .Path (sys .argv [0 ]).name } " , # Prefix script name to the log in an attempt to avoid confusion when parsing logs
35
+ "%(asctime)s" ,
36
+ "%(levelname)-7s" ,
37
+ "%(threadName)s" ,
38
+ "%(module)s" ,
39
+ "%(funcName)s" ,
40
+ "Line:%(lineno)d" ,
41
+ "%(message)s" ,
42
+ ]),
43
+ level = logging .INFO ,
44
+ )
27
45
g_macos_deployment_target = '12.0'
28
46
29
47
g_shared_lib_prefix = "lib"
@@ -32,6 +50,12 @@ if platform.system() == 'Darwin':
32
50
else :
33
51
g_shared_lib_suffix = ".so"
34
52
53
+ class BinaryNotFound (BaseException ):
54
+
55
+ def __init__ (self , * , tool : str , path : pathlib .Path ):
56
+ super ().__init__ ("Unable to find {tool} source directory at {path}" )
57
+
58
+
35
59
def main ():
36
60
parser = argparse .ArgumentParser (description = """
37
61
This script will build a bootstrapped copy of the Swift Package Manager, and optionally perform extra
@@ -60,7 +84,10 @@ def main():
60
84
parser_install .set_defaults (func = install )
61
85
add_build_args (parser_install )
62
86
87
+ logging .info ("sys.argv: %r" , sys .argv )
63
88
args = parser .parse_args ()
89
+ # update the root logger level based on the verbose flag
90
+ logging .getLogger ().setLevel (logging .DEBUG if args .verbose else logging .INFO )
64
91
args .func = args .func or build
65
92
args .func (args )
66
93
@@ -159,6 +186,13 @@ def add_build_args(parser):
159
186
parser .add_argument (
160
187
"--cross-compile-config" ,
161
188
help = "Swift flags to cross-compile SwiftPM with itself" )
189
+ parser .add_argument (
190
+ "--no-local-deps" ,
191
+ default = True ,
192
+ action = "store_false" ,
193
+ dest = "use_local_deps" ,
194
+ help = "When set, do not use local dependencies"
195
+ )
162
196
163
197
def add_test_args (parser ):
164
198
"""Configures the parser with the arguments necessary for the test action."""
@@ -253,36 +287,47 @@ def parse_test_args(args):
253
287
254
288
def get_swiftc_path (args ):
255
289
"""Returns the path to the Swift compiler."""
290
+ logging .debug ("Getting path to swiftc..." )
256
291
if args .swiftc_path :
257
292
swiftc_path = os .path .abspath (args .swiftc_path )
293
+ logging .debug ("path provided via command line argument. swiftc_path is %r" , swiftc_path )
258
294
elif os .getenv ("SWIFT_EXEC" ):
259
- swiftc_path = os .path .realpath (os .getenv ("SWIFT_EXEC" ))
295
+ swiftc_path = os .getenv ("SWIFT_EXEC" )
296
+ logging .debug ("SWIFT_EXEC env set. swiftc_path set to %r" , swiftc_path )
260
297
elif platform .system () == 'Darwin' :
298
+ logging .debug ("we are on darwin, so calling `xcrun --find swiftc`" )
261
299
swiftc_path = call_output (
262
300
["xcrun" , "--find" , "swiftc" ],
263
301
stderr = subprocess .PIPE ,
264
- verbose = args .verbose
302
+ verbose = args .verbose ,
265
303
)
304
+ logging .debug ("swiftc_path is set to %r" , swiftc_path )
266
305
else :
267
306
swiftc_path = call_output (["which" , "swiftc" ], verbose = args .verbose )
307
+ logging .debug ("calling 'which swiftc'. path is %r" , swiftc_path )
268
308
269
309
if os .path .basename (swiftc_path ) == 'swift' :
270
310
swiftc_path = swiftc_path + 'c'
311
+ logging .debug ("appending to path, it is now %r" , swiftc_path )
271
312
313
+ logging .debug ("swiftc_path set to %r" , swiftc_path )
272
314
if os .path .exists (swiftc_path ):
315
+ logging .debug ("swiftc_path exists.. returning..." )
273
316
return swiftc_path
274
- error ("unable to find swiftc at %s" % swiftc_path )
317
+ logging .error ("unable to find swiftc at %s" , swiftc_path )
318
+ raise BinaryNotFound (tool = "swiftc" , path = swiftc_path )
275
319
276
320
def get_tool_path (args , tool ):
277
321
"""Returns the path to the specified tool."""
322
+ logging .debug ("Searching for %s tool" , tool )
278
323
path = getattr (args , tool + "_path" , None )
279
324
if path is not None :
280
325
return os .path .abspath (path )
281
326
elif platform .system () == 'Darwin' :
282
327
return call_output (
283
328
["xcrun" , "--find" , tool ],
284
329
stderr = subprocess .PIPE ,
285
- verbose = args .verbose
330
+ verbose = args .verbose ,
286
331
)
287
332
else :
288
333
return call_output (["which" , tool ], verbose = args .verbose )
@@ -294,26 +339,30 @@ def get_build_target(args, cross_compile=False):
294
339
if cross_compile :
295
340
cross_compile_json = json .load (open (args .cross_compile_config ))
296
341
command += ['-target' , cross_compile_json ["target" ]]
342
+ logging .debug ("Running command >>> %r" , command )
297
343
target_info_json = subprocess .check_output (command ,
298
- stderr = subprocess .PIPE , universal_newlines = True ).strip ()
344
+ stderr = subprocess .PIPE , universal_newlines = True , env = os .environ ).strip ()
345
+ logging .debug ("Command returned: %r" , target_info_json )
299
346
args .target_info = json .loads (target_info_json )
300
- if platform .system () == 'Darwin' :
301
- return args .target_info ["target" ]["unversionedTriple" ]
302
- return args .target_info ["target" ]["triple" ]
303
- except Exception as e :
347
+ return args .target_info ["target" ]["unversionedTriple" if platform .system () == 'Darwin' else "triple" ]
348
+ except subprocess .CalledProcessError as cpe :
349
+ logging .debug ("Command failed..." )
304
350
# Temporary fallback for Darwin.
305
351
if platform .system () == 'Darwin' :
306
- return 'x86_64-apple-macosx'
352
+ macOS_default = 'x86_64-apple-macosx'
353
+ logging .debug ("we are on Darwin. defaulting to %r" , macOS_default )
354
+ return macOS_default
307
355
else :
308
- error (str (e ))
356
+ logging .error ("get build targets: %s" , str (cpe ))
357
+ raise cpe
309
358
310
359
# -----------------------------------------------------------
311
360
# Actions
312
361
# -----------------------------------------------------------
313
362
314
363
def clean (args ):
315
364
"""Cleans the build artifacts."""
316
- note ("Cleaning" )
365
+ logging . info ("Cleaning" )
317
366
parse_global_args (args )
318
367
319
368
call (["rm" , "-rf" , args .build_dir ], verbose = args .verbose )
@@ -323,6 +372,7 @@ def build(args):
323
372
parse_build_args (args )
324
373
325
374
if args .bootstrap :
375
+ logging .info ("Building bootstrap" )
326
376
# Build llbuild if its build path is not passed in.
327
377
if not "llbuild" in args .build_dirs :
328
378
build_llbuild (args )
@@ -359,7 +409,7 @@ def test(args):
359
409
"""Builds SwiftPM, then tests itself."""
360
410
build (args )
361
411
362
- note ("Testing" )
412
+ logging . info ("Testing" )
363
413
parse_test_args (args )
364
414
cmd = [
365
415
os .path .join (args .bin_dir , "swift-test" )
@@ -376,7 +426,7 @@ def test(args):
376
426
return
377
427
378
428
# Build SwiftPM with the integrated driver.
379
- note ("Bootstrap with the integrated Swift driver" )
429
+ logging . info ("Bootstrap with the integrated Swift driver" )
380
430
build_swiftpm_with_swiftpm (args ,integrated_swift_driver = True )
381
431
382
432
# Test SwiftPM with the integrated driver. Only the build and
@@ -439,7 +489,7 @@ def install_swiftpm(prefix, args):
439
489
for tool in ["swift-build" , "swift-test" , "swift-run" , "swift-package-collection" , "swift-package-registry" , "swift-sdk" , "swift-experimental-sdk" ]:
440
490
src = "swift-package"
441
491
dest = os .path .join (cli_tool_dest , tool )
442
- note ("Creating tool symlink from %s to %s" % ( src , dest ) )
492
+ logging . info ("Creating tool symlink from %s to %s" , src , dest )
443
493
symlink_force (src , dest )
444
494
445
495
# Install the PackageDescription/CompilerPluginSupport libraries and associated modules.
@@ -488,7 +538,7 @@ def install_file(args, src, destination, destination_is_directory=True, ignored_
488
538
else :
489
539
dest = destination
490
540
491
- note ("Installing %s to %s" % ( src , dest ) )
541
+ logging . info ("Installing %s to %s" , src , dest )
492
542
if os .path .isdir (src ):
493
543
shutil .copytree (src , dest , ignore = shutil .ignore_patterns (* ignored_patterns ))
494
544
else :
@@ -521,8 +571,7 @@ def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake
521
571
"-DCMAKE_RANLIB:PATH=%s" % (args .ranlib_path ),
522
572
] + cmake_args + [source_path ]
523
573
524
- if args .verbose :
525
- print (' ' .join (cmd ))
574
+ logging .debug (' ' .join (cmd ))
526
575
527
576
mkdir_p (build_dir )
528
577
call (cmd , cwd = build_dir , verbose = True )
@@ -540,7 +589,7 @@ def build_with_cmake(args, cmake_args, ninja_args, source_path, build_dir, cmake
540
589
541
590
def build_llbuild (args ):
542
591
"""Builds LLBuild using CMake."""
543
- note ("Building llbuild" )
592
+ logging . info ("Building llbuild" )
544
593
545
594
# Set where we are going to build llbuild for future steps to find it
546
595
args .build_dirs ["llbuild" ] = os .path .join (args .target_dir , "llbuild" )
@@ -571,7 +620,7 @@ def build_llbuild(args):
571
620
build_with_cmake (args , flags , [], args .source_dirs ["llbuild" ], args .build_dirs ["llbuild" ], cmake_env = cmake_env )
572
621
573
622
def build_dependency (args , target_name , common_cmake_flags = [], non_darwin_cmake_flags = []):
574
- note ("Building " + target_name )
623
+ logging . info ("Building dependency %s" , target_name )
575
624
args .build_dirs [target_name ] = os .path .join (args .target_dir , target_name )
576
625
577
626
cmake_flags = common_cmake_flags
@@ -587,8 +636,8 @@ def add_rpath_for_cmake_build(args, rpath):
587
636
"Adds the given rpath to the CMake-built swift-bootstrap"
588
637
swift_build = os .path .join (args .bootstrap_dir , "bin/swift-bootstrap" )
589
638
add_rpath_cmd = ["install_name_tool" , "-add_rpath" , rpath , swift_build ]
590
- note (' ' .join (add_rpath_cmd ))
591
- subprocess .call (add_rpath_cmd , stderr = subprocess .PIPE )
639
+ logging . info (' ' .join (add_rpath_cmd ))
640
+ subprocess .call (add_rpath_cmd , stderr = subprocess .PIPE , env = os . environ )
592
641
593
642
def get_swift_backdeploy_library_paths (args ):
594
643
if platform .system () == 'Darwin' :
@@ -598,7 +647,7 @@ def get_swift_backdeploy_library_paths(args):
598
647
599
648
def build_swiftpm_with_cmake (args ):
600
649
"""Builds SwiftPM using CMake."""
601
- note ("Building SwiftPM (with CMake)" )
650
+ logging . info ("Building SwiftPM (with CMake)" )
602
651
603
652
cmake_flags = [
604
653
get_llbuild_cmake_arg (args ),
@@ -642,19 +691,20 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
642
691
swiftpm_args = []
643
692
644
693
if args .bootstrap :
645
- note ("Building SwiftPM (with a freshly built swift-bootstrap)" )
694
+ logging . info ("Building SwiftPM (with a freshly built swift-bootstrap)" )
646
695
swiftpm_args .append ("SWIFTPM_CUSTOM_LIBS_DIR=" + os .path .join (args .bootstrap_dir , "pm" ))
647
696
swiftpm_args .append (os .path .join (args .bootstrap_dir , "bin/swift-bootstrap" ))
648
697
else :
649
- note ("Building SwiftPM (with a prebuilt swift-build)" )
698
+ logging . info ("Building SwiftPM (with a prebuilt swift-build)" )
650
699
swiftpm_args .append (args .swift_build_path or os .path .join (os .path .split (args .swiftc_path )[0 ], "swift-build" ))
651
700
swiftpm_args .append ("--disable-sandbox" )
652
701
653
702
# Enforce resolved versions to avoid stray dependencies that aren't local.
654
703
swiftpm_args .append ("--force-resolved-versions" )
655
704
656
705
# Any leftover resolved file from a run without `SWIFTCI_USE_LOCAL_DEPS` needs to be deleted.
657
- if os .path .exists ("Package.resolved" ):
706
+ if os .path .exists ("Package.resolved" ) and args .use_local_deps :
707
+ logging .debug ("removing Package.resolve" )
658
708
os .remove ("Package.resolved" )
659
709
660
710
if integrated_swift_driver :
@@ -680,25 +730,27 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
680
730
681
731
def call_swiftpm (args , cmd , cwd = None ):
682
732
"""Calls a SwiftPM binary with the necessary environment variables and flags."""
683
-
733
+ logging . info ( "function args: %r, cmd: %r, cwd: %r" , args , cmd , cwd )
684
734
args .build_target = get_build_target (args , cross_compile = (True if args .cross_compile_config else False ))
685
735
736
+ logging .debug ("build target: %r" , args .build_target )
686
737
args .platform_path = None
687
738
for path in args .target_info ["paths" ]["runtimeLibraryPaths" ]:
688
739
args .platform_path = re .search (r"(lib/swift/([^/]+))$" , path )
689
740
if args .platform_path :
690
741
break
691
-
692
- if not args . platform_path :
693
- error (
694
- "the command `%s -print-target-info` didn't return a valid runtime library path"
695
- % args .swiftc_path
742
+ else :
743
+ # this gets called if the for loop does not break
744
+ logging . error (
745
+ "the command `%s -print-target-info` didn't return a valid runtime library path" ,
746
+ args .swiftc_path
696
747
)
748
+ raise SystemExit (1 )
697
749
698
750
full_cmd = get_swiftpm_env_cmd (args ) + cmd + get_swiftpm_flags (args )
699
751
if cwd is None :
700
752
cwd = args .project_root
701
- call (full_cmd , cwd = cwd , verbose = True )
753
+ call_output (full_cmd , cwd = cwd , stderr = True , verbose = True )
702
754
703
755
# -----------------------------------------------------------
704
756
# Build-related helper functions
@@ -727,8 +779,9 @@ def get_llbuild_source_path(args):
727
779
llbuild_path = os .path .join (args .project_root , ".." , "llbuild" )
728
780
if os .path .exists (llbuild_path ):
729
781
return llbuild_path
730
- note ("clone llbuild next to swiftpm directory; see development docs: https://github.com/swiftlang/swift-package-manager/blob/master/Documentation/Contributing.md" )
731
- error ("unable to find llbuild source directory at %s" % llbuild_path )
782
+ logging .info ("clone llbuild next to swiftpm directory; see development docs: https://github.com/swiftlang/swift-package-manager/blob/master/Documentation/Contributing.md" )
783
+ logging .error ("unable to find llbuild source directory at %s" , llbuild_path )
784
+ raise BinaryNotFound (tool = "llbuild" , path = llbuild_path )
732
785
733
786
def get_swiftpm_env_cmd (args ):
734
787
"""Returns the environment variable command to run SwiftPM binaries."""
@@ -739,7 +792,8 @@ def get_swiftpm_env_cmd(args):
739
792
740
793
if args .llbuild_link_framework :
741
794
env_cmd .append ("SWIFTPM_LLBUILD_FWK=1" )
742
- env_cmd .append ("SWIFTCI_USE_LOCAL_DEPS=1" )
795
+ if args .use_local_deps :
796
+ env_cmd .append ("SWIFTCI_USE_LOCAL_DEPS=1" )
743
797
env_cmd .append ("SWIFTPM_MACOS_DEPLOYMENT_TARGET=%s" % g_macos_deployment_target )
744
798
745
799
if not '-macosx' in args .build_target and args .command == 'install' :
@@ -823,7 +877,8 @@ def get_swiftpm_flags(args):
823
877
elif cross_compile_hosts .startswith ('android-' ):
824
878
build_flags .extend (["--destination" , args .cross_compile_config ])
825
879
else :
826
- error ("cannot cross-compile for %s" % cross_compile_hosts )
880
+ logging .error ("cannot cross-compile for %s" , cross_compile_hosts )
881
+ raise SystemExit (1 )
827
882
828
883
# Ensure we are not sharing the module cache with concurrent builds in CI
829
884
local_module_cache_path = os .path .join (args .build_dir , "module-cache" )
@@ -837,6 +892,6 @@ def get_swiftpm_flags(args):
837
892
return build_flags
838
893
839
894
if __name__ == '__main__' :
840
- log_timestamp ("start" )
895
+ logging . info ("start" )
841
896
main ()
842
- log_timestamp ("end" )
897
+ logging . info ("end" )
0 commit comments