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

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

Open
luispadron opened this issue Oct 22, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@luispadron
Copy link
Contributor

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: #3093

Reproduction steps

  1. Checkout Add rules_ios example depending on swift_library #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 luispadron added the bug Something isn't working label Oct 22, 2024
@luispadron
Copy link
Contributor Author

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
Copy link
Contributor Author

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'

@luispadron
Copy link
Contributor Author

As a workaround we have this rules_ios specific patch right now, working on generalizing it so we can upstream:

diff --git xcodeproj/internal/processed_targets/mergeable_infos.bzl xcodeproj/internal/processed_targets/mergeable_infos.bzl
index f04ccb0c..e98c8b55 100644
--- xcodeproj/internal/processed_targets/mergeable_infos.bzl
+++ xcodeproj/internal/processed_targets/mergeable_infos.bzl
@@ -112,6 +112,32 @@ def _calculate_mergeable_info(
             swift = swift,
         )
 
+    if len(mergeable_infos) > 2:
+        rules_ios_swift_library_info = [info for info in mergeable_infos if info.id and info.id.split(" ")[0].endswith("_swift")]
+        rules_ios_objc_library_info = [info for info in mergeable_infos if info.id and info.id.split(" ")[0].endswith("_objc")]
+        swift = None
+        cc = None
+        if len(rules_ios_swift_library_info) == 1:
+            swift = rules_ios_swift_library_info[0]
+        if len(rules_ios_objc_library_info) == 1:
+            cc = rules_ios_objc_library_info[0]
+
+        if cc and swift:
+            return _handle_mixed_language_mergeable_infos(
+                cc = cc,
+                dynamic_frameworks = dynamic_frameworks,
+                product_type = product_type,
+                swift = swift,
+            )
+        elif cc:
+            return _cc_mergeable_info(mergeable_info = cc)
+        elif swift:
+            return _swift_mergeable_info(
+                dynamic_frameworks = dynamic_frameworks,
+                mergeable_info = swift,
+                product_type = product_type,
+            )
+
     # Unmergeable source target count
     return None

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant