MobileNativeFoundation / rules_xcodeproj

Bazel rules for generating Xcode projects.
MIT License
526 stars 84 forks source link

Bug: Target merging fails when using `swift_library` dependency directly in `rules_ios` framework target #3094

Open luispadron opened 2 days ago

luispadron commented 2 days ago

Description

Given the following BUILD file:

load(
    "@build_bazel_rules_ios//rules:framework.bzl",
    rules_ios_apple_framework = "apple_framework",
)
load(
    "@build_bazel_rules_ios//rules:test.bzl",
    rules_ios_unit_test = "ios_unit_test",
)
load(
    "@build_bazel_rules_swift//swift:swift.bzl",
    "swift_library",
    "swift_library_group",
)

rules_ios_apple_framework(
    name = "LibTwo",
    srcs = ["Sources/LibTwo.swift"],
    platforms = {"ios": "15.0"},
    deps = [
        ":External",
    ],
    visibility = ["@rules_xcodeproj//xcodeproj:generated"],
)

rules_ios_unit_test(
    name = "LibTwoTests",
    srcs = ["Tests/LibTwoTests.swift"],
    minimum_os_version = "15.0",
    deps = [
        ":LibTwo",
    ],
    visibility = ["@rules_xcodeproj//xcodeproj:generated"],
)

swift_library(
    name = "External",
    srcs = ["External/External.swift"],
    module_name = "External",
)

With the following rules_xcodeproj scheme:

xcschemes.scheme(
    name = "LibTwo_Scheme",
    run = xcschemes.run(
        build_targets = [
            "//LibTwo",
        ],
    ),
    test = xcschemes.test(
        build_targets = [
            "//LibTwo",
        ],
        test_targets = [
            "//LibTwo:LibTwoTests",
        ],
    ),
),

When generating the project the LibTwo_Scheme's LibTwo target does not merge and we end up with a scheme that looks like:

Screenshot 2024-10-22 at 6 48 22 PM

With LibTwo making up two targets: LibTwo (Static Framework) and LibTwo (Library). I would expect these to be merged into a single LibTwo target in Xcode as is the case when using apple_framework as deps.

I tested both 2.7.0 and 2.5.2 and both seem to have the same issue. I added a reproducing example in: https://github.com/MobileNativeFoundation/rules_xcodeproj/pull/3093

Reproduction steps

  1. Checkout https://github.com/MobileNativeFoundation/rules_xcodeproj/pull/3093
  2. cd examples/rules_ios
  3. bazel run //:xcodeproj-incremental
  4. xed rules_ios.xcodeproj
  5. Select the LibTwo_Scheme target
  6. Attempt to build the target
  7. Observe the failure:

    /path/_CompileStub_.m Build input file cannot be found: '/path/_CompileStub_.m'.
    Did you forget to declare this file as an output of a script phase or custom build rule which produces it?

Expected behavior

The LibTwo target is merged into a single target so that building it succeeds.

rules_xcodeproj version

2.7.0

Xcode version

15.4

Bazel version

7.2.0

rules_apple version

3.9.2

rules_swift version

2.1.1

Additional information

No response

luispadron commented 2 days ago

As a workaround (and potentially helps narrow down the issue): manually changing the target in the scheme from LibTwo (Static Framework) to LibTwo (Library) fixes the build.

luispadron commented 2 days ago

If I remove use of transitive_deps from the merging logic then target merging works as expected and the build also passes.

However, indexing seems to fail when making changes:

examples/rules_ios/LibTwo/Sources/LibTwo.swift:1:8 No such module 'External'