-
Notifications
You must be signed in to change notification settings - Fork 24k
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
Fix build errors when a native module includes Swift #38806
Fix build errors when a native module includes Swift #38806
Conversation
Base commit: 589aea0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused, because these errors should not happen: a .h
file is not build unless a .m
or .mm
file imports it.
A .h
files imported by .m
files must not contains C++ code/headers or they fail with the error you are seeing. But, if we rename the .m
to .mm
the error should go away.
I feel that this change fixes the symptom but not the root cause: instead of adding #ifdef __cplusplus
all over the place, can we try to look for the .m
that is making the build fail, and rename that file, instead?
The maintenance of the codebase would be better with that change instead of this one.
This is a solution, but only for Objective-C. If any
The root cause is exactly what I described in this PR. To integrate well with Swift, all public headers must not contain C++ code.
I think the maintenance would be easier if we have a better separation between Objective-C and C++ code, instead of trying to mix them in headers. Moreover, I think that #37275 also introduced some regressions in Swift integration. In particular, it adds EDIT: I closed the PR by accident, I'm re-opening it in the next comment 😅 |
I'm also going to add a dummy Swift file to the native module example so we can see issues like this immediately. Sadly, missing |
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
I don't like the number of times I've seen this pattern work its way into C++ headers inside of RN. It is quite fragile, and any new header could add breakage. Is it possible to use an explicitly defined umbrella header or module map? Here is a recent example where someone have a modulemap that SwiftPM uses to make sure the umbrella header only includes the public C APIs. https://github.com/facebook/yoga/blob/6f958afd3b10d2845a08ca0ad2917a87b09a7867/yoga/module.modulemap |
I agree that this probably isn't perfect, but it's as common as
It is possible, but I don't think it solves the problem. You can achieve the same result by just adding those files to |
This is not quite correct. The I went through the effort of removing ifdefs Expo added to Yoga a while back in 33ebb5d |
IIRC, CocoaPods with custom module_map will break in use_frameworks mode. does yoga use the custom module_map for CocoaPods as well or SPM only? |
@Kudo It looks like it's not used for CocoaPods ( |
besides custom module_map, i feel like the swift build errors happen many times from the past. @tsapeta has an idea to create a pr and add a swift file to rn-tester, so that we could find swift integration error as early as possible. |
In Cocoapods for Yoga, we include a small set of public headers which forms the transitive closure of importing “<yoga/Yoga.h>”. It is fairly minimal, and C compatible. So, modular headers get this smaller set of headers. Fabric C++ has been importing private C++ implementation details from Yoga. E.g. YGStyle I’ve been working towards RN only using public Yoga APIs, and cleaning up the directory structure, but in the meantime, the C++ build for Fabric has private Yoga headers added to its header search path for C++ users. In Yoga there is an intentional header structure for the C API, that avoids importing any C++ headers by using a PIMPL-like pattern (all refs in the headers are opaque pointers). If we were designing an explicit C/ObjC extension point for these RN bits, what would it look like? And then how to we create a thin header graph that can keep explicitly being C++ free. |
that would be huge effort for RN but would benefit ABI safety. the scope is far more than this pr. |
What headers are you using from Swift, where these C++ headers got added to your include chain? |
since swift doesn't support importing a c/c++ header file, we could just |
The React-core clang module has quite a bit of surface that seems like it would be unneeded for Swift modules. That seems like space for a solution, where we split out a module with smaller surface that we can keep explicitly ObjC headers only, and explicitly able to be imported by Swift. I’m also curious, if the React Core module was previously all ObjC headers, what change introduced the new C++ headers? That might be a sign of organization we can improve. |
closing as it has been superseded by #38993 |
that is a great question. i took some time to check the difference between 0.72 and the git history, 42d67452eb9a#diff-226ff5f87f146abfebd14a69eeb7d95c358d53da30533321e3ae9281c8acc6f0L102 could be the root cause. i'm creating #38993 as a replacement for this pr. |
Summary: supersedes #38806 the errors are actually coming from 42d67452eb9a#diff-226ff5f87f146abfebd14a69eeb7d95c358d53da30533321e3ae9281c8acc6f0L102. we should keep c++ headers as cocoapods private headers, so that those headers will not expose into the umbrella header. this pr also adds a swift test file to rn-tester, so we can verify the fix and prevent the similar build errors in the future. ## Changelog: [IOS] [FIXED] - Fix build errors when importing React-Core module from Swift Pull Request resolved: #38993 Test Plan: add a swift file in rn-tester and make sure it builds successfully Reviewed By: cipolleschi Differential Revision: D48414292 Pulled By: NickGerleman fbshipit-source-id: d65273adc4bfab927d7c3db1db6bb48d3e48349e
…k#38993) Summary: supersedes facebook#38806 the errors are actually coming from facebook@42d67452eb9a#diff-226ff5f87f146abfebd14a69eeb7d95c358d53da30533321e3ae9281c8acc6f0L102. we should keep c++ headers as cocoapods private headers, so that those headers will not expose into the umbrella header. this pr also adds a swift test file to rn-tester, so we can verify the fix and prevent the similar build errors in the future. [IOS] [FIXED] - Fix build errors when importing React-Core module from Swift Pull Request resolved: facebook#38993 Test Plan: add a swift file in rn-tester and make sure it builds successfully Reviewed By: cipolleschi Differential Revision: D48414292 Pulled By: NickGerleman fbshipit-source-id: d65273adc4bfab927d7c3db1db6bb48d3e48349e
Summary:
Similar to #34527, but covers much more Objective-C++ headers that are now included in the autogenerated
React-Core-umbrella.h
.Changelog:
[IOS] [FIXED] - Fixed build errors when a native module includes Swift
Test Plan:
RNTester builds without errors after adding a Swift file to https://github.com/facebook/react-native/tree/main/packages/rn-tester/NativeModuleExample and running
USE_FRAMEWORKS=static pod install
.