From 15698bf40741133317d3f4f8327f30a82fe68089 Mon Sep 17 00:00:00 2001 From: Liu Liu Date: Wed, 27 Oct 2021 21:29:18 -0400 Subject: [PATCH] RFC: Add --features=swift.static_stdlib This PR added the ability to compile Swift binary with stdlib in Linux. It added `-static-stdlib` to `swiftc` invocation and added `static-stdlib-args.lnk` to linker flag. However, there is an issue with Bazel cache: ``` bazel build examples:ddpg --features=swift.static_stdlib ``` It compiles. Then: ``` bazel build examples:ddpg ``` See error: ``` /usr/bin/ld: cannot find -lDispatchStubs /usr/bin/ld: cannot find -lCoreFoundation ``` It seems reused the previous autolink extract results. Disable incremental build when -static-stdlib is presented. --- swift/internal/compiling.bzl | 11 +++++++++ swift/internal/feature_names.bzl | 4 +++ swift/internal/swift_toolchain.bzl | 39 ++++++++++++++++++++++-------- tools/worker/work_processor.cc | 5 +++- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/swift/internal/compiling.bzl b/swift/internal/compiling.bzl index 807355415..4eae0aa5a 100644 --- a/swift/internal/compiling.bzl +++ b/swift/internal/compiling.bzl @@ -66,6 +66,7 @@ load( "SWIFT_FEATURE_USE_OLD_DRIVER", "SWIFT_FEATURE_USE_PCH_OUTPUT_DIR", "SWIFT_FEATURE_VFSOVERLAY", + "SWIFT_FEATURE_STATIC_STDLIB", "SWIFT_FEATURE__NUM_THREADS_0_IN_SWIFTCOPTS", "SWIFT_FEATURE__WMO_IN_SWIFTCOPTS", ) @@ -1037,6 +1038,16 @@ def compile_action_configs( ], configurators = [_conditional_compilation_flag_configurator], ), + + # Enable the built modules to reference static Swift standard libraries. + swift_toolchain_config.action_config( + actions = [ + swift_action_names.COMPILE, + swift_action_names.DERIVE_FILES, + ], + configurators = [swift_toolchain_config.add_arg("-static-stdlib")], + features = [SWIFT_FEATURE_STATIC_STDLIB], + ), ] # NOTE: The positions of these action configs in the list are important, diff --git a/swift/internal/feature_names.bzl b/swift/internal/feature_names.bzl index 534467f13..95578287d 100644 --- a/swift/internal/feature_names.bzl +++ b/swift/internal/feature_names.bzl @@ -291,6 +291,10 @@ SWIFT_FEATURE_ENABLE_SKIP_FUNCTION_BODIES = "swift.skip_function_bodies_for_deri # swift.coverage_prefix_map also remap the path in coverage data. SWIFT_FEATURE_REMAP_XCODE_PATH = "swift.remap_xcode_path" +# If enabled the built binary will statically link Swift standard libraries. +# This requires Swift 5.3.1 +SWIFT_FEATURE_STATIC_STDLIB = "swift.static_stdlib" + # A private feature that is set by the toolchain if a flag enabling WMO was # passed on the command line using `--swiftcopt`. Users should never manually # enable, disable, or query this feature. diff --git a/swift/internal/swift_toolchain.bzl b/swift/internal/swift_toolchain.bzl index 675e46f9a..5aa30123c 100644 --- a/swift/internal/swift_toolchain.bzl +++ b/swift/internal/swift_toolchain.bzl @@ -34,6 +34,7 @@ load( "SWIFT_FEATURE_USE_AUTOLINK_EXTRACT", "SWIFT_FEATURE_USE_MODULE_WRAP", "SWIFT_FEATURE_USE_RESPONSE_FILES", + "SWIFT_FEATURE_STATIC_STDLIB", ) load(":features.bzl", "features_for_build_modes") load( @@ -202,7 +203,8 @@ def _swift_unix_linkopts_cc_info( cpu, os, toolchain_label, - toolchain_root): + toolchain_root, + static_stdlib): """Returns a `CcInfo` containing flags that should be passed to the linker. The provider returned by this function will be used as an implicit @@ -216,27 +218,43 @@ def _swift_unix_linkopts_cc_info( toolchain_label: The label of the Swift toolchain that will act as the owner of the linker input propagating the flags. toolchain_root: The toolchain's root directory. + static_stdlib: Whether to statically link Swift standard libraries. Returns: A `CcInfo` provider that will provide linker flags to binaries that depend on Swift targets. """ - # TODO(#8): Support statically linking the Swift runtime. - platform_lib_dir = "{toolchain_root}/lib/swift/{os}".format( - os = os, - toolchain_root = toolchain_root, - ) + if static_stdlib: + platform_lib_dir = "{toolchain_root}/lib/swift_static/{os}".format( + os = os, + toolchain_root = toolchain_root, + ) + else: + platform_lib_dir = "{toolchain_root}/lib/swift/{os}".format( + os = os, + toolchain_root = toolchain_root, + ) + + linkopts = [ + "-pie", + "-L{}".format(platform_lib_dir), + "-Wl,-rpath,{}".format(platform_lib_dir), + ] + + # Appending generic linker args from Swift runtime. + if static_stdlib: + static_stdlib_args = "{platform_lib_dir}/static-stdlib-args.lnk".format( + platform_lib_dir = platform_lib_dir, + ) + linkopts.append("@{}".format(static_stdlib_args)) runtime_object_path = "{platform_lib_dir}/{cpu}/swiftrt.o".format( cpu = cpu, platform_lib_dir = platform_lib_dir, ) - linkopts = [ - "-pie", - "-L{}".format(platform_lib_dir), - "-Wl,-rpath,{}".format(platform_lib_dir), + linkopts += [ "-lm", "-lstdc++", "-lrt", @@ -273,6 +291,7 @@ def _swift_toolchain_impl(ctx): ctx.attr.os, ctx.label, toolchain_root, + SWIFT_FEATURE_STATIC_STDLIB in ctx.features, ) # Combine build mode features, autoconfigured features, and required diff --git a/tools/worker/work_processor.cc b/tools/worker/work_processor.cc index d1776f507..ee4883f20 100644 --- a/tools/worker/work_processor.cc +++ b/tools/worker/work_processor.cc @@ -81,6 +81,7 @@ void WorkProcessor::ProcessWorkRequest( std::string output_file_map_path; std::string emit_module_path; bool is_wmo = false; + bool is_static_stdlib = false; bool is_dump_ast = false; std::string prev_arg; @@ -97,6 +98,8 @@ void WorkProcessor::ProcessWorkRequest( arg.clear(); } else if (prev_arg == "-emit-module-path") { emit_module_path = arg; + } else if (arg == "-static-stdlib") { + is_static_stdlib = true; } else if (ArgumentEnablesWMO(arg)) { is_wmo = true; } @@ -108,7 +111,7 @@ void WorkProcessor::ProcessWorkRequest( prev_arg = original_arg; } - bool is_incremental = !is_wmo && !is_dump_ast; + bool is_incremental = !is_wmo && !is_dump_ast && !is_static_stdlib; if (!output_file_map_path.empty()) { if (is_incremental) {