Skip to content

RFC: Add --@bazel_build_rules_swift//swift:static_stdlib #706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions swift/internal/compiling.bzl
Original file line number Diff line number Diff line change
@@ -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,
4 changes: 4 additions & 0 deletions swift/internal/feature_names.bzl
Original file line number Diff line number Diff line change
@@ -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.
39 changes: 29 additions & 10 deletions swift/internal/swift_toolchain.bzl
Original file line number Diff line number Diff line change
@@ -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
5 changes: 4 additions & 1 deletion tools/worker/work_processor.cc
Original file line number Diff line number Diff line change
@@ -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;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not happy with this. This appears to be a bug in swiftc which should invalidate previous cache when this parameter changed. It is perfectly capable of doing incremental build for static stdlib build otherwise.

If I have a way to invalidate the current persistent worker and restart when swift.static_stdlib enabled / disabled, that would be ideal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh interesting, can you reproduce this outside of bazel? Wondering if we should report something. Are you testing with 5.5 as well?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I am on 5.5.1. Would need to dig this.

} 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) {