Skip to content

Commit

Permalink
Add special -parse-as-library handling for swift_binary
Browse files Browse the repository at this point in the history
This matches the behavior implemented in
swiftlang/swift-package-manager#3410 for single
file modules.
  • Loading branch information
keith committed Oct 3, 2022
1 parent b250c3f commit a86aeb0
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 1 deletion.
22 changes: 21 additions & 1 deletion swift/internal/swift_binary_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,25 @@ def _configure_features_for_binary(
unsupported_features = unsupported_features,
)

def _maybe_parse_as_library_copts(srcs):
"""Returns a list of compiler flags depending on `main.swift`'s presence.
Now that the `@main` attribute exists and is becoming more common, in the
case there is a single file not named `main.swift`, we assume that it has a
`@main` annotation, in which case it needs to be parsed as a library, not
as if it has top level code. In the case this is the wrong assumption,
compilation or linking will fail.
Args:
srcs: A list of source files to check for the presence of `main.swift`.
Returns:
A list of compiler flags to add to `copts`
"""
use_parse_as_library = len(srcs) == 1 and \
srcs[0].basename != "main.swift"
return ["-parse-as-library"] if use_parse_as_library else []

def _swift_linking_rule_impl(
ctx,
binary_path,
Expand Down Expand Up @@ -184,7 +203,8 @@ def _swift_linking_rule_impl(
if not module_name:
module_name = swift_common.derive_module_name(ctx.label)

copts = expand_locations(ctx, ctx.attr.copts, ctx.attr.swiftc_inputs)
copts = expand_locations(ctx, ctx.attr.copts, ctx.attr.swiftc_inputs) + \
_maybe_parse_as_library_copts(srcs)

module_context, cc_compilation_outputs, other_compilation_outputs = swift_common.compile(
actions = ctx.actions,
Expand Down
3 changes: 3 additions & 0 deletions test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ load(":debug_settings_tests.bzl", "debug_settings_test_suite")
load(":features_tests.bzl", "features_test_suite")
load(":generated_header_tests.bzl", "generated_header_test_suite")
load(":linking_tests.bzl", "linking_test_suite")
load(":mainattr_tests.bzl", "mainattr_test_suite")
load(":module_cache_settings_tests.bzl", "module_cache_settings_test_suite")
load(":output_file_map_tests.bzl", "output_file_map_test_suite")
load(":private_deps_tests.bzl", "private_deps_test_suite")
Expand All @@ -28,6 +29,8 @@ generated_header_test_suite(name = "generated_header")

linking_test_suite(name = "linking")

mainattr_test_suite(name = "mainattr")

module_cache_settings_test_suite(name = "module_cache_settings")

output_file_map_test_suite(name = "output_file_map")
Expand Down
23 changes: 23 additions & 0 deletions test/fixtures/mainattr/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
load("//swift:swift.bzl", "swift_binary")

package(
default_visibility = ["//test:__subpackages__"],
)

swift_binary(
name = "main",
srcs = ["main.swift"],
)

swift_binary(
name = "custommain",
srcs = ["custommain.swift"],
)

swift_binary(
name = "multiplefiles",
srcs = [
"file1.swift",
"file2.swift",
],
)
6 changes: 6 additions & 0 deletions test/fixtures/mainattr/custommain.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@main
struct Foo {
static func main() {
print("Hello, world!")
}
}
1 change: 1 addition & 0 deletions test/fixtures/mainattr/file1.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print(foo())
3 changes: 3 additions & 0 deletions test/fixtures/mainattr/file2.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
func foo() -> String {
return "foo"
}
1 change: 1 addition & 0 deletions test/fixtures/mainattr/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print("hi")
38 changes: 38 additions & 0 deletions test/mainattr_tests.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Tests for validating @main related usage"""

load(
"@build_bazel_rules_swift//test/rules:action_command_line_test.bzl",
"make_action_command_line_test_rule",
)

mainattr_test = make_action_command_line_test_rule()

def mainattr_test_suite(name):
mainattr_test(
name = "{}_single_main".format(name),
not_expected_argv = ["-parse-as-library"],
mnemonic = "SwiftCompile",
tags = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/mainattr:main",
)

mainattr_test(
name = "{}_single_custom_main".format(name),
expected_argv = ["-parse-as-library"],
mnemonic = "SwiftCompile",
tags = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/mainattr:custommain",
)

mainattr_test(
name = "{}_multiple_files".format(name),
not_expected_argv = ["-parse-as-library"],
mnemonic = "SwiftCompile",
tags = [name],
target_under_test = "@build_bazel_rules_swift//test/fixtures/mainattr:multiplefiles",
)

native.test_suite(
name = name,
tags = [name],
)

0 comments on commit a86aeb0

Please sign in to comment.