def build_ninja(self): if not os.path.exists(self.workspace.source_dir("ninja")): fatal_error("can't find source directory for ninja " "(tried %s)" % (self.workspace.source_dir("ninja"))) ninja_build = products.Ninja.new_builder( args=self.args, toolchain=self.toolchain, workspace=self.workspace, host=StdlibDeploymentTarget.get_target_for_name( self.args.host_target)) ninja_build.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={}".format(" ".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, "--libicu-build-type", args.libicu_build_variant, "--xctest-build-type", args.build_variant, "--llbuild-build-type", args.build_variant, "--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(), "--llbuild-enable-assertions", str(args.llbuild_assertions).lower(), "--lldb-assertions", str(args.lldb_assertions).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()), "--dsymutil-jobs", str(args.dsymutil_jobs), ] # Compute any product specific cmake arguments. # # NOTE: The sum(list(...)) is b/c compute_product_pipelines returns a # tuple of lists of which the first is the build-script-impl products # and the second is the non-build-script-impl-products. It guarantees # that when we concatenate these two lists together we get a valid # dependency graph. for product_class in sum(list(self.compute_product_pipelines()[0]), []): if not product_class.is_build_script_impl_product(): continue product_name = product_class.product_name() product_source_name = product_class.product_source_name() source_dir = self.workspace.source_dir(product_source_name) if not os.path.exists(source_dir): fatal_error("can't find source directory for %s " "(tried %s)" % (product_name, source_dir)) product = product_class( args=args, toolchain=self.toolchain, source_dir=source_dir, # FIXME: This is incorrect since it always assumes the host # target I think? build_dir=self.workspace.build_dir(args.host_target, product_name)) cmake_opts = product.cmake_options # FIXME: We should be using pipes.quote here but we run into issues # with build-script-impl/cmake not being happy with all of the # extra "'" in the strings. To fix this easily, we really need to # just invoke cmake from build-script directly rather than futzing # with build-script-impl. This makes even more sense since there # really isn't a security issue here. if cmake_opts: impl_args += [ "--{}-cmake-options={}".format(product_name, ' '.join(cmake_opts)) ] 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 args.test_paths: impl_args += ["--test-paths", " ".join(args.test_paths)] if toolchain.ninja: impl_args += ["--ninja-bin=%s" % toolchain.ninja] if args.distcc: impl_args += [ "--distcc", "--distcc-pump=%s" % toolchain.distcc_pump ] if args.sccache: args.cmake_c_launcher = toolchain.sccache args.cmake_cxx_launcher = toolchain.sccache # *NOTE* We use normal cmake to pass through tsan/ubsan options. We do # NOT pass them to build-script-impl. if args.enable_asan: impl_args += ["--enable-asan"] # If we are on linux, disable leak detection when running ASAN. We # have a separate bot that checks for leaks. if platform.system() == 'Linux': os.environ['ASAN_OPTIONS'] = 'detect_leaks=0' if args.enable_ubsan: impl_args += ["--enable-ubsan"] # If we have lsan, we need to export our suppression list. The actual # passing in of the LSAN flag is done via the normal cmake method. We # do not pass the flag to build-script-impl. if args.enable_lsan: supp_file = os.path.join(SWIFT_SOURCE_ROOT, SWIFT_REPO_NAME, "utils", "lsan_leaks_suppression_list.txt") os.environ['LSAN_OPTIONS'] = 'suppressions={}'.format(supp_file) if args.verbose_build: impl_args += ["--verbose-build"] if args.install_symroot: impl_args += [ "--install-symroot", os.path.abspath(args.install_symroot) ] if args.install_destdir: impl_args += [ "--install-destdir", os.path.abspath(args.install_destdir) ] if args.skip_build: impl_args += ["--skip-build"] if not args.build_benchmarks: impl_args += ["--skip-build-benchmarks"] if args.swift_disable_dead_stripping: args.extra_cmake_options.append( '-DSWIFT_DISABLE_DEAD_STRIPPING:BOOL=TRUE') if args.build_backdeployconcurrency: args.extra_cmake_options.append( '-DSWIFT_BACK_DEPLOY_CONCURRENCY:BOOL=TRUE') # Then add subproject install flags that either skip building them /or/ # if we are going to build them and install_all is set, we also install # them. conditional_subproject_configs = [ (args.build_cmark, "cmark"), (args.build_llvm, "llvm"), (args.build_swift, "swift"), (args.build_foundation, "foundation"), (args.build_xctest, "xctest"), (args.build_lldb, "lldb"), (args.build_llbuild, "llbuild"), (args.build_libcxx, "libcxx"), (args.build_libdispatch, "libdispatch"), (args.build_libicu, "libicu") ] for (should_build, string_name) in conditional_subproject_configs: if not should_build and not self.args.infer_dependencies: impl_args += ["--skip-build-{}".format(string_name)] elif self.install_all: impl_args += ["--install-{}".format(string_name)] 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 not args.build_android: impl_args += ["--skip-build-android"] if not args.build_clang_tools_extra: impl_args += ["--skip-build-clang-tools-extra"] if not args.test and not args.long_test and not args.stress_test: impl_args += ["--skip-test-swift"] if not args.test: impl_args += [ "--skip-test-cmark", "--skip-test-lldb", "--skip-test-llbuild", "--skip-test-xctest", "--skip-test-foundation", "--skip-test-libdispatch", "--skip-test-libicu", ] 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 args.stress_test: impl_args += ["--stress-test"] if args.skip_local_build: impl_args += ["--skip-local-build"] if args.only_executable_test: impl_args += ["--only-executable-test"] if not args.benchmark: impl_args += ["--skip-test-benchmarks"] if args.build_libparser_only: impl_args += ["--build-libparser-only"] if args.android: impl_args += [ "--android-arch", args.android_arch, "--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, "--android-icu-data", args.android_icu_data, ] # If building natively on an Android host, only pass the API level. if StdlibDeploymentTarget.Android.contains( StdlibDeploymentTarget.host_target().name): impl_args += ["--android-api-level", args.android_api_level] 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", targets.darwin_toolchain_prefix(args.install_prefix), "--host-lipo", toolchain.lipo, ] # Isolate build from the system; Darwin toolchains build against SDKs. # For additional isolation, disable pkg-config. Homebrew's pkg-config # prioritizes CommandLineTools paths, resulting in compile errors. args.extra_cmake_options += [ '-DCMAKE_IGNORE_PATH=/usr/lib;/usr/local/lib;/lib', '-DPKG_CONFIG_EXECUTABLE=/usr/bin/false', ] if toolchain.libtool is not None: impl_args += [ "--host-libtool", toolchain.libtool, ] if args.native_clang_tools_path is not None: impl_args += [ "--native-clang-tools-path=%s" % args.native_clang_tools_path ] if args.native_llvm_tools_path is not None: impl_args += [ "--native-llvm-tools-path=%s" % args.native_llvm_tools_path ] if args.native_swift_tools_path is not None: impl_args += [ "--native-swift-tools-path=%s" % args.native_swift_tools_path ] # 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=%s" % ';'.join(args.extra_swift_args) ] # Enable macCatalyst if args.maccatalyst: (args.extra_cmake_options.append( '-DSWIFT_ENABLE_MACCATALYST:BOOL=TRUE')) if args.maccatalyst_ios_tests: impl_args += ["--darwin-test-maccatalyst-ios-like=1"] # 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.reconfigure: impl_args += ["--reconfigure"] if args.clang_profile_instr_use: impl_args += [ "--clang-profile-instr-use=%s" % os.path.abspath(args.clang_profile_instr_use) ] if args.lit_args: impl_args += ["--llvm-lit-args=%s" % args.lit_args] if args.coverage_db: impl_args += [ "--coverage-db=%s" % os.path.abspath(args.coverage_db) ] if args.llvm_install_components: impl_args += [ "--llvm-install-components=%s" % args.llvm_install_components ] if not args.clean_llbuild: impl_args += ["--skip-clean-llbuild"] if args.llvm_ninja_targets: impl_args += [ "--llvm-ninja-targets=%s" % ' '.join(args.llvm_ninja_targets) ] if args.llvm_ninja_targets_for_cross_compile_hosts: impl_args += [ "--llvm-ninja-targets-for-cross-compile-hosts=%s" % ' '.join(args.llvm_ninja_targets_for_cross_compile_hosts) ] if args.darwin_symroot_path_filters: impl_args += [ "--darwin_symroot_path_filters=%s" % ' '.join(args.darwin_symroot_path_filters) ] # 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)