Skip to content

Commit

Permalink
Handle non-standard codegen output dirs (#165)
Browse files Browse the repository at this point in the history
Fixes: #161
  • Loading branch information
Johennes authored Nov 26, 2024
1 parent bf3e7b9 commit 59bc61e
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 4 deletions.
1 change: 1 addition & 0 deletions .github/workflows/compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ jobs:
--builder-bob-version ${{ matrix.bob-version }} \
--rn-version ${{ matrix.rn-version }} \
--packgage-json-mixin integration/fixtures/compat/package.json \
--react-native-config integration/fixtures/compat/react-native.config.js \
--${{ matrix.runner == 'macos-latest' && 'ios' || 'android' }} \
../turbo-module
11 changes: 11 additions & 0 deletions crates/ubrn_cli/src/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ pub(crate) struct AndroidConfig {

#[serde(default = "AndroidConfig::default_package_name")]
pub(crate) package_name: String,

#[serde(default = "AndroidConfig::default_codegen_output_dir")]
pub(crate) codegen_output_dir: String,
}

impl Default for AndroidConfig {
Expand Down Expand Up @@ -82,13 +85,21 @@ impl AndroidConfig {
fn default_jni_libs() -> String {
"src/main/jniLibs".to_string()
}

fn default_codegen_output_dir() -> String {
workspace::package_json().android_codegen_output_dir()
}
}

impl AndroidConfig {
pub(crate) fn directory(&self, project_root: &Utf8Path) -> Utf8PathBuf {
project_root.join(&self.directory)
}

pub(crate) fn codegen_output_dir(&self, project_root: &Utf8Path) -> Utf8PathBuf {
project_root.join(&self.codegen_output_dir)
}

pub(crate) fn jni_libs(&self, project_root: &Utf8Path) -> Utf8PathBuf {
self.directory(project_root).join(&self.jni_libs)
}
Expand Down
2 changes: 2 additions & 0 deletions crates/ubrn_cli/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,15 @@ mod tests {
cargo_extras: ExtraArgs::default(),
api_level: 21,
package_name: "com.tester".to_string(),
codegen_output_dir: "android/generated".to_string(),
};
let ios = IOsConfig {
directory: "ios".to_string(),
framework_name: "MyRustCrateFramework".to_string(),
xcodebuild_extras: ExtraArgs::default(),
targets: Default::default(),
cargo_extras: ExtraArgs::default(),
codegen_output_dir: "ios/generated".to_string(),
};
let bindings = BindingsConfig {
cpp: "cpp/bindings".to_string(),
Expand Down
7 changes: 5 additions & 2 deletions crates/ubrn_cli/src/codegen/templates/build.kt.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,11 @@ android {
main {
if (isNewArchitectureEnabled()) {
java.srcDirs += [
"generated/java",
"generated/jni"
{%- let root = self.project_root() %}
{%- let dir = self.config.project.android.codegen_output_dir(root) %}
{%- let codegen = self.relative_to(root, dir) %}
"{{ codegen }}/java",
"{{ codegen }}/jni"
]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ Pod::Spec.new do |s|
{%- let framework = self.relative_to(root, dir) %}
{%- let dir = self.config.project.ios.directory(root) %}
{%- let ios = self.relative_to(root, dir) %}
{%- let dir = self.config.project.ios.codegen_output_dir(root) %}
{%- let codegen = self.relative_to(root, dir) %}
{%- let dir = self.config.project.tm.cpp_path(root) %}
{%- let tm = self.relative_to(root, dir) %}
{%- let dir = self.config.project.bindings.cpp_path(root) %}
{%- let bindings = self.relative_to(root, dir) -%}
s.source_files = "{{ ios }}/**/*.{h,m,mm}", "{{ tm }}/**/*.{hpp,cpp,c,h}", "{{ bindings }}/**/*.{hpp,cpp,c,h}"
s.source_files = "{{ ios }}/**/*.{h,m,mm}", "{{ codegen }}/**/*.{h,m,mm}", "{{ tm }}/**/*.{hpp,cpp,c,h}", "{{ bindings }}/**/*.{hpp,cpp,c,h}"
s.vendored_frameworks = "{{ framework }}"
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
Expand Down
36 changes: 36 additions & 0 deletions crates/ubrn_cli/src/config/npm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ impl PackageJson {
}
}

pub(crate) fn android_codegen_output_dir(&self) -> String {
self.codegen_config.output_dir.android.clone()
}

pub(crate) fn ios_codegen_output_dir(&self) -> String {
self.codegen_config.output_dir.ios.clone()
}

pub(crate) fn repo(&self) -> &PackageJsonRepo {
&self.repository
}
Expand All @@ -69,6 +77,8 @@ pub(crate) struct RnCodegenConfig {
pub(crate) js_srcs_dir: String,
#[serde(default)]
android: RnAndroidCodegenConfig,
#[serde(default)]
output_dir: RnOutputDirCodegenConfig,
}

impl Default for RnCodegenConfig {
Expand All @@ -82,3 +92,29 @@ impl Default for RnCodegenConfig {
struct RnAndroidCodegenConfig {
java_package_name: Option<String>,
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct RnOutputDirCodegenConfig {
#[serde(default = "default_ios_codegen_output_dir")]
ios: String,
#[serde(default = "default_android_codegen_output_dir")]
android: String,
}

impl Default for RnOutputDirCodegenConfig {
fn default() -> Self {
Self {
ios: default_ios_codegen_output_dir(),
android: default_android_codegen_output_dir(),
}
}
}

fn default_android_codegen_output_dir() -> String {
"android/generated".to_string()
}

fn default_ios_codegen_output_dir() -> String {
"ios/generated".to_string()
}
11 changes: 11 additions & 0 deletions crates/ubrn_cli/src/ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ pub(crate) struct IOsConfig {

#[serde(default = "IOsConfig::default_cargo_extras")]
pub(crate) cargo_extras: ExtraArgs,

#[serde(default = "IOsConfig::default_codegen_output_dir")]
pub(crate) codegen_output_dir: String,
}

impl IOsConfig {
Expand Down Expand Up @@ -74,6 +77,10 @@ impl IOsConfig {
let args: &[&str] = &["aarch64-apple-ios", sim_target];
args.iter().map(|s| Target::from_str(s).unwrap()).collect()
}

fn default_codegen_output_dir() -> String {
workspace::package_json().ios_codegen_output_dir()
}
}

impl Default for IOsConfig {
Expand All @@ -87,6 +94,10 @@ impl IOsConfig {
project_root.join(&self.directory)
}

pub(crate) fn codegen_output_dir(&self, project_root: &Utf8Path) -> Utf8PathBuf {
project_root.join(&self.codegen_output_dir)
}

pub(crate) fn framework_path(&self, project_root: &Utf8Path) -> Utf8PathBuf {
let filename = format!("{}.xcframework", self.framework_name);
project_root.join(filename)
Expand Down
18 changes: 17 additions & 1 deletion docs/src/reference/config-yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ android:
apiLevel: 21
jniLibs: src/main/jniLibs
packageName: <DERIVED FROM package.json>
codegenOutputDir: <DERIVED FROM package.json>
```

The `directory` is the location of the Android project, relative to the root of the React Native library project.
Expand All @@ -91,10 +92,16 @@ The `directory` is the location of the Android project, relative to the root of
Reducing the number of targets to build for will speed up the edit-compile-run cycle.
```

`packageName` is the name of the Android package that Codegen used to generate the TurboModule. This is derived from the `package.json` file, and can almost always be left.
`packageName` is the name of the Android package that Codegen used to generate the TurboModule. `codegenOutputDir` is the path under which Codegen stores its generated files. Both are derived from the `package.json` file, and can almost always be left.

To customize the `packageName`, you should edit or add the entry at the path `codegenConfig`/`android`/`javaPackageName` in `package.json`.

To customize the `codegenOutputDir`, you should edit or add the entry at the path `codegenConfig`/`outputDir`/`android` in `package.json`.

```admonish warning
Note that for Android the `outputDir` value in `package.json` needs to have a matching entry under `dependency`/`platforms`/`android`/`cmakeListsPath` in `react-native.config.js`. For example, if you set the Android output directory in `package.json` to `android/tmp`, the `cmakeListsPath` value in `react-native.config.js` needs to be set to `tmp/jni/CMakeLists.txt`.
```

## `ios`

This is to configure the build steps for the Rust, the bindings, and the turbo-module code for iOS.
Expand All @@ -110,6 +117,7 @@ ios:
- aarch64-apple-ios-sim
xcodebuildExtras: []
frameworkName: build/MyFramework
codegenOutputDir: <DERIVED FROM package.json>
```


Expand All @@ -121,6 +129,14 @@ The `directory` is the location of the iOS project, relative to the root of the

`xcodebuildExtras` is a list of extra arguments passed directly to the `xcodebuild` command.

`codegenOutputDir` is the path under which Codegen stores its generated files. This is derived from the `package.json` file, and can almost always be left.

To customize the `codegenOutputDir`, you should edit or add the entry at the path `codegenConfig`/`outputDir`/`ios` in `package.json`.

```admonish warning
Note that for Android the `outputDir` value in `package.json` needs to have a matching entry under `dependency`/`platforms`/`android`/`cmakeListsPath` in `react-native.config.js`. For example, if you set the Android output directory in `package.json` to `android/tmp`, the `cmakeListsPath` value in `react-native.config.js` needs to be set to `tmp/jni/CMakeLists.txt`.
```

## `turboModule`

This section configures the location of the Typescript and C++ files generated by the `generate turbo-module` command.
Expand Down
9 changes: 9 additions & 0 deletions integration/fixtures/compat/react-native.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
dependency: {
platforms: {
android: {
cmakeListsPath: "tmp/jni/CMakeLists.txt",
},
},
},
};
9 changes: 9 additions & 0 deletions scripts/test-turbo-modules.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ reset_args() {
SKIP_ANDROID=true
UBRN_CONFIG=
PACKAGE_JSON_MIXIN=
REACT_NATIVE_CONFIG=
APP_TSX=
}

Expand All @@ -26,6 +27,7 @@ usage() {
echo " -I, --ios Build for iOS."
echo " -C, --ubrn-config Use a ubrn config file."
echo " -P, --packgage-json-mixin Merge another JSON file into package.json"
echo " -R, --react-native-config Use a react-native.config.js file"
echo " -T, --app-tsx Use a App.tsx file."
echo
echo " -s, --slug PROJECT_SLUG Specify the project slug (default: my-test-library)."
Expand Down Expand Up @@ -105,6 +107,10 @@ parse_cli_options() {
PACKAGE_JSON_MIXIN=$(join_paths "$PWD" "$2")
shift
;;
-R|--react-native-config)
REACT_NATIVE_CONFIG=$(join_paths "$PWD" "$2")
shift
;;
-T|--app-tsx)
APP_TSX=$(join_paths "$PWD" "$2")
shift
Expand Down Expand Up @@ -302,6 +308,9 @@ generate_turbo_module_for_compiling() {
jq -s '.[0] * .[1]' ./package.json "$PACKAGE_JSON_MIXIN" > ./package.json.new
mv ./package.json.new ./package.json
fi
if [ -f "$REACT_NATIVE_CONFIG" ] ; then
cp "$REACT_NATIVE_CONFIG" ./react-native.config.js
fi
if [ -f "$APP_TSX" ] ; then
cp "$APP_TSX" ./example/src/App.tsx
fi
Expand Down

0 comments on commit 59bc61e

Please sign in to comment.