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

Supported autolinking on the new architecture #642

Merged
merged 22 commits into from
Sep 18, 2022
Merged

Conversation

grahammendick
Copy link
Owner

@grahammendick grahammendick commented Sep 18, 2022

React Native 0.70 added autolinking to Android. This removes the need for the user to make manual changes for native component library dependencies on Android in the new architecture. But it doesn’t support libraries with interfaceOnly components. These components use c++ state so have to opt-out of the full codegen and hand-write some of the files.

I asked React Native how to support autolinking with interfaceOnly components. Ended up going with react native screens approach because React Native’s answer didn’t work. A custom CMakeLists.txt that takes custom hand-written cpp combined with the react native codegen’ed ones.

The tricky part is getting the custom component descriptors included in the rncli.cpp generated by the android build. This file includes navigationreactnative.h so had to sneak them in there (ingenious solution from react native screens). Although this file is generated, included it with the hand-written ones and included the custom descriptors. Had to exclude this file from the podspec otherwise couldn’t build on ios. For example, NVActionBarComponentDescriptor is hand-written so isn't part of ComponentDescriptors.h but is included in navigationreactnative.h.

#include <navigationreactnative.h>
#include <react/renderer/components/navigationreactnative/ComponentDescriptors.h>

namespace facebook {
namespace react {

void rncli_registerProviders(std::shared_ptr<ComponentDescriptorProviderRegistry const> providerRegistry) {
  providerRegistry->add(concreteComponentDescriptorProvider<NVActionBarComponentDescriptor>());

Autolinking on Android doesn't like hyphens in library name
And renamed import to match as well, though don't know why needed the folder name before. Plan to drop the subfolders from cpp folder
There's no need for the subfolders now that React Native autolinks on android. The subfolders were to make the handwritten setup on android more consistent
Copied it from the codegen'ed one and pointed LOCAL_SRC_FILES at both the codegen and the hand-written c++ state files in cpp folder. Just a first go, not tried it yet
Don't know why it's needed as well as Android.mk?! Copied the codegen'ed one and added codegen files and c++ state cpp files
Couldn't get it to work using codegen and cpp folder - so followed advice from reactwg/react-native-new-architecture#71 (comment) that said needed own c++ implementation for everything. Gets further but falling over at the NativeMaterial3ModuleSpec - it's not generated now. Wondering if this approach works with ModuleSpecs as well?!
This file was codegen'ed but clearer to drop the 'generated' from the name
Copying from react native autolinking repo and they only have the CMakeLists.txt troZee/react-native-cpp-autolinking@5e1b0f2
Need to put together example repo with android build failing so react native can investigate
Had to go through all the files on the example repo 1 by 1 to see what was wrong, JSI_EXPORT. There were 3 key errors
1. Added JSI_EXPORT to hand-written cpp interfaces
2. Include "Props.h" instead of <react/renderer/components/navigationreactnative/Props.h>
3. Removed libraries from codegenConfig in package.json
These each took me ages to spot
Also went back to androidMkPath because cmakeListsPath is a later change. Copies the config from React Native's autlink example
Copying over the codegen didn't work for ios. Ended up with redefinition of EventEmitters errors reactwg/react-native-new-architecture#71 (reply in thread). There's no custom build on ios so it includes the copied over codegen as well as the actual codegen so it gets included twice. Can't just exclude it on ios because the includes on shadownodes point to local "EventEmitters.h'.
So went with the react native screens approach of pointing at the codegen instead of copying it over reactwg/react-native-new-architecture#71 (comment). It works on android and should work on ios (haven't tested yet) because it's just the hand-written files now
Copied this over from react native screens example but isn't necessary
This matches approach for generated components
The current directory has no relevant cpp files - they're now all in react/renderer/components/navigationreactnative
Still copying code from react native screens example reactwg/react-native-new-architecture#71 (comment)
Couldn't work out how to get the ComponentDescriptor in the generated rncli.cpp because it only includes ComponentDescriptors.h. Noticed it also includes navigationreactnative.h - so the trick is to include the hand-written descriptors in that file!! React native screens did this just didn't notice or realise what it was for. It's very sneaky!
This allows it to work on android and ios!! And with lower maintenance because not copying over hand-generated - apart from navigationreactnative.h and .cpp. Had to exclude these files from the podspec otherwise doesn't build on ios
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

Successfully merging this pull request may close these issues.

1 participant