+ Swift, compiled to WebAssembly
+ A swift_binary(linkshared = True) reactor module
+ built with rules_swift — instantiated and driven from JavaScript:
+ loading…
+ The text above was produced by the Swift Greeter
+ library running in WebAssembly, read out of the module's linear memory.
+
+
+
+
diff --git a/examples/cross_compilation/wasm/web/verify.mjs b/examples/cross_compilation/wasm/web/verify.mjs
new file mode 100644
index 000000000..c2551888e
--- /dev/null
+++ b/examples/cross_compilation/wasm/web/verify.mjs
@@ -0,0 +1,58 @@
+// Headless end-to-end check of the WebAssembly reactor, mirroring index.html:
+// instantiate with a minimal WASI shim, run `_initialize`, then read the
+// greeting that Swift writes into linear memory. Exits non-zero on mismatch.
+//
+// node examples/cross_compilation/wasm/web/verify.mjs \
+// bazel-bin/examples/cross_compilation/wasm/Reactor.wasm
+//
+// (index.html does exactly this in a browser.)
+
+import { readFileSync } from "node:fs";
+import { webcrypto as crypto } from "node:crypto";
+
+const wasmPath = process.argv[2] ?? "bazel-bin/examples/cross_compilation/wasm/Reactor.wasm";
+const expected = "Hello from Swift, WebAssembly!";
+
+let instance;
+const dv = () => new DataView(instance.exports.memory.buffer);
+const u8 = () => new Uint8Array(instance.exports.memory.buffer);
+const SUCCESS = 0, BADF = 8;
+const wasi = {
+ args_sizes_get: (a, b) => { dv().setUint32(a, 0, true); dv().setUint32(b, 0, true); return SUCCESS; },
+ args_get: () => SUCCESS,
+ environ_sizes_get: (a, b) => { dv().setUint32(a, 0, true); dv().setUint32(b, 0, true); return SUCCESS; },
+ environ_get: () => SUCCESS,
+ fd_fdstat_get: (fd, ptr) => { for (let i = 0; i < 24; i++) dv().setUint8(ptr + i, 0); return SUCCESS; },
+ fd_prestat_get: () => BADF,
+ fd_prestat_dir_name: () => BADF,
+ fd_close: () => SUCCESS,
+ fd_read: (fd, iovs, n, nread) => { dv().setUint32(nread, 0, true); return SUCCESS; },
+ fd_seek: (fd, off, whence, newOff) => { dv().setUint32(newOff, 0, true); return SUCCESS; },
+ fd_write: (fd, iovs, n, nwritten) => {
+ let written = 0;
+ for (let i = 0; i < n; i++) written += dv().getUint32(iovs + i * 8 + 4, true);
+ dv().setUint32(nwritten, written, true);
+ return SUCCESS;
+ },
+ path_open: () => BADF,
+ proc_exit: (code) => { throw new Error("proc_exit(" + code + ")"); },
+ random_get: (ptr, len) => { crypto.getRandomValues(u8().subarray(ptr, ptr + len)); return SUCCESS; },
+};
+
+const bytes = readFileSync(wasmPath);
+instance = (await WebAssembly.instantiate(bytes, { wasi_snapshot_preview1: wasi })).instance;
+instance.exports._initialize();
+
+const length = instance.exports.greeting_length();
+const memory = instance.exports.memory;
+const ptr = memory.buffer.byteLength;
+memory.grow(Math.ceil((length + 1) / 65536));
+const written = instance.exports.greeting_into(ptr, length + 1);
+const greeting = new TextDecoder().decode(new Uint8Array(memory.buffer, ptr, written));
+
+console.log("greeting:", JSON.stringify(greeting));
+if (greeting !== expected) {
+ console.error(`FAIL: expected ${JSON.stringify(expected)}`);
+ process.exit(1);
+}
+console.log("OK: Swift → WebAssembly greeting verified end-to-end");
diff --git a/swift/extensions.bzl b/swift/extensions.bzl
index 409cf7b72..ba2e227d4 100644
--- a/swift/extensions.bzl
+++ b/swift/extensions.bzl
@@ -27,12 +27,14 @@ load(
"//swift/internal/extensions:swift_sdks.bzl",
"ANDROID_ARCHS",
"swift_android_sdk_repository",
+ "swift_wasm_sdk_repository",
)
load(
"//swift/internal/extensions:toolchains.bzl",
_android_sdk_toolchains_for_platform = "android_sdk_toolchains_for_platform",
_toolchains_for_platform = "toolchains_for_platform",
_toolchains_repository = "toolchains_repository",
+ _wasm_sdk_toolchains_for_platform = "wasm_sdk_toolchains_for_platform",
)
load("//tools/explicit_modules:extensions.bzl", _system_sdk = "system_sdk")
@@ -91,6 +93,44 @@ def _setup_android_sdk(*, tag, toolchain_name, swift_version, platforms):
)
return build_file_content
+def _setup_wasm_sdk(*, tag, toolchain_name, swift_version, platforms):
+ """Creates the repositories for a `swift.wasm_sdk` tag.
+
+ Args:
+ tag: The `wasm_sdk` tag.
+ toolchain_name: The name of the `swift.toolchain` tag the SDK extends.
+ swift_version: The Swift release version of that toolchain.
+ platforms: The host platforms the toolchain was created for.
+
+ Returns:
+ BUILD file content with the `toolchain` declarations to add to the
+ toolchains hub repository.
+ """
+ sha256 = tag.sha256
+ if not sha256:
+ if swift_version not in SWIFT_SDK_RELEASES:
+ fail("No known WebAssembly Swift SDK for version `{}`. Please choose one of {}, or provide the SDK's sha256.".format(
+ swift_version,
+ SWIFT_SDK_RELEASES.keys(),
+ ))
+ sha256 = SWIFT_SDK_RELEASES[swift_version]["wasm"]
+
+ build_file_content = ""
+ for platform in platforms:
+ repository_name = "{}_wasm_sdk_{}".format(toolchain_name, platform)
+ swift_wasm_sdk_repository(
+ name = repository_name,
+ sha256 = sha256,
+ swift_version = swift_version,
+ toolchain_repo = "{}_{}".format(toolchain_name, platform),
+ url = swift_sdk_download_url(swift_version, "wasm"),
+ )
+ build_file_content += _wasm_sdk_toolchains_for_platform(
+ platform = platform,
+ sdk_repository = repository_name,
+ )
+ return build_file_content
+
def _sdk_tags_by_toolchain_name(tags, kind):
"""Groups SDK tags by the toolchain they extend, rejecting duplicates."""
tags_by_name = {}
@@ -117,6 +157,10 @@ def _standalone_toolchain_impl(module_ctx):
root_module.tags.android_sdk,
"android_sdk",
)
+ wasm_sdk_tags = _sdk_tags_by_toolchain_name(
+ root_module.tags.wasm_sdk,
+ "wasm_sdk",
+ )
toolchain_names = [
toolchain.name
@@ -128,6 +172,12 @@ def _standalone_toolchain_impl(module_ctx):
toolchain_name,
toolchain_names,
))
+ for toolchain_name in wasm_sdk_tags:
+ if toolchain_name not in toolchain_names:
+ fail("The `wasm_sdk` tag references unknown toolchain `{}`. Please use the name of a `toolchain` tag: {}".format(
+ toolchain_name,
+ toolchain_names,
+ ))
toolchains_build_file_content = ""
for toolchain in root_module.tags.toolchain:
@@ -169,6 +219,13 @@ def _standalone_toolchain_impl(module_ctx):
swift_version = swift_version,
platforms = platforms,
)
+ if toolchain.name in wasm_sdk_tags:
+ toolchains_build_file_content += _setup_wasm_sdk(
+ tag = wasm_sdk_tags[toolchain.name],
+ toolchain_name = toolchain.name,
+ swift_version = swift_version,
+ platforms = platforms,
+ )
_toolchains_repository(
name = toolchain.name,
@@ -202,6 +259,25 @@ defines Swift toolchains targeting Android.
""",
)
+_wasm_sdk = tag_class(
+ attrs = {
+ "sha256": attr.string(
+ doc = """\
+The expected SHA-256 of the SDK artifact bundle. May be omitted for Swift
+versions known to this version of rules_swift.
+""",
+ ),
+ "toolchain_name": attr.string(
+ doc = "The name of the `toolchain` tag to add this Swift SDK to.",
+ mandatory = True,
+ ),
+ },
+ doc = """\
+Downloads the WebAssembly Swift SDK matching a `toolchain` tag's Swift version
+and defines Swift and C++ toolchains targeting `wasm32-unknown-wasip1`.
+""",
+)
+
_toolchain = tag_class(attrs = {
"name": attr.string(
doc = "Repository name of the generated toolchain",
@@ -224,5 +300,6 @@ swift = module_extension(
tag_classes = {
"android_sdk": _android_sdk,
"toolchain": _toolchain,
+ "wasm_sdk": _wasm_sdk,
},
)
diff --git a/swift/internal/extensions/BUILD.bazel.tpl b/swift/internal/extensions/BUILD.bazel.tpl
index 9520c53a8..722214771 100644
--- a/swift/internal/extensions/BUILD.bazel.tpl
+++ b/swift/internal/extensions/BUILD.bazel.tpl
@@ -16,6 +16,8 @@ exports_files([
### Tools referenced by Swift SDK cross-compilation repositories. ###
exports_files([
+ "usr/bin/clang",
+ "usr/bin/llvm-ar",
"usr/bin/swiftc",
"usr/bin/swift-autolink-extract",
"usr/bin/swift-symbolgraph-extract",
@@ -37,6 +39,24 @@ filegroup(
),
)
+# The subset of the toolchain that link actions driven by this toolchain's
+# clang need (used by the WebAssembly SDK's cc toolchain).
+filegroup(
+ name = "swift_sdk_linker_inputs",
+ srcs = glob(
+ [
+ "usr/bin/clang*",
+ "usr/bin/ld.lld",
+ "usr/bin/ld64.lld",
+ "usr/bin/lld",
+ "usr/bin/llvm-ar",
+ "usr/bin/wasm-ld",
+ "usr/lib/clang/**",
+ ],
+ allow_empty = True,
+ ),
+)
+
filegroup(
name = "files",
srcs = glob(
diff --git a/swift/internal/extensions/swift_sdk_releases.bzl b/swift/internal/extensions/swift_sdk_releases.bzl
index 8cfea21f6..ae0a28a50 100644
--- a/swift/internal/extensions/swift_sdk_releases.bzl
+++ b/swift/internal/extensions/swift_sdk_releases.bzl
@@ -14,6 +14,7 @@ https://www.swift.org/api/v1/install/releases.json.
SWIFT_SDK_RELEASES = {
"6.3.2": {
"android": "939e933549d12d28f2e0bf71019d734d309859e9773c572657ce565a81f85d68",
+ "wasm": "a61f0584c93283589f8b2f42db05c1f9a182b506c2957271402992655591dd7c",
},
}
diff --git a/swift/internal/extensions/swift_sdks.bzl b/swift/internal/extensions/swift_sdks.bzl
index e5a7b383e..084b95137 100644
--- a/swift/internal/extensions/swift_sdks.bzl
+++ b/swift/internal/extensions/swift_sdks.bzl
@@ -2,12 +2,13 @@
A "Swift SDK" is an artifact bundle published by swift.org for cross-compiling
Swift to a platform the host toolchain cannot target by itself (the bundles that
-`swift sdk install` consumes). The `android_sdk` extension defines a repository
-rule that downloads such a bundle and generates a `swift_toolchain` targeting
-`{aarch64,x86_64}-unknown-linux-android`; this module holds the helpers and
-BUILD-file template it uses. C/C++ compilation and linking go through a
-separately registered Android cc toolchain (e.g. `@androidndk//:all`), which also
-provides the sysroot the Swift toolchain reads.
+`swift sdk install` consumes). The per-platform extensions (`android_sdk`,
+`wasm_sdk`) define repository rules that download such a bundle and generate a
+`swift_toolchain` for the target; this module holds the helpers and BUILD-file
+templates they share. Android's C/C++ compilation and linking go through a
+separately registered Android cc toolchain (e.g. `@androidndk//:all`), while the
+WebAssembly repository also generates a rules_cc `cc_toolchain` that drives the
+paired toolchain's clang.
Because the Swift module format is not stable across compiler versions, a Swift
SDK must come from exactly the same release as the host toolchain it is paired
@@ -51,6 +52,106 @@ swift_tools(
)
"""
+# The WebAssembly repository also generates a rules_cc cc_toolchain, so its
+# BUILD header needs the rules_cc toolchain loads.
+_WASM_BUILD_HEADER_TEMPLATE = """\
+load("@rules_cc//cc/toolchains:args.bzl", "cc_args")
+load("@rules_cc//cc/toolchains:make_variable.bzl", "cc_make_variable")
+load("@rules_cc//cc/toolchains:tool.bzl", "cc_tool")
+load("@rules_cc//cc/toolchains:tool_map.bzl", "cc_tool_map")
+load("@rules_cc//cc/toolchains:toolchain.bzl", "cc_toolchain")
+load("@rules_swift//swift/toolchains:swift_toolchain.bzl", "swift_toolchain")
+load("@rules_swift//swift/toolchains:swift_tools.bzl", "swift_tools")
+
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+ name = "sdk_files",
+ srcs = glob(["{bundle_dir}/**"]),
+)
+
+swift_tools(
+ name = "tools",
+ swift_driver = "@{toolchain_repo}//:usr/bin/swiftc",
+ swift_autolink_extract = "@{toolchain_repo}//:usr/bin/swift-autolink-extract",
+ swift_symbolgraph_extract = "@{toolchain_repo}//:usr/bin/swift-symbolgraph-extract",
+ additional_inputs = {compiler_inputs},
+)
+"""
+
+_CC_TOOLCHAIN_TEMPLATE = """
+cc_tool(
+ name = "clang",
+ src = "{clang}",
+ data = {clang_data},
+ tags = ["manual"],
+)
+
+cc_tool(
+ name = "ar",
+ src = "{ar}",
+ tags = ["manual"],
+)
+
+cc_tool_map(
+ name = "cc_tools",
+ tags = ["manual"],
+ tools = {{
+ "@rules_cc//cc/toolchains/actions:ar_actions": ":ar",
+ "@rules_cc//cc/toolchains/actions:assembly_actions": ":clang",
+ "@rules_cc//cc/toolchains/actions:c_compile": ":clang",
+ "@rules_cc//cc/toolchains/actions:cpp_compile_actions": ":clang",
+ "@rules_cc//cc/toolchains/actions:link_actions": ":clang",
+ }},
+)
+"""
+
+_CC_TOOLCHAIN_FOR_TARGET_TEMPLATE = """
+cc_args(
+ name = "cc_args_{suffix}",
+ actions = [
+ "@rules_cc//cc/toolchains/actions:compile_actions",
+ "@rules_cc//cc/toolchains/actions:link_actions",
+ ],
+ args = {args},
+)
+
+cc_args(
+ name = "cc_link_args_{suffix}",
+ actions = [
+ "@rules_cc//cc/toolchains/actions:link_actions",
+ ],
+ args = {link_args},
+)
+
+cc_make_variable(
+ name = "cc_target_triple_{suffix}",
+ value = "{triple}",
+ variable_name = "CC_TARGET_TRIPLE",
+)
+
+cc_toolchain(
+ name = "cc_toolchain_{suffix}",
+ args = [
+ ":cc_args_{suffix}",
+ ":cc_link_args_{suffix}",
+ ],
+ compiler = "clang",
+ enabled_features = [
+ "@rules_cc//cc/toolchains/args/archiver_flags:feature",
+ "@rules_cc//cc/toolchains/args/libraries_to_link:feature",
+ "@rules_cc//cc/toolchains/args/link_flags:feature",
+ # Needed so `swift_binary(linkshared = True)` links a shared library
+ # (passes `-shared` for the dynamic_library link action).
+ "@rules_cc//cc/toolchains/args/shared_flag:feature",
+ ],
+ make_variables = [
+ ":cc_target_triple_{suffix}",
+ ],
+ tool_map = ":cc_tools",
+)
+"""
+
def _execroot_relative_path(path):
"""Returns the execution-root-relative path for an external repository path.
@@ -221,3 +322,107 @@ target Android.
""",
implementation = _swift_android_sdk_impl,
)
+
+def _swift_wasm_sdk_impl(repository_ctx):
+ bundle_dir = _download_sdk_bundle(repository_ctx)
+ toolchain_repo = repository_ctx.attr.toolchain_repo
+
+ repo_root = "external/" + repository_ctx.name
+ sdk_dir = "{}/{}/{}".format(
+ repo_root,
+ bundle_dir,
+ "{0}/wasm32-unknown-wasip1".format(bundle_dir.removesuffix(".artifactbundle")),
+ )
+ if not repository_ctx.path(sdk_dir.removeprefix(repo_root + "/")).exists:
+ fail("The WebAssembly Swift SDK bundle has an unexpected layout; " +
+ "missing " + sdk_dir)
+ wasi_sdk = sdk_dir + "/WASI.sdk"
+ resource_dir = sdk_dir + "/swift.xctoolchain/usr/lib/swift_static"
+
+ build_content = _WASM_BUILD_HEADER_TEMPLATE.format(
+ bundle_dir = bundle_dir,
+ compiler_inputs = _build_list([
+ ":sdk_files",
+ "@{}//:swift_sdk_compiler_inputs".format(toolchain_repo),
+ ]),
+ toolchain_repo = toolchain_repo,
+ )
+
+ build_content += _SWIFT_TOOLCHAIN_TEMPLATE.format(
+ arch = "wasm32",
+ copts = _build_list([
+ "-resource-dir",
+ resource_dir,
+ ]),
+ features = _build_list([
+ "swift.module_map_no_private_headers",
+ "swift.no_embed_debug_module",
+ # wasm-ld cannot alias a renamed entry point back to the symbol
+ # that wasi-libc's startup code expects.
+ "swift.no_entry_point_rename",
+ "swift.use_autolink_extract",
+ ]),
+ linker_inputs = _build_list([":sdk_files"]),
+ # The runtime objects and libraries that `swiftc` would add when
+ # linking a static executable for WASI; see
+ # `swift_static/wasi/static-executable-args.lnk` in the SDK.
+ linkopts = _build_list([
+ "{}/wasi/wasm32/swiftrt.o".format(resource_dir),
+ "-L{}/wasi".format(resource_dir),
+ "-lc++",
+ "-lc++abi",
+ "-lswiftSwiftOnoneSupport",
+ "-ldl",
+ "-lm",
+ "-lwasi-emulated-mman",
+ "-lwasi-emulated-signal",
+ "-lwasi-emulated-process-clocks",
+ # The Swift driver always passes these bases to wasm-ld.
+ # `--table-base=4096` in particular is required: without it,
+ # optimized (`-O`) generic-metadata instantiation reads out of
+ # bounds at runtime (`-Onone` happens to tolerate the default).
+ "-Wl,--global-base=4096",
+ "-Wl,--table-base=4096",
+ ]),
+ os = "wasi",
+ sdkroot = wasi_sdk,
+ suffix = "wasm32",
+ swift_version = repository_ctx.attr.swift_version,
+ )
+
+ build_content += _CC_TOOLCHAIN_TEMPLATE.format(
+ ar = "@{}//:usr/bin/llvm-ar".format(toolchain_repo),
+ clang = "@{}//:usr/bin/clang".format(toolchain_repo),
+ clang_data = _build_list([
+ ":sdk_files",
+ "@{}//:swift_sdk_linker_inputs".format(toolchain_repo),
+ ]),
+ )
+
+ build_content += _CC_TOOLCHAIN_FOR_TARGET_TEMPLATE.format(
+ args = _build_list([
+ "--target=wasm32-unknown-wasip1",
+ "--sysroot=" + wasi_sdk,
+ ]),
+ # The Swift SDK's clang resource directory provides the compiler
+ # builtins (libclang_rt) for wasm32, which the host toolchain's own
+ # resource directory does not include.
+ link_args = _build_list([
+ "-resource-dir",
+ resource_dir + "/clang",
+ ]),
+ suffix = "wasm32",
+ triple = "wasm32-unknown-wasip1",
+ )
+
+ repository_ctx.file("BUILD.bazel", build_content)
+
+swift_wasm_sdk_repository = repository_rule(
+ attrs = _common_attrs(),
+ doc = """\
+Downloads the WebAssembly Swift SDK artifact bundle and defines Swift and C++
+toolchains that target `wasm32-unknown-wasip1` using a standalone host
+toolchain's compiler.
+""",
+ implementation = _swift_wasm_sdk_impl,
+)
diff --git a/swift/internal/extensions/toolchains.bzl b/swift/internal/extensions/toolchains.bzl
index c520f1942..cb6916ba7 100644
--- a/swift/internal/extensions/toolchains.bzl
+++ b/swift/internal/extensions/toolchains.bzl
@@ -55,6 +55,33 @@ toolchain(
)
"""
+_WASM_SDK_TOOLCHAIN_PLATFORM = """
+# Swift SDK toolchains from repository: `{sdk_repository}`
+toolchain(
+ name = "swift_toolchain_{target}_{platform}",
+ exec_compatible_with = {exec_compatible_with},
+ target_compatible_with = {target_compatible_with},
+ toolchain = "@{sdk_repository}//:swift_toolchain_{target_suffix}",
+ toolchain_type = "@rules_swift//toolchains:toolchain_type",
+ visibility = ["//visibility:public"],
+)
+
+# The paired rules_cc toolchain drives the SDK bundle's own clang for the C
+# side of the build (unlike Android, where the cc toolchain comes from the
+# separately registered NDK). It only resolves for this wasm target platform,
+# and because root-module registrations take precedence in toolchain
+# resolution, a consumer who registers their own wasm cc toolchain wins over
+# this one automatically.
+toolchain(
+ name = "cc_toolchain_{target}_{platform}",
+ exec_compatible_with = {exec_compatible_with},
+ target_compatible_with = {target_compatible_with},
+ toolchain = "@{sdk_repository}//:cc_toolchain_{target_suffix}",
+ toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
+ visibility = ["//visibility:public"],
+)
+"""
+
def _exec_compatible_with_for_platform(platform):
# This assumption is baked into the API so we have to go along with it
if platform == "xcode":
@@ -102,6 +129,30 @@ def android_sdk_toolchains_for_platform(platform, sdk_repository, archs):
)
return content
+def wasm_sdk_toolchains_for_platform(platform, sdk_repository):
+ """Returns `toolchain` declarations for a WebAssembly Swift SDK.
+
+ Args:
+ platform: The platform name (e.g. "xcode" or "ubuntu22.04") whose
+ standalone toolchain the SDK is paired with.
+ sdk_repository: The name of the repository created by
+ `swift_wasm_sdk_repository`.
+
+ Returns:
+ BUILD file content declaring the Swift and C++ toolchains.
+ """
+ return _WASM_SDK_TOOLCHAIN_PLATFORM.format(
+ exec_compatible_with = _exec_compatible_with_for_platform(platform),
+ platform = platform,
+ sdk_repository = sdk_repository,
+ target = "wasm32",
+ target_compatible_with = [
+ "@platforms//os:wasi",
+ "@platforms//cpu:wasm32",
+ ],
+ target_suffix = "wasm32",
+ )
+
def _toolchains_impl(repository_ctx):
repository_ctx.file("BUILD.bazel", repository_ctx.attr.build_file_content)
diff --git a/swift/swift_binary.bzl b/swift/swift_binary.bzl
index 2186bc9e4..a0d28b078 100644
--- a/swift/swift_binary.bzl
+++ b/swift/swift_binary.bzl
@@ -78,6 +78,12 @@ def _maybe_parse_as_library_copts(srcs):
srcs[0].basename != "main.swift"
return ["-parse-as-library"] if use_parse_as_library else []
+def _is_wasm(ctx):
+ """Returns True if the target platform is WebAssembly."""
+ return ctx.target_platform_has_constraint(
+ ctx.attr._wasi_os_constraint[platform_common.ConstraintValueInfo],
+ )
+
def _swift_binary_impl(ctx):
toolchains = find_all_toolchains(ctx)
feature_configuration = configure_features_for_binary(
@@ -87,10 +93,12 @@ def _swift_binary_impl(ctx):
unsupported_features = ctx.disabled_features,
)
- # A binary linked as a shared object (`linkshared`) has no `main`, so the
- # entry-point rename (and the matching `--defsym main=...` at link time)
- # must be skipped, just as it is when the toolchain requests it via
- # `swift.no_entry_point_rename`.
+ is_wasm = _is_wasm(ctx)
+
+ # A binary linked as a shared object (`linkshared`) or a WebAssembly
+ # reactor has no `main`, so the entry-point rename (and the matching
+ # `--defsym main=...` at link time) must be skipped, just as it is when the
+ # toolchain requests it via `swift.no_entry_point_rename`.
skip_entry_point = ctx.attr.linkshared or is_feature_enabled(
feature_configuration = feature_configuration,
feature_name = SWIFT_FEATURE_NO_ENTRY_POINT_RENAME,
@@ -195,12 +203,21 @@ def _swift_binary_impl(ctx):
else:
name = ctx.label.name
- # `linkshared` produces a real dynamic library (`lib