bazel-xcode / bazel-xcode/PodToBUILD
Cannot rely on React Native pod from Swift
- Dominant language
- Swift
- Stars
- 330
- Forks
- 68
- PR merge metrics
- No merged PRs in 30d
Description
*I want to prefix this by saying that I'm **not** super familiar with Swift/Objective-C compilation or Clang modules, so there may be some misconceptions/mistakes below; please feel free to point those out if you see them.*
# The issue
I'm attempting to rely on the React Native pod via a Swift file. This is causing React Native to be included as a module, and is trying to compile the React Native headers using modulemaps. It looks like the modulemaps generated for this pod are incorrect, both those generated by Bazel when `generate_module_map = False` and those generated by PodToBUILD when `generate_module_map = True`. Notably when `generate_module_map = True` it can't even compile the `.m` files in React Native (though that seems to be known already, as it is set to `False` in the "React" example).
A minimal example of this can be found here (which is a slight modification of the existing "React" example in this repo): https://github.com/FuegoFro/PodToBUILD/commit/b07429485557489482adc8c15ad8a3fe744210c0
The error I get when running `make` in that example is:
```
ERROR: .../PodToBUILD/Examples/React/BUILD:4:1: Compiling Swift module swift_lib failed (Exit 1)
Test.swift:1:2: error: expected an attribute name
@import Vendor_React_Core
^
.../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/React/Core.modulemaps/../../../../../../Vendor/React/pod_support/Headers/Public/yoga/RCTConvert.h:17:9: note: while building module 'Vendor_yoga_yoga' imported from .../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/React/Core.modulemaps/../../../../../../Vendor/React/pod_support/Headers/Public/yoga/RCTConvert.h:17:
#import
^
:1:9: note: in file included from :1:
#import "../../../../../../Vendor/yoga/pod_support/Headers/Public/yoga/Utils.h"
^
.../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/yoga/yoga.modulemaps/../../../../../../Vendor/yoga/yoga/Utils.h:9:10: note: in file included from .../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/yoga/yoga.modulemaps/../../../../../../Vendor/yoga/yoga/Utils.h:9:
#include "YGNode.h"
^
.../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/yoga/yoga.modulemaps/../../../../../../Vendor/yoga/yoga/YGNode.h:10:10: note: in file included from .../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/yoga/yoga.modulemaps/../../../../../../Vendor/yoga/yoga/YGNode.h:10:
#include "YGLayout.h"
^
.../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/yoga/yoga.modulemaps/../../../../../../Vendor/yoga/yoga/YGLayout.h:9:10: note: in file included from .../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/yoga/yoga.modulemaps/../../../../../../Vendor/yoga/yoga/YGLayout.h:9:
#include "Yoga-internal.h"
^
.../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/yoga/yoga.modulemaps/../../../../../../Vendor/yoga/yoga/Yoga-internal.h:9:10: error: 'algorithm' file not found
#include
^
:8:9: note: in file included from :8:
#import "../../../../../../Vendor/React/React/Base/RCTConvert.h"
^
.../sandbox/darwin-sandbox/137/execroot/__main__/bazel-out/apl-ios_x86_64-fastbuild/genfiles/Vendor/React/Core.modulemaps/../../../../../../Vendor/React/pod_support/Headers/Public/yoga/RCTConvert.h:17:9: error: could not build module 'Vendor_yoga_yoga'
#import
^
Test.swift:1:9: error: could not build Objective-C module 'Vendor_React_Core'
@import Vendor_React_Core
^
```
It looks like in this particular instance it's missing `requires cplusplus` in the modulemap for Yoga. I've tried manually specifying a modulemap for the module that includes this and run into other issues that seem maybe related to including an overly-broad set of headers in the modulemap (https://github.com/pinterest/PodToBUILD/issues/13).
I've also tried adding a bridging header and using `"-import-objc-header"` in the `swift_library`'s `copts`, but this still tries to compile the pod as a module.
It's also unclear to me if this would be present if trying to use the React pod via an Objective-C module (eg something like `@import Vendor_React_Core;` in Objective-c). I wasn't able to test this since I couldn't figure out how to make that work - it couldn't find a module with that name, presumably because `generate_module_map = False` (and, as mentioned, other things break if that's switched to `True`).
# Other similar issues I've found
https://github.com/pinterest/PodToBUILD/issues/13
https://github.com/pinterest/PodToBUILD/issues/58
https://github.com/bazelbuild/bazel/issues/1870
https://github.com/bazelbuild/rules_apple/issues/416
https://github.com/bazelbuild/rules_apple/issues/240
# Location of this issue
In the course of looking into this, it wasn't clear to me if this is something that can be fixed on the PodToBUILD side, or if this issue (and potential fix) would be better suited in one of https://github.com/bazelbuild/rules_swift, https://github.com/bazelbuild/rules_apple/ or https://github.com/bazelbuild/bazel. Would love some advice/guidance if you think this belongs somewhere else 🙂
I know that on the README for this repo it says that Swift likely won't work, but it seemed that this is more about how the Objective-C code is described, and not about compiling pods with Swift in them. However, I understand if this falls out of the scope of this repo/project.
# Potential fixes
The main workaround that I've found that looks viable so far is to manually specify `module.modulemap` files for each module, though not all Pods follow semantics that work with modules (eg some have headers that rely on being imported by other headers in the library and don't, for instance, re-import Foundation on their own).
Another potential fix would likely lie on the https://github.com/bazelbuild/rules_swift side is to mimic what Xcode does in this scenario, which is to point at the header include paths rather than at auto-generated modulemaps.
I would love it if there's any other thoughts/potential fixes on this issue. Thank you ahead of time!
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.