Skip to content

Commit dad6710

Browse files
authored
feat: Support autolinking C++ only TurboModules on Android (#2387)
* feat(android): add cxxOnly config property * feat(android-autolinking): Dont search for java related properties if cxxOnly is true * feat(android-autolinking): Don't autolink cxxOnly modules using the Java packagelist This also ignores them from getting included with gradle dependencies * chore: remove unnecessary newline from dependencies * chore: remove the cxxOnly property * feat: derive if a dependency is pure cxx from other properties * docs: document pure cxx linking
1 parent 98375b7 commit dad6710

File tree

4 files changed

+62
-20
lines changed

4 files changed

+62
-20
lines changed

docs/autolinking.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,26 @@ You’re already using Gradle, so Android support will work by default.
7070

7171
On the iOS side, you will need to ensure you have a Podspec to the root of your repo. The `react-native-webview` Podspec is a good example of a [`package.json`](https://github.com/react-native-community/react-native-webview/blob/master/react-native-webview.podspec)-driven Podspec. Note that CocoaPods does not support having `/`s in the name of a dependency, so if you are using scoped packages - you may need to change the name for the Podspec.
7272

73+
### Pure C++ libraries
74+
75+
Alternatively, if you have a pure C++ library and don't want to use Gradle, you can still use autolinking. You need to update your `react-native.config.js` to include the following:
76+
77+
```js
78+
// react-native.config.js
79+
module.exports = {
80+
dependency: {
81+
platforms: {
82+
android: {
83+
sourceDir: 'path/to/your/c++/code',
84+
cxxModuleCMakeListsPath: `relative/path/to/CMakeLists.txt`, // This is relative to the sourceDir.
85+
cxxModuleCMakeListsModuleName: 'MyModule', // This is the name of the CMake target.
86+
cxxModuleHeaderName: 'MyHeader', // CLI will include this header while linking.
87+
},
88+
},
89+
},
90+
};
91+
```
92+
7393
## How can I customize how autolinking works for my package?
7494

7595
A library can add a `react-native.config.js` configuration file, which will customize the defaults, example:

packages/cli-platform-android/native_modules.gradle

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ class ReactNativeModules {
186186
reactNativeModules.forEach { reactNativeModule ->
187187
def nameCleansed = reactNativeModule["nameCleansed"]
188188
def dependencyConfiguration = reactNativeModule["dependencyConfiguration"]
189+
def isPureCxxDependency = reactNativeModule["isPureCxxDependency"]
190+
if (isPureCxxDependency) {
191+
return
192+
}
193+
189194
appProject.dependencies {
190195
if (reactNativeModulesBuildVariants.containsKey(nameCleansed)) {
191196
reactNativeModulesBuildVariants
@@ -248,10 +253,14 @@ class ReactNativeModules {
248253
"${prefix}${packageName}.${className}${suffix}"
249254
})
250255
}
251-
packageImports = packages.collect {
256+
packageImports = packages
257+
.findAll { !it.isPureCxxDependency }
258+
.collect {
252259
"// ${it.name}\n${interpolateDynamicValues(it.packageImportPath)}"
253260
}.join('\n')
254-
packageClassInstances = ",\n " + packages.collect {
261+
packageClassInstances = ",\n " + packages
262+
.findAll { !it.isPureCxxDependency }
263+
.collect {
255264
interpolateDynamicValues(it.packageInstance)
256265
}.join(",\n ")
257266
}
@@ -481,6 +490,7 @@ class ReactNativeModules {
481490
reactNativeModuleConfig.put("cxxModuleCMakeListsModuleName", androidConfig["cxxModuleCMakeListsModuleName"])
482491
reactNativeModuleConfig.put("cxxModuleCMakeListsPath", androidConfig["cxxModuleCMakeListsPath"])
483492
reactNativeModuleConfig.put("cxxModuleHeaderName", androidConfig["cxxModuleHeaderName"])
493+
reactNativeModuleConfig.put("isPureCxxDependency", androidConfig["isPureCxxDependency"])
484494

485495
if (androidConfig["buildTypes"] && !androidConfig["buildTypes"].isEmpty()) {
486496
reactNativeModulesBuildVariants.put(nameCleansed, androidConfig["buildTypes"])

packages/cli-platform-android/src/config/index.ts

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -135,28 +135,38 @@ export function dependencyConfig(
135135
? path.join(sourceDir, userConfig.manifestPath)
136136
: findManifest(sourceDir);
137137
const buildGradlePath = findBuildGradle(sourceDir, true);
138-
139-
if (!manifestPath && !buildGradlePath) {
138+
const isPureCxxDependency =
139+
userConfig.cxxModuleCMakeListsModuleName != null &&
140+
userConfig.cxxModuleCMakeListsPath != null &&
141+
userConfig.cxxModuleHeaderName != null &&
142+
!manifestPath &&
143+
!buildGradlePath;
144+
145+
if (!manifestPath && !buildGradlePath && !isPureCxxDependency) {
140146
return null;
141147
}
142148

143-
const packageName =
144-
userConfig.packageName || getPackageName(manifestPath, buildGradlePath);
145-
const packageClassName = findPackageClassName(sourceDir);
149+
let packageImportPath = null,
150+
packageInstance = null;
146151

147-
/**
148-
* This module has no package to export
149-
*/
150-
if (!packageClassName) {
151-
return null;
152-
}
152+
if (!isPureCxxDependency) {
153+
const packageName =
154+
userConfig.packageName || getPackageName(manifestPath, buildGradlePath);
155+
const packageClassName = findPackageClassName(sourceDir);
156+
157+
/**
158+
* This module has no package to export
159+
*/
160+
if (!packageClassName) {
161+
return null;
162+
}
153163

154-
const packageImportPath =
155-
userConfig.packageImportPath ||
156-
`import ${packageName}.${packageClassName};`;
164+
packageImportPath =
165+
userConfig.packageImportPath ||
166+
`import ${packageName}.${packageClassName};`;
157167

158-
const packageInstance =
159-
userConfig.packageInstance || `new ${packageClassName}()`;
168+
packageInstance = userConfig.packageInstance || `new ${packageClassName}()`;
169+
}
160170

161171
const buildTypes = userConfig.buildTypes || [];
162172
const dependencyConfiguration = userConfig.dependencyConfiguration;
@@ -193,5 +203,6 @@ export function dependencyConfig(
193203
cxxModuleCMakeListsModuleName,
194204
cxxModuleCMakeListsPath,
195205
cxxModuleHeaderName,
206+
isPureCxxDependency,
196207
};
197208
}

packages/cli-types/src/android.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export type AndroidProjectParams = {
2525

2626
export type AndroidDependencyConfig = {
2727
sourceDir: string;
28-
packageImportPath: string;
29-
packageInstance: string;
28+
packageImportPath: string | null;
29+
packageInstance: string | null;
3030
dependencyConfiguration?: string;
3131
buildTypes: string[];
3232
libraryName?: string | null;
@@ -35,6 +35,7 @@ export type AndroidDependencyConfig = {
3535
cxxModuleCMakeListsModuleName?: string | null;
3636
cxxModuleCMakeListsPath?: string | null;
3737
cxxModuleHeaderName?: string | null;
38+
isPureCxxDependency?: boolean;
3839
};
3940

4041
export type AndroidDependencyParams = {

0 commit comments

Comments
 (0)