@@ -50,7 +50,7 @@ from swift_build_support.cmake import CMake # noqa (E402)
5050import swift_build_support .workspace # noqa (E402)
5151
5252
53- def call_without_sleeping (command , dry_run = False ):
53+ def call_without_sleeping (command , env = None , dry_run = False ):
5454 """
5555 Execute a command during which system sleep is disabled.
5656
@@ -62,7 +62,119 @@ def call_without_sleeping(command, dry_run=False):
6262 # Don't mutate the caller's copy of the arguments.
6363 command = ["caffeinate" ] + list (command )
6464
65- shell .call (command , dry_run = dry_run , echo = False )
65+ shell .call (command , env = env , dry_run = dry_run )
66+
67+
68+ class HostSpecificConfiguration (object ):
69+ """Configuration information for an individual host."""
70+
71+ def __init__ (self , host_target , invocation ):
72+ """Initialize for the given `host_target`."""
73+
74+ # Compute the set of deployment targets to configure/build.
75+ args = invocation .args
76+ if host_target == args .host_target :
77+ # This host is the user's desired product, so honor the requested
78+ # set of targets to configure/build.
79+ stdlib_targets_to_configure = args .stdlib_deployment_targets
80+ if "all" in args .build_stdlib_deployment_targets :
81+ stdlib_targets_to_build = set (stdlib_targets_to_configure )
82+ else :
83+ stdlib_targets_to_build = set (
84+ args .build_stdlib_deployment_targets ).intersect (
85+ set (args .stdlib_deployment_targets ))
86+ else :
87+ # Otherwise, this is a host we are building as part of
88+ # cross-compiling, so we only need the target itself.
89+ stdlib_targets_to_configure = [host_target ]
90+ stdlib_targets_to_build = set (stdlib_targets_to_configure )
91+
92+ # Compute the lists of **CMake** targets for each use case (configure
93+ # vs. build vs. run) and the SDKs to configure with.
94+ self .sdks_to_configure = set ()
95+ self .swift_stdlib_build_targets = []
96+ self .swift_test_run_targets = []
97+ self .swift_benchmark_build_targets = []
98+ self .swift_benchmark_run_targets = []
99+ for deployment_target_name in stdlib_targets_to_configure :
100+ # Get the target object.
101+ deployment_target = StdlibDeploymentTarget .get_target_for_name (
102+ deployment_target_name )
103+ if deployment_target is None :
104+ diagnostics .fatal ("unknown target: %r" % (
105+ deployment_target_name ,))
106+
107+ # Add the SDK to use.
108+ deployment_platform = deployment_target .platform
109+ self .sdks_to_configure .add (deployment_platform .sdk_name )
110+
111+ # If we aren't actually building this target (only configuring
112+ # it), do nothing else.
113+ if deployment_target_name not in stdlib_targets_to_build :
114+ continue
115+
116+ # Compute which actions are desired.
117+ build = (
118+ deployment_platform not in invocation .platforms_to_skip_build )
119+ test = (
120+ deployment_platform not in invocation .platforms_to_skip_test )
121+ test_host_only = None
122+ build_benchmark = build and deployment_target .supports_benchmark
123+ # FIXME: Note, `build-script-impl` computed a property here
124+ # w.r.t. testing, but it was actually unused.
125+
126+ # For platforms which normally require a connected device to
127+ # test, the default behavior is to run tests that only require
128+ # the host (i.e., they do not attempt to execute).
129+ if deployment_platform .is_darwin and \
130+ deployment_platform .is_embedded and \
131+ not deployment_platform .is_simulator :
132+ if deployment_platform not in \
133+ invocation .platforms_to_skip_test_host :
134+ test_host_only = True
135+ test = True
136+ else :
137+ test = False
138+
139+ name = deployment_target .name
140+ if build :
141+ # Validation and long tests require building the full standard
142+ # library, whereas the other targets can build a slightly
143+ # smaller subset which is faster to build.
144+ if args .build_swift_stdlib_unittest_extra or \
145+ args .validation_test or args .long_test :
146+ self .swift_stdlib_build_targets .append (
147+ "swift-stdlib-" + name )
148+ else :
149+ self .swift_stdlib_build_targets .append (
150+ "swift-test-stdlib-" + name )
151+ if build_benchmark :
152+ self .swift_benchmark_build_targets .append (
153+ "swift-benchmark-" + name )
154+ # FIXME: This probably should respect `args.benchmark`, but
155+ # a typo in build-script-impl meant we always would do this.
156+ self .swift_benchmark_run_targets .append (
157+ "check-swift-benchmark-" + name )
158+ if test :
159+ if test_host_only :
160+ suffix = "-non-executable"
161+ else :
162+ suffix = ""
163+ subset_suffix = ""
164+ if args .validation_test and args .long_test :
165+ subset_suffix = "-all"
166+ elif args .validation_test :
167+ subset_suffix = "-validation"
168+ elif args .long_test :
169+ subset_suffix = "-only_long"
170+ else :
171+ subset_suffix = ""
172+ self .swift_test_run_targets .append ("check-swift{}{}-{}" .format (
173+ subset_suffix , suffix , name ))
174+ if args .test_optimized and not test_host_only :
175+ self .swift_test_run_targets .append (
176+ "check-swift{}-optimize-{}" .format (
177+ subset_suffix , name ))
66178
67179
68180class BuildScriptInvocation (object ):
@@ -291,6 +403,79 @@ class BuildScriptInvocation(object):
291403 source_root = SWIFT_SOURCE_ROOT ,
292404 build_root = os .path .join (SWIFT_BUILD_ROOT , args .build_subdir ))
293405
406+ # Compute derived information from the arguments.
407+ #
408+ # FIXME: We should move the platform-derived arguments to be entirely
409+ # data driven, so that we can eliminate this code duplication and just
410+ # iterate over all supported platforms.
411+
412+ self .platforms_to_skip_build = set ()
413+ if args .skip_build_linux :
414+ self .platforms_to_skip_build .add (StdlibDeploymentTarget .Linux )
415+ if args .skip_build_freebsd :
416+ self .platforms_to_skip_build .add (StdlibDeploymentTarget .FreeBSD )
417+ if args .skip_build_cygwin :
418+ self .platforms_to_skip_build .add (StdlibDeploymentTarget .Cygwin )
419+ if args .skip_build_osx :
420+ self .platforms_to_skip_build .add (StdlibDeploymentTarget .OSX )
421+ if args .skip_build_ios_device :
422+ self .platforms_to_skip_build .add (StdlibDeploymentTarget .iOS )
423+ if args .skip_build_ios_simulator :
424+ self .platforms_to_skip_build .add (
425+ StdlibDeploymentTarget .iOSSimulator )
426+ if args .skip_build_tvos_device :
427+ self .platforms_to_skip_build .add (StdlibDeploymentTarget .AppleTV )
428+ if args .skip_build_tvos_simulator :
429+ self .platforms_to_skip_build .add (
430+ StdlibDeploymentTarget .AppleTVSimulator )
431+ if args .skip_build_watchos_device :
432+ self .platforms_to_skip_build .add (StdlibDeploymentTarget .AppleWatch )
433+ if args .skip_build_watchos_simulator :
434+ self .platforms_to_skip_build .add (
435+ StdlibDeploymentTarget .AppleWatchSimulator )
436+ if args .skip_build_android :
437+ self .platforms_to_skip_build .add (StdlibDeploymentTarget .Android )
438+
439+ self .platforms_to_skip_test = set ()
440+ if args .skip_test_linux :
441+ self .platforms_to_skip_test .add (StdlibDeploymentTarget .Linux )
442+ if args .skip_test_freebsd :
443+ self .platforms_to_skip_test .add (StdlibDeploymentTarget .FreeBSD )
444+ if args .skip_test_cygwin :
445+ self .platforms_to_skip_test .add (StdlibDeploymentTarget .Cygwin )
446+ if args .skip_test_osx :
447+ self .platforms_to_skip_test .add (StdlibDeploymentTarget .OSX )
448+ if args .skip_test_ios_host :
449+ self .platforms_to_skip_test .add (StdlibDeploymentTarget .iOS )
450+ if args .skip_test_ios_simulator :
451+ self .platforms_to_skip_test .add (
452+ StdlibDeploymentTarget .iOSSimulator )
453+ if args .skip_test_tvos_host :
454+ self .platforms_to_skip_test .add (StdlibDeploymentTarget .AppleTV )
455+ if args .skip_test_tvos_simulator :
456+ self .platforms_to_skip_test .add (
457+ StdlibDeploymentTarget .AppleTVSimulator )
458+ if args .skip_test_watchos_host :
459+ self .platforms_to_skip_test .add (StdlibDeploymentTarget .AppleWatch )
460+ if args .skip_test_watchos_simulator :
461+ self .platforms_to_skip_test .add (
462+ StdlibDeploymentTarget .AppleWatchSimulator )
463+ # We never allow testing Android, currently.
464+ #
465+ # FIXME: Allow Android host tests to be enabled/disabled by the build
466+ # script.
467+ self .platforms_to_skip_test .add (StdlibDeploymentTarget .Android )
468+
469+ self .platforms_to_skip_test_host = set ()
470+ if args .skip_test_ios_host :
471+ self .platforms_to_skip_test_host .add (StdlibDeploymentTarget .iOS )
472+ if args .skip_test_tvos_host :
473+ self .platforms_to_skip_test_host .add (
474+ StdlibDeploymentTarget .AppleTV )
475+ if args .skip_test_watchos_host :
476+ self .platforms_to_skip_test_host .add (
477+ StdlibDeploymentTarget .AppleWatch )
478+
294479 def initialize_runtime_environment (self ):
295480 """Change the program environment for building."""
296481
@@ -322,10 +507,10 @@ class BuildScriptInvocation(object):
322507 self .toolchain .ninja = ninja_build .ninja_bin_path
323508
324509 def convert_to_impl_arguments (self ):
325- """convert_to_impl_arguments() -> args
510+ """convert_to_impl_arguments() -> (env, args)
326511
327- Convert the invocation to a list of arguments suitable for invoking
328- `build-script-impl`.
512+ Convert the invocation to an environment and list of arguments suitable
513+ for invoking `build-script-impl`.
329514 """
330515
331516 # Create local shadows, for convenience.
@@ -374,6 +559,14 @@ class BuildScriptInvocation(object):
374559 pipes .quote (arg ) for arg in cmake .build_args ()),
375560 ]
376561
562+ if args .build_stdlib_deployment_targets :
563+ impl_args += [
564+ "--build-stdlib-deployment-targets" , " " .join (
565+ args .build_stdlib_deployment_targets )]
566+ if args .cross_compile_hosts :
567+ impl_args += [
568+ "--cross-compile-hosts" , " " .join (args .cross_compile_hosts )]
569+
377570 if toolchain .ninja :
378571 impl_args += ["--ninja-bin=%s" % toolchain .ninja ]
379572 if args .distcc :
@@ -415,6 +608,8 @@ class BuildScriptInvocation(object):
415608 impl_args += ["--skip-build-libdispatch" ]
416609 if not args .build_swiftpm :
417610 impl_args += ["--skip-build-swiftpm" ]
611+ if args .build_swift_stdlib_unittest_extra :
612+ impl_args += ["--build-swift-stdlib-unittest-extra" ]
418613
419614 if args .skip_build_linux :
420615 impl_args += ["--skip-build-linux" ]
@@ -536,7 +731,48 @@ class BuildScriptInvocation(object):
536731 if args .dry_run :
537732 impl_args += ["--dry-run" ]
538733
539- return impl_args
734+ # Compute the set of host-specific variables, which we pass through to
735+ # the build script via environment variables.
736+ host_specific_variables = self .compute_host_specific_variables ()
737+ impl_env = {}
738+ for (host_target , options ) in host_specific_variables .items ():
739+ for (name , value ) in options .items ():
740+ # We mangle into an environment variable we can easily evaluate
741+ # from the `build-script-impl`.
742+ impl_env ["HOST_VARIABLE_{}__{}" .format (
743+ host_target .replace ("-" , "_" ), name )] = value
744+
745+ return (impl_env , impl_args )
746+
747+ def compute_host_specific_variables (self ):
748+ """compute_host_specific_variables(args) -> dict
749+
750+ Compute the host-specific options, organized as a dictionary keyed by
751+ host of options.
752+ """
753+
754+ args = self .args
755+
756+ options = {}
757+ for host_target in [args .host_target ] + args .cross_compile_hosts :
758+ # Compute the host specific configuration.
759+ config = HostSpecificConfiguration (host_target , self )
760+
761+ # Convert into `build-script-impl` style variables.
762+ options [host_target ] = {
763+ "SWIFT_SDKS" : " " .join (sorted (
764+ config .sdks_to_configure )),
765+ "SWIFT_STDLIB_TARGETS" : " " .join (
766+ config .swift_stdlib_build_targets ),
767+ "SWIFT_BENCHMARK_TARGETS" : " " .join (
768+ config .swift_benchmark_build_targets ),
769+ "SWIFT_RUN_BENCHMARK_TARGETS" : " " .join (
770+ config .swift_benchmark_run_targets ),
771+ "SWIFT_TEST_TARGETS" : " " .join (
772+ config .swift_test_run_targets ),
773+ }
774+
775+ return options
540776
541777
542778# Main entry point for the preset mode.
@@ -814,13 +1050,27 @@ details of the setups of other systems or automated environments.""")
8141050 help = "The host target. LLVM, Clang, and Swift will be built for this "
8151051 "target. The built LLVM and Clang will be used to compile Swift "
8161052 "for the cross-compilation targets." ,
817- default = StdlibDeploymentTarget .host_target ())
1053+ default = StdlibDeploymentTarget .host_target ().name )
1054+ targets_group .add_argument (
1055+ "--cross-compile-hosts" ,
1056+ help = "A space separated list of targets to cross-compile host Swift "
1057+ "tools for. Can be used multiple times." ,
1058+ action = arguments .action .concat , type = arguments .type .shell_split ,
1059+ default = [])
1060+ stdlib_targets = StdlibDeploymentTarget .default_stdlib_deployment_targets ()
8181061 targets_group .add_argument (
8191062 "--stdlib-deployment-targets" ,
8201063 help = "list of targets to compile or cross-compile the Swift standard "
8211064 "library for. %(default)s by default." ,
8221065 nargs = "*" ,
823- default = StdlibDeploymentTarget .default_stdlib_deployment_targets ())
1066+ default = [
1067+ target .name
1068+ for target in stdlib_targets ])
1069+ targets_group .add_argument (
1070+ "--build-stdlib-deployment-targets" ,
1071+ help = "A space-separated list that filters which of the configured "
1072+ "targets to build the Swift standard library for, or 'all'." ,
1073+ type = arguments .type .shell_split , default = ["all" ])
8241074
8251075 projects_group = parser .add_argument_group (
8261076 title = "Options to select projects" )
@@ -1120,6 +1370,10 @@ details of the setups of other systems or automated environments.""")
11201370 help = "Use the host compiler, not the self-built one to compile the "
11211371 "Swift runtime" ,
11221372 action = "store_true" )
1373+ parser .add_argument (
1374+ "--build-swift-stdlib-unittest-extra" ,
1375+ help = "Build optional StdlibUnittest components" ,
1376+ action = "store_true" )
11231377
11241378 run_build_group = parser .add_argument_group (
11251379 title = "Run build" )
@@ -1480,6 +1734,7 @@ details of the setups of other systems or automated environments.""")
14801734 "--build-jobs" ,
14811735 "--common-cmake-options" ,
14821736 "--only-execute" ,
1737+ "--skip-test-optimized" ,
14831738 action = arguments .action .unavailable )
14841739
14851740 args = migration .parse_args (parser , sys .argv [1 :])
@@ -1541,10 +1796,12 @@ details of the setups of other systems or automated environments.""")
15411796 invocation .build_ninja ()
15421797
15431798 # Convert to a build-script-impl invocation.
1544- build_script_impl_args = invocation .convert_to_impl_arguments ()
1799+ (build_script_impl_env , build_script_impl_args ) = \
1800+ invocation .convert_to_impl_arguments ()
15451801
15461802 # Execute the underlying build script implementation.
1547- call_without_sleeping ([build_script_impl ] + build_script_impl_args )
1803+ call_without_sleeping ([build_script_impl ] + build_script_impl_args ,
1804+ env = build_script_impl_env )
15481805
15491806 if args .symbols_package :
15501807 print ('--- Creating symbols package ---' )
0 commit comments