| #!/usr/bin/env python |
| # utils/build-script - The ultimate tool for building Swift -*- python -*- |
| # |
| # This source file is part of the Swift.org open source project |
| # |
| # Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors |
| # Licensed under Apache License v2.0 with Runtime Library Exception |
| # |
| # See http://swift.org/LICENSE.txt for license information |
| # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| |
| from __future__ import print_function |
| |
| import argparse |
| import multiprocessing |
| import os |
| import pipes |
| import platform |
| import sys |
| |
| # FIXME: Instead of modifying the system path in order to enable imports from |
| # other directories, all Python modules related to the build script |
| # should be moved to the `swift_build_support` module. Remove "noqa" |
| # markers when this is fixed. |
| # For additional information, see: https://bugs.swift.org/browse/SR-237. |
| sys.path.append(os.path.dirname(__file__)) |
| from SwiftBuildSupport import ( |
| HOME, |
| SWIFT_BUILD_ROOT, |
| SWIFT_SOURCE_ROOT, |
| get_all_preset_names, |
| get_preset_options, |
| ) # noqa (E402 module level import not at top of file) |
| |
| sys.path.append(os.path.join(os.path.dirname(__file__), 'swift_build_support')) |
| |
| # E402 means module level import not at top of file |
| from swift_build_support import arguments # noqa (E402) |
| from swift_build_support import diagnostics # noqa (E402) |
| from swift_build_support import host # noqa (E402) |
| from swift_build_support.toolchain import host_toolchain # noqa (E402) |
| import swift_build_support.debug # noqa (E402) |
| from swift_build_support import migration # noqa (E402) |
| from swift_build_support import products # noqa (E402) |
| from swift_build_support import shell # noqa (E402) |
| import swift_build_support.tar # noqa (E402) |
| import swift_build_support.targets # noqa (E402) |
| from swift_build_support.targets import StdlibDeploymentTarget # noqa (E402) |
| from swift_build_support.cmake import CMake # noqa (E402) |
| import swift_build_support.workspace # noqa (E402) |
| |
| sys.path.append(os.path.join(os.path.dirname(__file__), 'android')) |
| import adb.commands # noqa (E402) |
| |
| |
| build_script_impl = os.path.join( |
| SWIFT_SOURCE_ROOT, "swift", "utils", "build-script-impl") |
| |
| |
| def call_without_sleeping(command, env=None, dry_run=False, echo=False): |
| """ |
| Execute a command during which system sleep is disabled. |
| |
| By default, this ignores the state of the `shell.dry_run` flag. |
| """ |
| |
| # Disable system sleep, if possible. |
| if platform.system() == 'Darwin': |
| # Don't mutate the caller's copy of the arguments. |
| command = ["caffeinate"] + list(command) |
| |
| shell.call(command, env=env, dry_run=dry_run, echo=echo) |
| |
| |
| class HostSpecificConfiguration(object): |
| """Configuration information for an individual host.""" |
| |
| def __init__(self, host_target, invocation): |
| """Initialize for the given `host_target`.""" |
| |
| # Compute the set of deployment targets to configure/build. |
| args = invocation.args |
| if host_target == args.host_target: |
| # This host is the user's desired product, so honor the requested |
| # set of targets to configure/build. |
| stdlib_targets_to_configure = args.stdlib_deployment_targets |
| if "all" in args.build_stdlib_deployment_targets: |
| stdlib_targets_to_build = set(stdlib_targets_to_configure) |
| else: |
| stdlib_targets_to_build = set( |
| args.build_stdlib_deployment_targets).intersection( |
| set(args.stdlib_deployment_targets)) |
| else: |
| # Otherwise, this is a host we are building as part of |
| # cross-compiling, so we only need the target itself. |
| stdlib_targets_to_configure = [host_target] |
| stdlib_targets_to_build = set(stdlib_targets_to_configure) |
| |
| # Compute the lists of **CMake** targets for each use case (configure |
| # vs. build vs. run) and the SDKs to configure with. |
| self.sdks_to_configure = set() |
| self.swift_stdlib_build_targets = [] |
| self.swift_test_run_targets = [] |
| self.swift_benchmark_build_targets = [] |
| self.swift_benchmark_run_targets = [] |
| for deployment_target_name in stdlib_targets_to_configure: |
| # Get the target object. |
| deployment_target = StdlibDeploymentTarget.get_target_for_name( |
| deployment_target_name) |
| if deployment_target is None: |
| diagnostics.fatal("unknown target: %r" % ( |
| deployment_target_name,)) |
| |
| # Add the SDK to use. |
| deployment_platform = deployment_target.platform |
| self.sdks_to_configure.add(deployment_platform.sdk_name) |
| |
| # If we aren't actually building this target (only configuring |
| # it), do nothing else. |
| if deployment_target_name not in stdlib_targets_to_build: |
| continue |
| |
| # Compute which actions are desired. |
| build = ( |
| deployment_platform not in invocation.platforms_to_skip_build) |
| test = ( |
| deployment_platform not in invocation.platforms_to_skip_test) |
| test_host_only = None |
| build_benchmark = build and deployment_target.supports_benchmark |
| # FIXME: Note, `build-script-impl` computed a property here |
| # w.r.t. testing, but it was actually unused. |
| |
| # For platforms which normally require a connected device to |
| # test, the default behavior is to run tests that only require |
| # the host (i.e., they do not attempt to execute). |
| if deployment_platform.is_darwin and \ |
| deployment_platform.is_embedded and \ |
| not deployment_platform.is_simulator: |
| if deployment_platform not in \ |
| invocation.platforms_to_skip_test_host: |
| test_host_only = True |
| test = True |
| else: |
| test = False |
| |
| name = deployment_target.name |
| if build: |
| # Validation and long tests require building the full standard |
| # library, whereas the other targets can build a slightly |
| # smaller subset which is faster to build. |
| if args.build_swift_stdlib_unittest_extra or \ |
| args.validation_test or args.long_test: |
| self.swift_stdlib_build_targets.append( |
| "swift-stdlib-" + name) |
| else: |
| self.swift_stdlib_build_targets.append( |
| "swift-test-stdlib-" + name) |
| if build_benchmark: |
| self.swift_benchmark_build_targets.append( |
| "swift-benchmark-" + name) |
| # FIXME: This probably should respect `args.benchmark`, but |
| # a typo in build-script-impl meant we always would do this. |
| self.swift_benchmark_run_targets.append( |
| "check-swift-benchmark-" + name) |
| if test: |
| if test_host_only: |
| suffix = "-non-executable" |
| else: |
| suffix = "" |
| subset_suffix = "" |
| if args.validation_test and args.long_test: |
| subset_suffix = "-all" |
| elif args.validation_test: |
| subset_suffix = "-validation" |
| elif args.long_test: |
| subset_suffix = "-only_long" |
| else: |
| subset_suffix = "" |
| self.swift_test_run_targets.append("check-swift{}{}-{}".format( |
| subset_suffix, suffix, name)) |
| if args.test_optimized and not test_host_only: |
| self.swift_test_run_targets.append( |
| "check-swift{}-optimize-{}".format( |
| subset_suffix, name)) |
| |
| |
| class BuildScriptInvocation(object): |
| """Represent a single build script invocation.""" |
| |
| @staticmethod |
| def validate_arguments(toolchain, args): |
| if toolchain.cc is None or toolchain.cxx is None: |
| diagnostics.fatal( |
| "can't find clang (please install clang-3.5 or a " |
| "later version)") |
| |
| if toolchain.cmake is None: |
| diagnostics.fatal("can't find CMake (please install CMake)") |
| |
| if args.distcc: |
| if toolchain.distcc is None: |
| diagnostics.fatal( |
| "can't find distcc (please install distcc)") |
| if toolchain.distcc_pump is None: |
| diagnostics.fatal( |
| "can't find distcc-pump (please install distcc-pump)") |
| |
| if args.host_target is None or args.stdlib_deployment_targets is None: |
| diagnostics.fatal("unknown operating system") |
| |
| if args.symbols_package: |
| if not os.path.isabs(args.symbols_package): |
| print( |
| '--symbols-package must be an absolute path ' |
| '(was \'{}\')'.format(args.symbols_package)) |
| return 1 |
| if not args.install_symroot: |
| diagnostics.fatal( |
| "--install-symroot is required when specifying " |
| "--symbols-package.") |
| |
| if args.android: |
| if args.android_ndk is None or \ |
| args.android_api_level is None or \ |
| args.android_icu_uc is None or \ |
| args.android_icu_uc_include is None or \ |
| args.android_icu_i18n is None or \ |
| args.android_icu_i18n_include is None: |
| diagnostics.fatal( |
| "when building for Android, --android-ndk, " |
| "--android-ndk-version, --android-icu-uc, " |
| "--android-icu-uc-include, --android-icu-i18n, " |
| "and --android-icu-i18n-include must be specified") |
| |
| @staticmethod |
| def apply_default_arguments(toolchain, args): |
| """Preprocess an argument set to apply default behaviors.""" |
| |
| # Build cmark if any cmark-related options were specified. |
| if (args.cmark_build_variant is not None): |
| args.build_cmark = True |
| |
| # Build LLDB if any LLDB-related options were specified. |
| if args.lldb_build_variant is not None or \ |
| args.lldb_assertions is not None: |
| args.build_lldb = True |
| |
| # Set the default build variant. |
| if args.build_variant is None: |
| args.build_variant = "Debug" |
| |
| # Set the default stdlib-deployment-targets, if none were provided. |
| if args.stdlib_deployment_targets is None: |
| stdlib_targets = \ |
| StdlibDeploymentTarget.default_stdlib_deployment_targets() |
| args.stdlib_deployment_targets = [ |
| target.name for target in stdlib_targets] |
| |
| # Propagate the default build variant. |
| if args.cmark_build_variant is None: |
| args.cmark_build_variant = args.build_variant |
| |
| if args.llvm_build_variant is None: |
| args.llvm_build_variant = args.build_variant |
| |
| if args.swift_build_variant is None: |
| args.swift_build_variant = args.build_variant |
| |
| if args.swift_stdlib_build_variant is None: |
| args.swift_stdlib_build_variant = args.build_variant |
| |
| if args.lldb_build_variant is None: |
| args.lldb_build_variant = args.build_variant |
| |
| if args.foundation_build_variant is None: |
| args.foundation_build_variant = args.build_variant |
| |
| if args.libdispatch_build_variant is None: |
| args.libdispatch_build_variant = args.build_variant |
| |
| # Assertions are enabled by default. |
| if args.assertions is None: |
| args.assertions = True |
| |
| # Propagate the default assertions setting. |
| if args.cmark_assertions is None: |
| args.cmark_assertions = args.assertions |
| |
| if args.llvm_assertions is None: |
| args.llvm_assertions = args.assertions |
| |
| if args.swift_assertions is None: |
| args.swift_assertions = args.assertions |
| |
| if args.swift_stdlib_assertions is None: |
| args.swift_stdlib_assertions = args.assertions |
| |
| # Set the default CMake generator. |
| if args.cmake_generator is None: |
| args.cmake_generator = "Ninja" |
| |
| ninja_required = ( |
| args.cmake_generator == 'Ninja' or args.build_foundation) |
| if ninja_required and toolchain.ninja is None: |
| args.build_ninja = True |
| |
| # SwiftPM and XCTest have a dependency on Foundation. |
| # On OS X, Foundation is built automatically using xcodebuild. |
| # On Linux, we must ensure that it is built manually. |
| if ((args.build_swiftpm or args.build_xctest) and |
| platform.system() != "Darwin"): |
| args.build_foundation = True |
| |
| # Propagate global --skip-build |
| if args.skip_build: |
| args.skip_build_linux = True |
| args.skip_build_freebsd = True |
| args.skip_build_cygwin = True |
| args.skip_build_osx = True |
| args.skip_build_ios = True |
| args.skip_build_tvos = True |
| args.skip_build_watchos = True |
| args.skip_build_android = True |
| args.skip_build_benchmarks = True |
| args.build_lldb = False |
| args.build_llbuild = False |
| args.build_swiftpm = False |
| args.build_xctest = False |
| args.build_foundation = False |
| args.build_libdispatch = False |
| args.build_playgroundlogger = False |
| args.build_playgroundsupport = False |
| |
| # --skip-{ios,tvos,watchos} or --skip-build-{ios,tvos,watchos} are |
| # merely shorthands for --skip-build-{**os}-{device,simulator} |
| if not args.ios or args.skip_build_ios: |
| args.skip_build_ios_device = True |
| args.skip_build_ios_simulator = True |
| |
| if not args.tvos or args.skip_build_tvos: |
| args.skip_build_tvos_device = True |
| args.skip_build_tvos_simulator = True |
| |
| if not args.watchos or args.skip_build_watchos: |
| args.skip_build_watchos_device = True |
| args.skip_build_watchos_simulator = True |
| |
| if not args.android or args.skip_build_android: |
| args.skip_build_android = True |
| |
| # --validation-test implies --test. |
| if args.validation_test: |
| args.test = True |
| |
| # --test-optimized implies --test. |
| if args.test_optimized: |
| args.test = True |
| |
| # If none of tests specified skip swift stdlib test on all platforms |
| if not args.test and not args.validation_test and not args.long_test: |
| args.skip_test_linux = True |
| args.skip_test_freebsd = True |
| args.skip_test_cygwin = True |
| args.skip_test_osx = True |
| args.skip_test_ios = True |
| args.skip_test_tvos = True |
| args.skip_test_watchos = True |
| |
| # --skip-test-ios is merely a shorthand for host and simulator tests. |
| if args.skip_test_ios: |
| args.skip_test_ios_host = True |
| args.skip_test_ios_simulator = True |
| # --skip-test-tvos is merely a shorthand for host and simulator tests. |
| if args.skip_test_tvos: |
| args.skip_test_tvos_host = True |
| args.skip_test_tvos_simulator = True |
| # --skip-test-watchos is merely a shorthand for host and simulator |
| # --tests. |
| if args.skip_test_watchos: |
| args.skip_test_watchos_host = True |
| args.skip_test_watchos_simulator = True |
| |
| # --skip-build-{ios,tvos,watchos}-{device,simulator} implies |
| # --skip-test-{ios,tvos,watchos}-{host,simulator} |
| if args.skip_build_ios_device: |
| args.skip_test_ios_host = True |
| if args.skip_build_ios_simulator: |
| args.skip_test_ios_simulator = True |
| |
| if args.skip_build_tvos_device: |
| args.skip_test_tvos_host = True |
| if args.skip_build_tvos_simulator: |
| args.skip_test_tvos_simulator = True |
| |
| if args.skip_build_watchos_device: |
| args.skip_test_watchos_host = True |
| if args.skip_build_watchos_simulator: |
| args.skip_test_watchos_simulator = True |
| |
| if args.skip_build_android: |
| args.skip_test_android_host = True |
| |
| if not args.host_test: |
| args.skip_test_ios_host = True |
| args.skip_test_tvos_host = True |
| args.skip_test_watchos_host = True |
| args.skip_test_android_host = True |
| |
| if args.build_subdir is None: |
| args.build_subdir = \ |
| swift_build_support.workspace.compute_build_subdir(args) |
| |
| # Add optional stdlib-deployment-targets |
| if args.android: |
| args.stdlib_deployment_targets.append( |
| StdlibDeploymentTarget.Android.armv7.name) |
| |
| # Infer platform flags from manually-specified configure targets. |
| # This doesn't apply to Darwin platforms, as they are |
| # already configured. No building without the platform flag, though. |
| |
| android_tgts = [tgt for tgt in args.stdlib_deployment_targets |
| if StdlibDeploymentTarget.Android.contains(tgt)] |
| if not args.android and len(android_tgts) > 0: |
| args.android = True |
| args.skip_build_android = True |
| |
| # --- |
| |
| def __init__(self, toolchain, args): |
| self.toolchain = toolchain |
| self.args = args |
| |
| self.workspace = swift_build_support.workspace.Workspace( |
| source_root=SWIFT_SOURCE_ROOT, |
| build_root=os.path.join(SWIFT_BUILD_ROOT, args.build_subdir)) |
| |
| # Compute derived information from the arguments. |
| # |
| # FIXME: We should move the platform-derived arguments to be entirely |
| # data driven, so that we can eliminate this code duplication and just |
| # iterate over all supported platforms. |
| |
| self.platforms_to_skip_build = set() |
| if args.skip_build_linux: |
| self.platforms_to_skip_build.add(StdlibDeploymentTarget.Linux) |
| if args.skip_build_freebsd: |
| self.platforms_to_skip_build.add(StdlibDeploymentTarget.FreeBSD) |
| if args.skip_build_cygwin: |
| self.platforms_to_skip_build.add(StdlibDeploymentTarget.Cygwin) |
| if args.skip_build_osx: |
| self.platforms_to_skip_build.add(StdlibDeploymentTarget.OSX) |
| if args.skip_build_ios_device: |
| self.platforms_to_skip_build.add(StdlibDeploymentTarget.iOS) |
| if args.skip_build_ios_simulator: |
| self.platforms_to_skip_build.add( |
| StdlibDeploymentTarget.iOSSimulator) |
| if args.skip_build_tvos_device: |
| self.platforms_to_skip_build.add(StdlibDeploymentTarget.AppleTV) |
| if args.skip_build_tvos_simulator: |
| self.platforms_to_skip_build.add( |
| StdlibDeploymentTarget.AppleTVSimulator) |
| if args.skip_build_watchos_device: |
| self.platforms_to_skip_build.add(StdlibDeploymentTarget.AppleWatch) |
| if args.skip_build_watchos_simulator: |
| self.platforms_to_skip_build.add( |
| StdlibDeploymentTarget.AppleWatchSimulator) |
| if args.skip_build_android: |
| self.platforms_to_skip_build.add(StdlibDeploymentTarget.Android) |
| |
| self.platforms_to_skip_test = set() |
| if args.skip_test_linux: |
| self.platforms_to_skip_test.add(StdlibDeploymentTarget.Linux) |
| if args.skip_test_freebsd: |
| self.platforms_to_skip_test.add(StdlibDeploymentTarget.FreeBSD) |
| if args.skip_test_cygwin: |
| self.platforms_to_skip_test.add(StdlibDeploymentTarget.Cygwin) |
| if args.skip_test_osx: |
| self.platforms_to_skip_test.add(StdlibDeploymentTarget.OSX) |
| # iOS device tests are not supported. |
| self.platforms_to_skip_test.add(StdlibDeploymentTarget.iOS) |
| if args.skip_test_ios_simulator: |
| self.platforms_to_skip_test.add( |
| StdlibDeploymentTarget.iOSSimulator) |
| # tvOS device tests are not supported. |
| self.platforms_to_skip_test.add(StdlibDeploymentTarget.AppleTV) |
| if args.skip_test_tvos_simulator: |
| self.platforms_to_skip_test.add( |
| StdlibDeploymentTarget.AppleTVSimulator) |
| # watchOS device tests are not supported. |
| self.platforms_to_skip_test.add(StdlibDeploymentTarget.AppleWatch) |
| if args.skip_test_watchos_simulator: |
| self.platforms_to_skip_test.add( |
| StdlibDeploymentTarget.AppleWatchSimulator) |
| |
| if args.skip_test_android_host: |
| self.platforms_to_skip_test.add(StdlibDeploymentTarget.Android) |
| |
| self.platforms_to_skip_test_host = set() |
| if args.skip_test_ios_host: |
| self.platforms_to_skip_test_host.add(StdlibDeploymentTarget.iOS) |
| if args.skip_test_tvos_host: |
| self.platforms_to_skip_test_host.add( |
| StdlibDeploymentTarget.AppleTV) |
| if args.skip_test_watchos_host: |
| self.platforms_to_skip_test_host.add( |
| StdlibDeploymentTarget.AppleWatch) |
| |
| def initialize_runtime_environment(self): |
| """Change the program environment for building.""" |
| |
| # Set an appropriate default umask. |
| os.umask(0o022) |
| |
| # Unset environment variables that might affect how tools behave. |
| for v in [ |
| 'MAKEFLAGS', |
| 'SDKROOT', |
| 'MACOSX_DEPLOYMENT_TARGET', |
| 'IPHONEOS_DEPLOYMENT_TARGET', |
| 'TVOS_DEPLOYMENT_TARGET', |
| 'WATCHOS_DEPLOYMENT_TARGET']: |
| os.environ.pop(v, None) |
| |
| def build_ninja(self): |
| if not os.path.exists(self.workspace.source_dir("ninja")): |
| diagnostics.fatal( |
| "can't find source directory for ninja " |
| "(tried %s)" % (self.workspace.source_dir("ninja"))) |
| |
| ninja_build = products.Ninja( |
| args=self.args, |
| toolchain=self.toolchain, |
| source_dir=self.workspace.source_dir("ninja"), |
| build_dir=self.workspace.build_dir("build", "ninja")) |
| ninja_build.do_build() |
| self.toolchain.ninja = ninja_build.ninja_bin_path |
| |
| def convert_to_impl_arguments(self): |
| """convert_to_impl_arguments() -> (env, args) |
| |
| Convert the invocation to an environment and list of arguments suitable |
| for invoking `build-script-impl`. |
| """ |
| |
| # Create local shadows, for convenience. |
| args = self.args |
| toolchain = self.toolchain |
| |
| cmake = CMake(args=args, |
| toolchain=self.toolchain) |
| |
| impl_args = [ |
| "--workspace", self.workspace.source_root, |
| "--build-dir", self.workspace.build_root, |
| "--install-prefix", args.install_prefix, |
| "--host-target", args.host_target, |
| "--stdlib-deployment-targets", |
| " ".join(args.stdlib_deployment_targets), |
| "--host-cc", toolchain.cc, |
| "--host-cxx", toolchain.cxx, |
| "--darwin-xcrun-toolchain", args.darwin_xcrun_toolchain, |
| "--darwin-deployment-version-osx=%s" % ( |
| args.darwin_deployment_version_osx), |
| "--darwin-deployment-version-ios=%s" % ( |
| args.darwin_deployment_version_ios), |
| "--darwin-deployment-version-tvos=%s" % ( |
| args.darwin_deployment_version_tvos), |
| "--darwin-deployment-version-watchos=%s" % ( |
| args.darwin_deployment_version_watchos), |
| "--cmake", toolchain.cmake, |
| "--cmark-build-type", args.cmark_build_variant, |
| "--llvm-build-type", args.llvm_build_variant, |
| "--swift-build-type", args.swift_build_variant, |
| "--swift-stdlib-build-type", args.swift_stdlib_build_variant, |
| "--lldb-build-type", args.lldb_build_variant, |
| "--foundation-build-type", args.foundation_build_variant, |
| "--libdispatch-build-type", args.libdispatch_build_variant, |
| "--xctest-build-type", args.build_variant, |
| "--llvm-enable-assertions", str(args.llvm_assertions).lower(), |
| "--swift-enable-assertions", str(args.swift_assertions).lower(), |
| "--swift-stdlib-enable-assertions", str( |
| args.swift_stdlib_assertions).lower(), |
| "--swift-analyze-code-coverage", str( |
| args.swift_analyze_code_coverage).lower(), |
| "--cmake-generator", args.cmake_generator, |
| "--build-jobs", str(args.build_jobs), |
| "--common-cmake-options=%s" % ' '.join( |
| pipes.quote(opt) for opt in cmake.common_options()), |
| "--build-args=%s" % ' '.join( |
| pipes.quote(arg) for arg in cmake.build_args()), |
| ] |
| |
| if args.build_stdlib_deployment_targets: |
| impl_args += [ |
| "--build-stdlib-deployment-targets", " ".join( |
| args.build_stdlib_deployment_targets)] |
| if args.cross_compile_hosts: |
| impl_args += [ |
| "--cross-compile-hosts", " ".join(args.cross_compile_hosts)] |
| |
| if toolchain.ninja: |
| impl_args += ["--ninja-bin=%s" % toolchain.ninja] |
| if args.distcc: |
| impl_args += [ |
| "--distcc", |
| "--distcc-pump=%s" % toolchain.distcc_pump |
| ] |
| if args.enable_asan: |
| impl_args += ["--enable-asan"] |
| if args.enable_ubsan: |
| impl_args += ["--enable-ubsan"] |
| if args.clang_compiler_version: |
| impl_args += [ |
| "--clang-compiler-version=%s" % ( |
| args.clang_compiler_version) |
| ] |
| if args.verbose_build: |
| impl_args += ["--verbose-build"] |
| if args.install_symroot: |
| impl_args += [ |
| "--install-symroot", os.path.abspath(args.install_symroot) |
| ] |
| |
| if args.skip_build: |
| impl_args += ["--skip-build-cmark", |
| "--skip-build-llvm", |
| "--skip-build-swift"] |
| if args.skip_build_benchmarks: |
| impl_args += ["--skip-build-benchmarks"] |
| if not args.build_foundation: |
| impl_args += ["--skip-build-foundation"] |
| if not args.build_xctest: |
| impl_args += ["--skip-build-xctest"] |
| if not args.build_lldb: |
| impl_args += ["--skip-build-lldb"] |
| if not args.build_llbuild: |
| impl_args += ["--skip-build-llbuild"] |
| if not args.build_libdispatch: |
| impl_args += ["--skip-build-libdispatch"] |
| if not args.build_swiftpm: |
| impl_args += ["--skip-build-swiftpm"] |
| if not args.build_playgroundlogger: |
| impl_args += ["--skip-build-playgroundlogger"] |
| if not args.build_playgroundsupport: |
| impl_args += ["--skip-build-playgroundsupport"] |
| if args.build_swift_dynamic_stdlib: |
| impl_args += ["--build-swift-dynamic-stdlib"] |
| if args.build_swift_static_stdlib: |
| impl_args += ["--build-swift-static-stdlib"] |
| if args.build_swift_stdlib_unittest_extra: |
| impl_args += ["--build-swift-stdlib-unittest-extra"] |
| if args.build_swift_dynamic_sdk_overlay: |
| impl_args += ["--build-swift-dynamic-sdk-overlay"] |
| if args.build_swift_static_sdk_overlay: |
| impl_args += ["--build-swift-static-sdk-overlay"] |
| |
| if args.skip_build_linux: |
| impl_args += ["--skip-build-linux"] |
| if args.skip_build_freebsd: |
| impl_args += ["--skip-build-freebsd"] |
| if args.skip_build_cygwin: |
| impl_args += ["--skip-build-cygwin"] |
| if args.skip_build_osx: |
| impl_args += ["--skip-build-osx"] |
| if args.skip_build_ios_device: |
| impl_args += ["--skip-build-ios-device"] |
| if args.skip_build_ios_simulator: |
| impl_args += ["--skip-build-ios-simulator"] |
| if args.skip_build_tvos_device: |
| impl_args += ["--skip-build-tvos-device"] |
| if args.skip_build_tvos_simulator: |
| impl_args += ["--skip-build-tvos-simulator"] |
| if args.skip_build_watchos_device: |
| impl_args += ["--skip-build-watchos-device"] |
| if args.skip_build_watchos_simulator: |
| impl_args += ["--skip-build-watchos-simulator"] |
| if args.skip_build_android: |
| impl_args += ["--skip-build-android"] |
| |
| if not args.test and not args.long_test: |
| impl_args += ["--skip-test-swift"] |
| if not args.test: |
| impl_args += ["--skip-test-cmark", |
| "--skip-test-lldb", |
| "--skip-test-llbuild", |
| "--skip-test-swiftpm", |
| "--skip-test-xctest", |
| "--skip-test-foundation", |
| "--skip-test-libdispatch", |
| "--skip-test-playgroundlogger", |
| "--skip-test-playgroundsupport"] |
| if args.skip_test_linux: |
| impl_args += ["--skip-test-linux"] |
| if args.skip_test_freebsd: |
| impl_args += ["--skip-test-freebsd"] |
| if args.skip_test_cygwin: |
| impl_args += ["--skip-test-cygwin"] |
| if args.skip_test_osx: |
| impl_args += ["--skip-test-osx"] |
| if args.skip_test_ios_host: |
| impl_args += ["--skip-test-ios-host"] |
| if args.skip_test_ios_simulator: |
| impl_args += ["--skip-test-ios-simulator"] |
| if args.skip_test_tvos_host: |
| impl_args += ["--skip-test-tvos-host"] |
| if args.skip_test_tvos_simulator: |
| impl_args += ["--skip-test-tvos-simulator"] |
| if args.skip_test_watchos_host: |
| impl_args += ["--skip-test-watchos-host"] |
| if args.skip_test_watchos_simulator: |
| impl_args += ["--skip-test-watchos-simulator"] |
| if args.skip_test_android_host: |
| impl_args += ["--skip-test-android-host"] |
| if args.build_runtime_with_host_compiler: |
| impl_args += ["--build-runtime-with-host-compiler"] |
| if args.validation_test: |
| impl_args += ["--validation-test"] |
| if args.long_test: |
| impl_args += ["--long-test"] |
| if not args.benchmark: |
| impl_args += ["--skip-test-benchmarks"] |
| if not args.test_optimized: |
| impl_args += ["--skip-test-optimized"] |
| |
| if args.android: |
| impl_args += [ |
| "--android-ndk", args.android_ndk, |
| "--android-api-level", args.android_api_level, |
| "--android-ndk-gcc-version", |
| args.android_ndk_gcc_version, |
| "--android-icu-uc", args.android_icu_uc, |
| "--android-icu-uc-include", args.android_icu_uc_include, |
| "--android-icu-i18n", args.android_icu_i18n, |
| "--android-icu-i18n-include", args.android_icu_i18n_include, |
| ] |
| if args.android_deploy_device_path: |
| impl_args += [ |
| "--android-deploy-device-path", |
| args.android_deploy_device_path, |
| ] |
| |
| if platform.system() == 'Darwin': |
| impl_args += [ |
| "--toolchain-prefix", |
| swift_build_support.targets.darwin_toolchain_prefix( |
| args.install_prefix), |
| ] |
| |
| # If we have extra_swift_args, combine all of them together and then |
| # add them as one command. |
| if args.extra_swift_args: |
| impl_args += [ |
| "--extra-swift-args", |
| ";".join(args.extra_swift_args)] |
| |
| # If we have extra_cmake_options, combine all of them together and then |
| # add them as one command. |
| if args.extra_cmake_options: |
| impl_args += [ |
| "--extra-cmake-options=%s" % ' '.join( |
| pipes.quote(opt) for opt in args.extra_cmake_options) |
| ] |
| |
| if args.lto_type is not None: |
| impl_args += [ |
| "--llvm-enable-lto=%s" % args.lto_type, |
| "--swift-tools-enable-lto=%s" % args.lto_type |
| ] |
| if args.llvm_max_parallel_lto_link_jobs is not None: |
| impl_args += [ |
| "--llvm-num-parallel-lto-link-jobs=%s" % |
| min(args.llvm_max_parallel_lto_link_jobs, args.build_jobs) |
| ] |
| if args.swift_tools_max_parallel_lto_link_jobs is not None: |
| impl_args += [ |
| "--swift-tools-num-parallel-lto-link-jobs=%s" % |
| min(args.swift_tools_max_parallel_lto_link_jobs, |
| args.build_jobs) |
| ] |
| |
| impl_args += args.build_script_impl_args |
| |
| if args.dry_run: |
| impl_args += ["--dry-run"] |
| |
| if args.lit_args: |
| impl_args += ["--llvm-lit-args=%s" % args.lit_args] |
| |
| # Compute the set of host-specific variables, which we pass through to |
| # the build script via environment variables. |
| host_specific_variables = self.compute_host_specific_variables() |
| impl_env = {} |
| for (host_target, options) in host_specific_variables.items(): |
| for (name, value) in options.items(): |
| # We mangle into an environment variable we can easily evaluate |
| # from the `build-script-impl`. |
| impl_env["HOST_VARIABLE_{}__{}".format( |
| host_target.replace("-", "_"), name)] = value |
| |
| return (impl_env, impl_args) |
| |
| def compute_host_specific_variables(self): |
| """compute_host_specific_variables(args) -> dict |
| |
| Compute the host-specific options, organized as a dictionary keyed by |
| host of options. |
| """ |
| |
| args = self.args |
| |
| options = {} |
| for host_target in [args.host_target] + args.cross_compile_hosts: |
| # Compute the host specific configuration. |
| config = HostSpecificConfiguration(host_target, self) |
| |
| # Convert into `build-script-impl` style variables. |
| options[host_target] = { |
| "SWIFT_SDKS": " ".join(sorted( |
| config.sdks_to_configure)), |
| "SWIFT_STDLIB_TARGETS": " ".join( |
| config.swift_stdlib_build_targets), |
| "SWIFT_BENCHMARK_TARGETS": " ".join( |
| config.swift_benchmark_build_targets), |
| "SWIFT_RUN_BENCHMARK_TARGETS": " ".join( |
| config.swift_benchmark_run_targets), |
| "SWIFT_TEST_TARGETS": " ".join( |
| config.swift_test_run_targets), |
| } |
| |
| return options |
| |
| def compute_product_classes(self): |
| """compute_product_classes() -> list |
| |
| Compute the list of all Product classes used in this build. This list |
| is constructed in dependency order. |
| """ |
| |
| # FIXME: This is a weird division (returning a list of class objects), |
| # but it matches the existing structure of the `build-script-impl`. |
| |
| product_classes = [] |
| product_classes.append(products.CMark) |
| product_classes.append(products.LLVM) |
| product_classes.append(products.Swift) |
| if self.args.build_lldb: |
| product_classes.append(products.LLDB) |
| if self.args.build_llbuild: |
| product_classes.append(products.LLBuild) |
| if self.args.build_libdispatch: |
| product_classes.append(products.LibDispatch) |
| if self.args.build_foundation: |
| product_classes.append(products.Foundation) |
| if self.args.build_xctest: |
| product_classes.append(products.XCTest) |
| if self.args.build_swiftpm: |
| product_classes.append(products.SwiftPM) |
| return product_classes |
| |
| def execute(self): |
| """Execute the invocation with the configured arguments.""" |
| |
| # Convert to a build-script-impl invocation. |
| (impl_env, impl_args) = self.convert_to_impl_arguments() |
| |
| # If using the legacy implementation, delegate all behavior to |
| # `build-script-impl`. |
| if self.args.legacy_impl: |
| # Execute the underlying build script implementation. |
| call_without_sleeping([build_script_impl] + impl_args, |
| env=impl_env, echo=True) |
| return |
| |
| # Otherwise, we compute and execute the individual actions ourselves. |
| |
| def execute_one_impl_action(host=None, product_class=None, name=None): |
| if host is None: |
| assert (product_class is None and |
| name == "merged-hosts-lipo"), "invalid action" |
| action_name = name |
| elif product_class is None: |
| assert name == "package", "invalid action" |
| action_name = "{}-{}".format(host.name, name) |
| else: |
| assert name is not None, "invalid action" |
| action_name = "{}-{}-{}".format( |
| host.name, product_class.product_name(), name) |
| call_without_sleeping( |
| [build_script_impl] + impl_args + [ |
| "--only-execute", action_name], |
| env=impl_env, echo=self.args.verbose_build) |
| |
| # Compute the list of hosts to operate on. |
| all_host_names = [ |
| self.args.host_target] + self.args.cross_compile_hosts |
| all_hosts = [StdlibDeploymentTarget.get_target_for_name(name) |
| for name in all_host_names] |
| |
| # Compute the list of product classes to operate on. |
| # |
| # FIXME: This should really be per-host, but the current structure |
| # matches that of `build-script-impl`. |
| product_classes = self.compute_product_classes() |
| |
| # Execute each "pass". |
| |
| # Build... |
| for host_target in all_hosts: |
| # FIXME: We should only compute these once. |
| config = HostSpecificConfiguration(host_target.name, self) |
| print("Building the standard library for: {}".format( |
| " ".join(config.swift_stdlib_build_targets))) |
| if config.swift_test_run_targets and ( |
| self.args.test or self.args.long_test): |
| print("Running Swift tests for: {}".format( |
| " ".join(config.swift_test_run_targets))) |
| if config.swift_benchmark_run_targets and self.args.benchmark: |
| print("Running Swift benchmarks for: {}".format( |
| " ".join(config.swift_benchmark_run_targets))) |
| |
| for product_class in product_classes: |
| execute_one_impl_action(host_target, product_class, "build") |
| |
| # Test... |
| for host_target in all_hosts: |
| for product_class in product_classes: |
| execute_one_impl_action(host_target, product_class, "test") |
| |
| # Install... |
| for host_target in all_hosts: |
| for product_class in product_classes: |
| execute_one_impl_action(host_target, product_class, "install") |
| |
| # Package... |
| for host_target in all_hosts: |
| execute_one_impl_action(host_target, name="package") |
| |
| # Lipo... |
| execute_one_impl_action(name="merged-hosts-lipo") |
| |
| |
| # Main entry point for the preset mode. |
| def main_preset(): |
| parser = argparse.ArgumentParser( |
| formatter_class=argparse.RawDescriptionHelpFormatter, |
| description="""Builds Swift using a preset.""") |
| parser.add_argument( |
| "-n", "--dry-run", |
| help="print the commands that would be executed, but do not execute " |
| "them", |
| action="store_true", |
| default=False) |
| parser.add_argument( |
| "--preset-file", |
| help="load presets from the specified file", |
| metavar="PATH", |
| action="append", |
| dest="preset_file_names", |
| default=[]) |
| parser.add_argument( |
| "--preset", |
| help="use the specified option preset", |
| metavar="NAME") |
| parser.add_argument( |
| "--show-presets", |
| help="list all presets and exit", |
| action=arguments.action.optional_bool) |
| parser.add_argument( |
| "--distcc", |
| help="use distcc", |
| action=arguments.action.optional_bool) |
| parser.add_argument( |
| "preset_substitutions_raw", |
| help="'name=value' pairs that are substituted in the preset", |
| nargs="*", |
| metavar="SUBSTITUTION") |
| parser.add_argument( |
| "--expand-build-script-invocation", |
| help="Print the expanded build-script invocation generated " |
| "by the preset, but do not run the preset", |
| action=arguments.action.optional_bool) |
| args = parser.parse_args() |
| |
| if len(args.preset_file_names) == 0: |
| args.preset_file_names = [ |
| os.path.join(HOME, ".swift-build-presets"), |
| os.path.join( |
| SWIFT_SOURCE_ROOT, "swift", "utils", "build-presets.ini") |
| ] |
| |
| if args.show_presets: |
| for name in sorted(get_all_preset_names(args.preset_file_names), |
| key=str.lower): |
| print(name) |
| return 0 |
| |
| if not args.preset: |
| diagnostics.fatal("missing --preset option") |
| |
| args.preset_substitutions = {} |
| |
| for arg in args.preset_substitutions_raw: |
| name, value = arg.split("=", 1) |
| args.preset_substitutions[name] = value |
| |
| preset_args = get_preset_options( |
| args.preset_substitutions, args.preset_file_names, args.preset) |
| |
| build_script_args = [sys.argv[0]] |
| if args.dry_run: |
| build_script_args += ["--dry-run"] |
| build_script_args += preset_args |
| if args.distcc: |
| build_script_args += ["--distcc"] |
| |
| diagnostics.note( |
| "using preset '" + args.preset + "', which expands to \n\n" + |
| shell.quote_command(build_script_args) + "\n") |
| |
| if args.expand_build_script_invocation: |
| return 0 |
| |
| call_without_sleeping(build_script_args) |
| return 0 |
| |
| |
| # Main entry point for the normal mode. |
| def main_normal(): |
| parser = argparse.ArgumentParser( |
| formatter_class=argparse.RawDescriptionHelpFormatter, |
| usage=""" |
| %(prog)s [-h | --help] [OPTION ...] |
| %(prog)s --preset=NAME [SUBSTITUTION ...] |
| """, |
| description=""" |
| Use this tool to build, test, and prepare binary distribution archives of Swift |
| and related tools. |
| |
| Builds Swift (and, optionally, LLDB), incrementally, optionally |
| testing it thereafter. Different build configurations are maintained in |
| parallel.""", |
| epilog=""" |
| Using option presets: |
| |
| --preset-file=PATH load presets from the specified file |
| |
| --preset=NAME use the specified option preset |
| |
| The preset mode is mutually exclusive with other options. It is not |
| possible to add ad-hoc customizations to a preset. This is a deliberate |
| design decision. (Rationale: a preset is a certain important set of |
| options that we want to keep in a centralized location. If you need to |
| customize it, you should create another preset in a centralized location, |
| rather than scattering the knowledge about the build across the system.) |
| |
| Presets support substitutions for controlled customizations. Substitutions |
| are defined in the preset file. Values for substitutions are supplied |
| using the name=value syntax on the command line. |
| |
| |
| Any arguments not listed are forwarded directly to Swift's |
| 'build-script-impl'. See that script's help for details. |
| |
| Environment variables |
| --------------------- |
| |
| This script respects a few environment variables, should you |
| choose to set them: |
| |
| SWIFT_SOURCE_ROOT: a directory containing the source for LLVM, Clang, Swift. |
| If this script is located in a Swift |
| source directory, the location of SWIFT_SOURCE_ROOT will be |
| inferred if the variable is not set. |
| |
| 'build-script' expects the sources to be laid out in the following way: |
| |
| $SWIFT_SOURCE_ROOT/llvm |
| /clang |
| /swift |
| /lldb (optional) |
| /llbuild (optional) |
| /swiftpm (optional, requires llbuild) |
| /compiler-rt (optional) |
| /swift-corelibs-xctest (optional) |
| /swift-corelibs-foundation (optional) |
| /swift-corelibs-libdispatch (optional) |
| |
| SWIFT_BUILD_ROOT: a directory in which to create out-of-tree builds. |
| Defaults to "$SWIFT_SOURCE_ROOT/build/". |
| |
| Preparing to run this script |
| ---------------------------- |
| |
| See README.md for instructions on cloning Swift subprojects. |
| |
| If you intend to use the -l, -L, --lldb, or --lldb-debug options. |
| |
| That's it; you're ready to go! |
| |
| Examples |
| -------- |
| |
| Given the above layout of sources, the simplest invocation of 'build-script' is |
| just: |
| |
| [~/src/s]$ ./swift/utils/build-script |
| |
| This builds LLVM, Clang, Swift and Swift standard library in debug mode. |
| |
| All builds are incremental. To incrementally build changed files, repeat the |
| same 'build-script' command. |
| |
| Typical uses of 'build-script' |
| ------------------------------ |
| |
| To build everything with optimization without debug information: |
| |
| [~/src/s]$ ./swift/utils/build-script -R |
| |
| To run tests, add '-t': |
| |
| [~/src/s]$ ./swift/utils/build-script -R -t |
| |
| To run normal tests and validation tests, add '-T': |
| |
| [~/src/s]$ ./swift/utils/build-script -R -T |
| |
| To build LLVM+Clang with optimization without debug information, and a |
| debuggable Swift compiler: |
| |
| [~/src/s]$ ./swift/utils/build-script -R --debug-swift |
| |
| To build a debuggable Swift standard library: |
| |
| [~/src/s]$ ./swift/utils/build-script -R --debug-swift-stdlib |
| |
| iOS build targets are always configured and present, but are not built by |
| default. To build the standard library for OS X, iOS simulator and iOS device: |
| |
| [~/src/s]$ ./swift/utils/build-script -R -i |
| |
| To run OS X and iOS tests that don't require a device: |
| |
| [~/src/s]$ ./swift/utils/build-script -R -i -t |
| |
| To use 'make' instead of 'ninja', use '-m': |
| |
| [~/src/s]$ ./swift/utils/build-script -m -R |
| |
| To create Xcode projects that can build Swift, use '-x': |
| |
| [~/src/s]$ ./swift/utils/build-script -x -R |
| |
| Preset mode in build-script |
| --------------------------- |
| |
| All buildbots and automated environments use 'build-script' in *preset mode*. |
| In preset mode, the command line only specifies the preset name and allows |
| limited customization (extra output paths). The actual options come from |
| the selected preset in 'utils/build-presets.ini'. For example, to build like |
| the incremental buildbot, run: |
| |
| [~/src/s]$ ./swift/utils/build-script --preset=buildbot_incremental |
| |
| To build with AddressSanitizer: |
| |
| [~/src/s]$ ./swift/utils/build-script --preset=asan |
| |
| To build a root for Xcode XYZ, '/tmp/xcode-xyz-root.tar.gz': |
| |
| [~/src/s]$ ./swift/utils/build-script --preset=buildbot_BNI_internal_XYZ \\ |
| install_destdir="/tmp/install" |
| install_symroot="/tmp/symroot" |
| installable_package="/tmp/xcode-xyz-root.tar.gz" |
| |
| If you have your own favorite set of options, you can create your own, local, |
| preset. For example, let's create a preset called 'ds' (which stands for |
| Debug Swift): |
| |
| $ cat > ~/.swift-build-presets |
| [preset: ds] |
| release |
| debug-swift |
| debug-swift-stdlib |
| test |
| build-subdir=ds |
| |
| To use it, specify the '--preset=' argument: |
| |
| [~/src/s]$ ./swift/utils/build-script --preset=ds |
| ./swift/utils/build-script: using preset 'ds', which expands to |
| ./swift/utils/build-script --release --debug-swift --debug-swift-stdlib \ |
| --test |
| --build-subdir=ds -- |
| ... |
| |
| Philosophy |
| ---------- |
| |
| While you can invoke CMake directly to build Swift, this tool will save you |
| time by taking away the mechanical parts of the process, providing you controls |
| for the important options. |
| |
| For all automated build environments, this tool is regarded as *the* *only* way |
| to build Swift. This is not a technical limitation of the Swift build system. |
| It is a policy decision aimed at making the builds uniform across all |
| environments and easily reproducible by engineers who are not familiar with the |
| details of the setups of other systems or automated environments.""") |
| |
| parser.add_argument( |
| "-n", "--dry-run", |
| help="print the commands that would be executed, but do not execute " |
| "them", |
| action="store_true", |
| default=False) |
| parser.add_argument( |
| "--no-legacy-impl", dest="legacy_impl", |
| help="avoid legacy implementation", |
| action="store_false", |
| default=True) |
| |
| targets_group = parser.add_argument_group( |
| title="Host and cross-compilation targets") |
| targets_group.add_argument( |
| "--host-target", |
| help="The host target. LLVM, Clang, and Swift will be built for this " |
| "target. The built LLVM and Clang will be used to compile Swift " |
| "for the cross-compilation targets.", |
| default=StdlibDeploymentTarget.host_target().name) |
| targets_group.add_argument( |
| "--cross-compile-hosts", |
| help="A space separated list of targets to cross-compile host Swift " |
| "tools for. Can be used multiple times.", |
| action=arguments.action.concat, type=arguments.type.shell_split, |
| default=[]) |
| targets_group.add_argument( |
| "--stdlib-deployment-targets", |
| help="list of targets to compile or cross-compile the Swift standard " |
| "library for. %(default)s by default.", |
| action=arguments.action.concat, type=arguments.type.shell_split, |
| default=None) |
| targets_group.add_argument( |
| "--build-stdlib-deployment-targets", |
| help="A space-separated list that filters which of the configured " |
| "targets to build the Swift standard library for, or 'all'.", |
| type=arguments.type.shell_split, default=["all"]) |
| |
| projects_group = parser.add_argument_group( |
| title="Options to select projects") |
| projects_group.add_argument( |
| "-l", "--lldb", |
| help="build LLDB", |
| action="store_true", |
| dest="build_lldb") |
| projects_group.add_argument( |
| "-b", "--llbuild", |
| help="build llbuild", |
| action="store_true", |
| dest="build_llbuild") |
| projects_group.add_argument( |
| "-p", "--swiftpm", |
| help="build swiftpm", |
| action="store_true", |
| dest="build_swiftpm") |
| projects_group.add_argument( |
| "--xctest", |
| help="build xctest", |
| action=arguments.action.optional_bool, |
| dest="build_xctest") |
| projects_group.add_argument( |
| "--foundation", |
| help="build foundation", |
| action=arguments.action.optional_bool, |
| dest="build_foundation") |
| projects_group.add_argument( |
| "--libdispatch", |
| help="build libdispatch", |
| action=arguments.action.optional_bool, |
| dest="build_libdispatch") |
| projects_group.add_argument("--playgroundlogger", |
| help="build playgroundlogger", |
| action="store_true", |
| dest="build_playgroundlogger") |
| projects_group.add_argument("--playgroundsupport", |
| help="build PlaygroundSupport", |
| action="store_true", |
| dest="build_playgroundsupport") |
| projects_group.add_argument( |
| "--build-ninja", |
| help="build the Ninja tool", |
| action=arguments.action.optional_bool) |
| |
| extra_actions_group = parser.add_argument_group( |
| title="Extra actions to perform before or in addition to building") |
| extra_actions_group.add_argument( |
| "-c", "--clean", |
| help="do a clean build", |
| action="store_true") |
| extra_actions_group.add_argument( |
| "--export-compile-commands", |
| help="generate compilation databases in addition to building", |
| action=arguments.action.optional_bool) |
| extra_actions_group.add_argument( |
| "--symbols-package", |
| metavar="PATH", |
| help="if provided, an archive of the symbols directory will be " |
| "generated at this path") |
| |
| build_variant_group = parser.add_mutually_exclusive_group(required=False) |
| build_variant_group.add_argument( |
| "-d", "--debug", |
| help="build the Debug variant of everything (LLVM, Clang, Swift host " |
| "tools, target Swift standard libraries, LLDB (if enabled) " |
| "(default)", |
| action="store_const", |
| const="Debug", |
| dest="build_variant") |
| build_variant_group.add_argument( |
| "-r", "--release-debuginfo", |
| help="build the RelWithDebInfo variant of everything (default is " |
| "Debug)", |
| action="store_const", |
| const="RelWithDebInfo", |
| dest="build_variant") |
| build_variant_group.add_argument( |
| "-R", "--release", |
| help="build the Release variant of everything (default is Debug)", |
| action="store_const", |
| const="Release", |
| dest="build_variant") |
| |
| build_variant_override_group = parser.add_argument_group( |
| title="Override build variant for a specific project") |
| build_variant_override_group.add_argument( |
| "--debug-llvm", |
| help="build the Debug variant of LLVM", |
| action="store_const", |
| const="Debug", |
| dest="llvm_build_variant") |
| build_variant_override_group.add_argument( |
| "--debug-swift", |
| help="build the Debug variant of Swift host tools", |
| action="store_const", |
| const="Debug", |
| dest="swift_build_variant") |
| build_variant_override_group.add_argument( |
| "--debug-swift-stdlib", |
| help="build the Debug variant of the Swift standard library and SDK " |
| "overlay", |
| action="store_const", |
| const="Debug", |
| dest="swift_stdlib_build_variant") |
| build_variant_override_group.add_argument( |
| "--debug-lldb", |
| help="build the Debug variant of LLDB", |
| action="store_const", |
| const="Debug", |
| dest="lldb_build_variant") |
| build_variant_override_group.add_argument( |
| "--debug-cmark", |
| help="build the Debug variant of CommonMark", |
| action="store_const", |
| const="Debug", |
| dest="cmark_build_variant") |
| build_variant_override_group.add_argument( |
| "--debug-foundation", |
| help="build the Debug variant of Foundation", |
| action="store_const", |
| const="Debug", |
| dest="foundation_build_variant") |
| build_variant_override_group.add_argument( |
| "--debug-libdispatch", |
| help="build the Debug variant of libdispatch", |
| action="store_const", |
| const="Debug", |
| dest="libdispatch_build_variant") |
| |
| assertions_group = parser.add_mutually_exclusive_group(required=False) |
| assertions_group.add_argument( |
| "--assertions", |
| help="enable assertions in all projects", |
| action="store_const", |
| const=True, |
| dest="assertions") |
| assertions_group.add_argument( |
| "--no-assertions", |
| help="disable assertions in all projects", |
| action="store_const", |
| const=False, |
| dest="assertions") |
| |
| assertions_override_group = parser.add_argument_group( |
| title="Control assertions in a specific project") |
| assertions_override_group.add_argument( |
| "--cmark-assertions", |
| help="enable assertions in CommonMark", |
| action="store_const", |
| const=True, |
| dest="cmark_assertions") |
| assertions_override_group.add_argument( |
| "--llvm-assertions", |
| help="enable assertions in LLVM", |
| action="store_const", |
| const=True, |
| dest="llvm_assertions") |
| assertions_override_group.add_argument( |
| "--no-llvm-assertions", |
| help="disable assertions in LLVM", |
| action="store_const", |
| const=False, |
| dest="llvm_assertions") |
| assertions_override_group.add_argument( |
| "--swift-assertions", |
| help="enable assertions in Swift", |
| action="store_const", |
| const=True, |
| dest="swift_assertions") |
| assertions_override_group.add_argument( |
| "--no-swift-assertions", |
| help="disable assertions in Swift", |
| action="store_const", |
| const=False, |
| dest="swift_assertions") |
| assertions_override_group.add_argument( |
| "--swift-stdlib-assertions", |
| help="enable assertions in the Swift standard library", |
| action="store_const", |
| const=True, |
| dest="swift_stdlib_assertions") |
| assertions_override_group.add_argument( |
| "--no-swift-stdlib-assertions", |
| help="disable assertions in the Swift standard library", |
| action="store_const", |
| const=False, |
| dest="swift_stdlib_assertions") |
| assertions_override_group.add_argument( |
| "--lldb-assertions", |
| help="enable assertions in LLDB", |
| action="store_const", |
| const=True, |
| dest="lldb_assertions") |
| assertions_override_group.add_argument( |
| "--no-lldb-assertions", |
| help="disable assertions in LLDB", |
| action="store_const", |
| const=False, |
| dest="lldb_assertions") |
| |
| cmake_generator_group = parser.add_argument_group( |
| title="Select the CMake generator") |
| cmake_generator_group.add_argument( |
| "-x", "--xcode", |
| help="use CMake's Xcode generator (default is Ninja)", |
| action="store_const", |
| const="Xcode", |
| dest="cmake_generator") |
| cmake_generator_group.add_argument( |
| "-m", "--make", |
| help="use CMake's Makefile generator (default is Ninja)", |
| action="store_const", |
| const="Unix Makefiles", |
| dest="cmake_generator") |
| cmake_generator_group.add_argument( |
| "-e", "--eclipse", |
| help="use CMake's Eclipse generator (default is Ninja)", |
| action="store_const", |
| const="Eclipse CDT4 - Ninja", |
| dest="cmake_generator") |
| |
| run_tests_group = parser.add_argument_group( |
| title="Run tests") |
| |
| # NOTE: We can't merge -t and --test, because nargs='?' makes |
| # `-ti` to be treated as `-t=i`. |
| run_tests_group.add_argument( |
| "-t", |
| help="test Swift after building", |
| action="store_const", |
| const=True, |
| dest="test") |
| run_tests_group.add_argument( |
| "--test", |
| help="test Swift after building", |
| action=arguments.action.optional_bool) |
| run_tests_group.add_argument( |
| "-T", |
| help="run the validation test suite (implies --test)", |
| action="store_const", |
| const=True, |
| dest="validation_test") |
| run_tests_group.add_argument( |
| "--validation-test", |
| help="run the validation test suite (implies --test)", |
| action=arguments.action.optional_bool) |
| run_tests_group.add_argument( |
| "-o", |
| help="run the test suite in optimized mode too (implies --test)", |
| action="store_const", |
| const=True, |
| dest="test_optimized") |
| run_tests_group.add_argument( |
| "--test-optimized", |
| help="run the test suite in optimized mode too (implies --test)", |
| action=arguments.action.optional_bool) |
| run_tests_group.add_argument( |
| "--long-test", |
| help="run the long test suite", |
| action=arguments.action.optional_bool) |
| run_tests_group.add_argument( |
| "--host-test", |
| help="run executable tests on host devices (such as iOS or tvOS)", |
| action=arguments.action.optional_bool) |
| run_tests_group.add_argument( |
| "-B", "--benchmark", |
| help="run the Swift Benchmark Suite after building", |
| action="store_true") |
| run_tests_group.add_argument( |
| "--skip-test-osx", |
| help="skip testing Swift stdlibs for Mac OS X", |
| action=arguments.action.optional_bool) |
| run_tests_group.add_argument( |
| "--skip-test-linux", |
| help="skip testing Swift stdlibs for Linux", |
| action=arguments.action.optional_bool) |
| run_tests_group.add_argument( |
| "--skip-test-freebsd", |
| help="skip testing Swift stdlibs for FreeBSD", |
| action=arguments.action.optional_bool) |
| run_tests_group.add_argument( |
| "--skip-test-cygwin", |
| help="skip testing Swift stdlibs for Cygwin", |
| action=arguments.action.optional_bool) |
| parser.add_argument( |
| "--build-runtime-with-host-compiler", |
| help="Use the host compiler, not the self-built one to compile the " |
| "Swift runtime", |
| action=arguments.action.optional_bool) |
| |
| run_build_group = parser.add_argument_group( |
| title="Run build") |
| run_build_group.add_argument( |
| "--build-swift-dynamic-stdlib", |
| help="build dynamic variants of the Swift standard library", |
| action=arguments.action.optional_bool, |
| default=True) |
| run_build_group.add_argument( |
| "--build-swift-static-stdlib", |
| help="build static variants of the Swift standard library", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--build-swift-dynamic-sdk-overlay", |
| help="build dynamic variants of the Swift SDK overlay", |
| action=arguments.action.optional_bool, |
| default=True) |
| run_build_group.add_argument( |
| "--build-swift-static-sdk-overlay", |
| help="build static variants of the Swift SDK overlay", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--build-swift-stdlib-unittest-extra", |
| help="Build optional StdlibUnittest components", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "-S", "--skip-build", |
| help="generate build directory only without building", |
| action="store_true") |
| run_build_group.add_argument( |
| "--skip-build-linux", |
| help="skip building Swift stdlibs for Linux", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-freebsd", |
| help="skip building Swift stdlibs for FreeBSD", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-cygwin", |
| help="skip building Swift stdlibs for Cygwin", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-osx", |
| help="skip building Swift stdlibs for MacOSX", |
| action=arguments.action.optional_bool) |
| |
| run_build_group.add_argument( |
| "--skip-build-ios", |
| help="skip building Swift stdlibs for iOS", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-ios-device", |
| help="skip building Swift stdlibs for iOS devices " |
| "(i.e. build simulators only)", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-ios-simulator", |
| help="skip building Swift stdlibs for iOS simulator " |
| "(i.e. build devices only)", |
| action=arguments.action.optional_bool) |
| |
| run_build_group.add_argument( |
| "--skip-build-tvos", |
| help="skip building Swift stdlibs for tvOS", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-tvos-device", |
| help="skip building Swift stdlibs for tvOS devices " |
| "(i.e. build simulators only)", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-tvos-simulator", |
| help="skip building Swift stdlibs for tvOS simulator " |
| "(i.e. build devices only)", |
| action=arguments.action.optional_bool) |
| |
| run_build_group.add_argument( |
| "--skip-build-watchos", |
| help="skip building Swift stdlibs for watchOS", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-watchos-device", |
| help="skip building Swift stdlibs for watchOS devices " |
| "(i.e. build simulators only)", |
| action=arguments.action.optional_bool) |
| run_build_group.add_argument( |
| "--skip-build-watchos-simulator", |
| help="skip building Swift stdlibs for watchOS simulator " |
| "(i.e. build devices only)", |
| action=arguments.action.optional_bool) |
| |
| run_build_group.add_argument( |
| "--skip-build-android", |
| help="skip building Swift stdlibs for Android", |
| action=arguments.action.optional_bool) |
| |
| run_build_group.add_argument( |
| "--skip-build-benchmarks", |
| help="skip building Swift Benchmark Suite", |
| action=arguments.action.optional_bool) |
| |
| skip_test_group = parser.add_argument_group( |
| title="Skip testing specified targets") |
| skip_test_group.add_argument( |
| "--skip-test-ios", |
| help="skip testing all iOS targets. Equivalent to specifying both " |
| "--skip-test-ios-simulator and --skip-test-ios-host", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-ios-simulator", |
| help="skip testing iOS simulator targets", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-ios-host", |
| help="skip testing iOS device targets on the host machine (the phone " |
| "itself)", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-tvos", |
| help="skip testing all tvOS targets. Equivalent to specifying both " |
| "--skip-test-tvos-simulator and --skip-test-tvos-host", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-tvos-simulator", |
| help="skip testing tvOS simulator targets", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-tvos-host", |
| help="skip testing tvOS device targets on the host machine (the TV " |
| "itself)", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-watchos", |
| help="skip testing all tvOS targets. Equivalent to specifying both " |
| "--skip-test-watchos-simulator and --skip-test-watchos-host", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-watchos-simulator", |
| help="skip testing watchOS simulator targets", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-watchos-host", |
| help="skip testing watchOS device targets on the host machine (the " |
| "watch itself)", |
| action=arguments.action.optional_bool) |
| skip_test_group.add_argument( |
| "--skip-test-android-host", |
| help="skip testing Android device targets on the host machine (the " |
| "phone itself)", |
| action=arguments.action.optional_bool) |
| |
| parser.add_argument( |
| "-i", "--ios", |
| help="also build for iOS, but disallow tests that require an iOS " |
| "device", |
| action="store_true") |
| parser.add_argument( |
| "--skip-ios", |
| help="set to skip everything iOS-related", |
| dest="ios", |
| action="store_false") |
| |
| parser.add_argument( |
| "--tvos", |
| help="also build for tvOS, but disallow tests that require a tvos " |
| "device", |
| action=arguments.action.optional_bool) |
| parser.add_argument( |
| "--skip-tvos", |
| help="set to skip everything tvOS-related", |
| dest="tvos", |
| action="store_false") |
| |
| parser.add_argument( |
| "--watchos", |
| help="also build for watchOS, but disallow tests that require an " |
| "watchOS device", |
| action=arguments.action.optional_bool) |
| parser.add_argument( |
| "--skip-watchos", |
| help="set to skip everything watchOS-related", |
| dest="watchos", |
| action="store_false") |
| |
| parser.add_argument( |
| "--android", |
| help="also build for Android", |
| action=arguments.action.optional_bool) |
| |
| parser.add_argument( |
| "--swift-analyze-code-coverage", |
| help="enable code coverage analysis in Swift (false, not-merged, " |
| "merged).", |
| choices=["false", "not-merged", "merged"], |
| default="false", # so CMake can see the inert mode as a false value |
| dest="swift_analyze_code_coverage") |
| |
| parser.add_argument( |
| "--build-subdir", |
| help="name of the directory under $SWIFT_BUILD_ROOT where the build " |
| "products will be placed", |
| metavar="PATH") |
| parser.add_argument( |
| "--install-prefix", |
| help="The installation prefix. This is where built Swift products " |
| "(like bin, lib, and include) will be installed.", |
| metavar="PATH", |
| default=swift_build_support.targets.install_prefix()) |
| parser.add_argument( |
| "--install-symroot", |
| help="the path to install debug symbols into", |
| metavar="PATH") |
| |
| parser.add_argument( |
| "-j", "--jobs", |
| help="the number of parallel build jobs to use", |
| type=int, |
| dest="build_jobs", |
| default=multiprocessing.cpu_count()) |
| |
| parser.add_argument( |
| "--darwin-xcrun-toolchain", |
| help="the name of the toolchain to use on Darwin", |
| default="default") |
| parser.add_argument( |
| "--cmake", |
| help="the path to a CMake executable that will be used to build " |
| "Swift", |
| type=arguments.type.executable, |
| metavar="PATH") |
| parser.add_argument( |
| "--show-sdks", |
| help="print installed Xcode and SDK versions", |
| action=arguments.action.optional_bool) |
| |
| parser.add_argument( |
| "--extra-swift-args", |
| help="Pass through extra flags to swift in the form of a cmake list " |
| "'module_regexp;flag'. Can be called multiple times to add " |
| "multiple such module_regexp flag pairs. All semicolons in flags " |
| "must be escaped with a '\\'", |
| action="append", dest="extra_swift_args", default=[]) |
| |
| android_group = parser.add_argument_group( |
| title="Build settings for Android") |
| android_group.add_argument( |
| "--android-ndk", |
| help="An absolute path to the NDK that will be used as a libc " |
| "implementation for Android builds", |
| metavar="PATH") |
| android_group.add_argument( |
| "--android-api-level", |
| help="The Android API level to target when building for Android. " |
| "Currently only 21 or above is supported", |
| default="21") |
| android_group.add_argument( |
| "--android-ndk-gcc-version", |
| help="The GCC version to use when building for Android. Currently " |
| "only 4.9 is supported. %(default)s is also the default value. " |
| "This option may be used when experimenting with versions " |
| "of the Android NDK not officially supported by Swift", |
| choices=["4.8", "4.9"], |
| default="4.9") |
| android_group.add_argument( |
| "--android-icu-uc", |
| help="Path to a directory containing libicuuc.so", |
| metavar="PATH") |
| android_group.add_argument( |
| "--android-icu-uc-include", |
| help="Path to a directory containing headers for libicuuc", |
| metavar="PATH") |
| android_group.add_argument( |
| "--android-icu-i18n", |
| help="Path to a directory containing libicui18n.so", |
| metavar="PATH") |
| android_group.add_argument( |
| "--android-icu-i18n-include", |
| help="Path to a directory containing headers libicui18n", |
| metavar="PATH") |
| android_group.add_argument( |
| "--android-deploy-device-path", |
| help="Path on an Android device to which built Swift stdlib products " |
| "will be deployed. If running host tests, specify the '{}' " |
| "directory.".format(adb.commands.DEVICE_TEMP_DIR), |
| default=adb.commands.DEVICE_TEMP_DIR, |
| metavar="PATH") |
| |
| parser.add_argument( |
| "--host-cc", |
| help="the absolute path to CC, the 'clang' compiler for the host " |
| "platform. Default is auto detected.", |
| type=arguments.type.executable, |
| metavar="PATH") |
| parser.add_argument( |
| "--host-cxx", |
| help="the absolute path to CXX, the 'clang++' compiler for the host " |
| "platform. Default is auto detected.", |
| type=arguments.type.executable, |
| metavar="PATH") |
| parser.add_argument( |
| "--distcc", |
| help="use distcc in pump mode", |
| action=arguments.action.optional_bool) |
| parser.add_argument( |
| "--enable-asan", |
| help="enable Address Sanitizer", |
| action=arguments.action.optional_bool) |
| parser.add_argument( |
| "--enable-ubsan", |
| help="enable Undefined Behavior Sanitizer", |
| action=arguments.action.optional_bool) |
| parser.add_argument( |
| "--clang-compiler-version", |
| help="string that indicates a compiler version for Clang", |
| type=arguments.type.clang_compiler_version, |
| metavar="MAJOR.MINOR.PATCH") |
| |
| parser.add_argument( |
| "--darwin-deployment-version-osx", |
| help="minimum deployment target version for OS X", |
| metavar="MAJOR.MINOR", |
| default="10.9") |
| parser.add_argument( |
| "--darwin-deployment-version-ios", |
| help="minimum deployment target version for iOS", |
| metavar="MAJOR.MINOR", |
| default="7.0") |
| parser.add_argument( |
| "--darwin-deployment-version-tvos", |
| help="minimum deployment target version for tvOS", |
| metavar="MAJOR.MINOR", |
| default="9.0") |
| parser.add_argument( |
| "--darwin-deployment-version-watchos", |
| help="minimum deployment target version for watchOS", |
| metavar="MAJOR.MINOR", |
| default="2.0") |
| |
| parser.add_argument( |
| "--extra-cmake-options", |
| help="Pass through extra options to CMake in the form of comma " |
| "separated options '-DCMAKE_VAR1=YES,-DCMAKE_VAR2=/tmp'. Can be " |
| "called multiple times to add multiple such options.", |
| action=arguments.action.concat, |
| type=arguments.type.shell_split, |
| default=[]) |
| |
| parser.add_argument( |
| "--build-args", |
| help="arguments to the build tool. This would be prepended to the " |
| "default argument that is '-j8' when CMake generator is " |
| "\"Ninja\".", |
| type=arguments.type.shell_split, |
| default=[]) |
| |
| parser.add_argument( |
| "--verbose-build", |
| help="print the commands executed during the build", |
| action=arguments.action.optional_bool) |
| |
| parser.add_argument( |
| "--lto", |
| help="use lto optimization on llvm/swift tools. This does not " |
| "imply using lto on the swift standard library or runtime. " |
| "Options: thin, full. If no optional arg is provided, full is " |
| "chosen by default", |
| metavar="LTO_TYPE", |
| nargs='?', |
| choices=['thin', 'full'], |
| default=None, |
| const='full', |
| dest='lto_type') |
| |
| default_max_lto_link_job_counts = host.max_lto_link_job_counts() |
| parser.add_argument( |
| "--llvm-max-parallel-lto-link-jobs", |
| help="the maximum number of parallel link jobs to use when compiling " |
| "llvm", |
| metavar="COUNT", |
| default=default_max_lto_link_job_counts['llvm']) |
| |
| parser.add_argument( |
| "--swift-tools-max-parallel-lto-link-jobs", |
| help="the maximum number of parallel link jobs to use when compiling " |
| "swift tools.", |
| metavar="COUNT", |
| default=default_max_lto_link_job_counts['swift']) |
| |
| parser.add_argument( |
| # Explicitly unavailable options here. |
| "--build-jobs", |
| "--common-cmake-options", |
| "--only-execute", |
| "--skip-test-optimized", |
| action=arguments.action.unavailable) |
| |
| parser.add_argument( |
| "--lit-args", |
| help="lit args to use when testing", |
| metavar="LITARGS", |
| default="-sv") |
| |
| args = migration.parse_args(parser, sys.argv[1:]) |
| |
| if args.build_script_impl_args: |
| # If we received any impl args, check if `build-script-impl` would |
| # accept them or not before any further processing. |
| try: |
| migration.check_impl_args(build_script_impl, |
| args.build_script_impl_args) |
| except ValueError as e: |
| parser.print_usage(sys.stderr) |
| print(e, file=sys.stderr) |
| sys.exit(2) # 2 is the same as `argparse` error exit code. |
| |
| if '--check-args-only' in args.build_script_impl_args: |
| return 0 |
| |
| shell.dry_run = args.dry_run |
| |
| # Prepare and validate toolchain |
| toolchain = host_toolchain(xcrun_toolchain=args.darwin_xcrun_toolchain) |
| |
| if args.host_cc is not None: |
| toolchain.cc = args.host_cc |
| if args.host_cxx is not None: |
| toolchain.cxx = args.host_cxx |
| if args.cmake is not None: |
| toolchain.cmake = args.cmake |
| |
| # Preprocess the arguments to apply defaults. |
| BuildScriptInvocation.apply_default_arguments(toolchain, args) |
| |
| # Validate the arguments. |
| BuildScriptInvocation.validate_arguments(toolchain, args) |
| |
| # Create the build script invocation. |
| invocation = BuildScriptInvocation(toolchain, args) |
| |
| # Sanitize the runtime environment. |
| invocation.initialize_runtime_environment() |
| |
| # Show SDKs, if requested. |
| if args.show_sdks: |
| swift_build_support.debug.print_xcodebuild_versions() |
| |
| # Clean build directory if requested. |
| if args.clean: |
| shell.rmtree(invocation.workspace.build_root) |
| |
| # Create build directory. |
| shell.makedirs(invocation.workspace.build_root) |
| |
| # Build ninja if required, which will update the toolchain. |
| if args.build_ninja: |
| invocation.build_ninja() |
| |
| # Execute the underlying build script implementation. |
| invocation.execute() |
| |
| if args.symbols_package: |
| print('--- Creating symbols package ---') |
| print('-- Package file: {} --'.format(args.symbols_package)) |
| |
| if platform.system() == 'Darwin': |
| prefix = swift_build_support.targets.darwin_toolchain_prefix( |
| args.install_prefix) |
| else: |
| prefix = args.install_prefix |
| |
| # As a security measure, `tar` normally strips leading '/' from paths |
| # it is archiving. To stay safe, we change working directories, then |
| # run `tar` without the leading '/' (we remove it ourselves to keep |
| # `tar` from emitting a warning). |
| with shell.pushd(args.install_symroot): |
| swift_build_support.tar.tar(source=prefix.lstrip('/'), |
| destination=args.symbols_package) |
| |
| return 0 |
| |
| |
| def main(): |
| if not SWIFT_SOURCE_ROOT: |
| diagnostics.fatal( |
| "could not infer source root directory " + |
| "(forgot to set $SWIFT_SOURCE_ROOT environment variable?)") |
| |
| if not os.path.isdir(SWIFT_SOURCE_ROOT): |
| diagnostics.fatal( |
| "source root directory \'" + SWIFT_SOURCE_ROOT + |
| "\' does not exist " + |
| "(forgot to set $SWIFT_SOURCE_ROOT environment variable?)") |
| |
| # Determine if we are invoked in the preset mode and dispatch accordingly. |
| if any([(opt.startswith("--preset") or opt == "--show-presets") |
| for opt in sys.argv[1:]]): |
| return main_preset() |
| else: |
| return main_normal() |
| |
| |
| if __name__ == "__main__": |
| sys.exit(main()) |