Skip to content
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

Swiftc imports bridging header twice #526

Open
michaeleisel opened this issue Dec 1, 2020 · 1 comment
Open

Swiftc imports bridging header twice #526

michaeleisel opened this issue Dec 1, 2020 · 1 comment

Comments

@michaeleisel
Copy link
Contributor

I have an app that consists of a single Swift/ObjC module, specified using an ObjC and a Swift rule, and a similar unit test module using an ObjC and a Swift rule. However, when running bazel build MyAppUnitTests --apple_platform_type=ios, I get a mysterious set of errors:

Sources/MyHeader.h:34:5: error: redefinition of enumerator 'MyEnumerator'
<many more similar redefinition errors>
a.swift:1:18: warning: implicit import of bridging header 'MyApp-Bridging-Header.h' via module 'MyApp' is deprecated and will be removed in a later version of Swift

a.swift is the one file in the unit test module's Swift rule, and it simply consists of @testable import MyApp, which imports the bridging header from the MyApp module. It also imports the bridging header for unit tests via copts = ["-import-objc-header", TEST_BRIDGING_HEADER], which itself imports the MyApp bridging header too (#import "MyApp-Bridging-Header.h"). These two seem to be fine together, i.e. no double-importing. However, that last import is overlooked by swiftc, because the warning it gives in the bottom of that error message implies that that import isn't occurring, though we can see it is. So then it implicitly imports the bridging header itself, and we end up with lots of duplicate definitions from this double importing.

What's weird is that certain seemingly innocuous changes will fix it. Adding or removing certain files, or removing module_name = MyAppHeaders below (even though that module name is never used anywhere in code), can cause it to reliably work again. As well, it works regardless when using rules_swift prior to 410d8ed ("Only read output_file_map if it's going to be written").

Below is a minimal example with placeholder files like a.m that contain very little. However, I wasn't able to get it down to an example trivial enough to share (you can see some globs in there). This is because removing certain files suddenly makes it work again.

load("@bazel_skylib//lib:collections.bzl", "collections")
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_binary", "swift_library")

MIN_OS_VERSION = "12.0"

BRIDGING_HEADER = "Sources/SupportingFiles/MyApp-Bridging-Header.h"

HEADERS = glob(["Sources/**/*.h"])

objc_library(
    name = "MyAppHeaders",
    module_name = "MyAppHeaders",
    includes = collections.uniq([paths.dirname(hdr) for hdr in HEADERS]),
    textual_hdrs = HEADERS,
)

swift_library(
    name = "MyAppSwift",
    srcs = glob(["Sources/**/*.swift"]),
    copts = [
        "-import-objc-header",
        BRIDGING_HEADER,
    ],
    generated_header_name = "MyApp-Swift.h",
    module_name = "MyApp",
    swiftc_inputs = [BRIDGING_HEADER],
    deps = [
        "MyAppHeaders",
        # Other deps not shown
    ],
)

objc_library(
    name = "MyAppObjC",
    srcs = ["b.m"],
    deps = [
        "MyAppHeaders",
        "MyAppSwift",
        # Other deps not shown
    ],
)

TEST_BRIDGING_HEADER = "Tests/MyAppTests-Bridging-Header.h"

swift_library(
    name = "MyAppUnitTestsLibSwift",
    testonly = True,
    srcs = ["a.swift"],
    copts = [
        "-import-objc-header",
        TEST_BRIDGING_HEADER,
    ],
    swiftc_inputs = [TEST_BRIDGING_HEADER],
    deps = [
        "MyAppHeaders",
        "MyAppSwift",
    ],
)

objc_library(
    name = "MyAppUnitTestsLibObjC",
    testonly = True,
    srcs = ["a.m"],
    deps = [
        "MyAppHeaders",
        "MyAppUnitTestsLibSwift",
    ],
)

ios_unit_test(
    name = "MyAppUnitTests",
    minimum_os_version = MIN_OS_VERSION,
    deps = [
        "MyAppUnitTestsLibObjC",
        "MyAppUnitTestsLibSwift",
    ],
)
@tinder-maxwellelliott
Copy link

I believe I am seeing a similar error (seen here bazel-ios/rules_ios#157), I am able to build my module successfully, but I cannot test that module without seeing duplication errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants