Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/tired-news-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"ferric-cli": patch
---

- Add path as arg to build project.
- Changed default build output to send to dist folder.
4 changes: 2 additions & 2 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export default tseslint.config(
"apps/test-app/ios/**",
"packages/host/hermes/**",
"packages/node-addon-examples/examples/**",
"packages/ferric-example/ferric_example.js",
"packages/ferric-example/ferric_example.d.ts",
"packages/ferric-example/dist/ferric_example.d.ts",
"packages/ferric-example/dist/ferric_example.js",
"packages/ferric-example/target/**",
"packages/node-tests/node/**",
"packages/node-tests/tests/**",
Expand Down
51 changes: 22 additions & 29 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions packages/ferric-example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ Cargo.lock
/*.apple.node/
/*.android.node/

# Generated files
/ferric_example.d.ts
/ferric_example.js
dist
4 changes: 2 additions & 2 deletions packages/ferric-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"url": "git+https://github.com/callstackincubator/react-native-node-api.git",
"directory": "packages/ferric-example"
},
"main": "ferric_example.js",
"types": "ferric_example.d.ts",
"main": "dist/ferric_example.js",
"types": "dist/ferric_example.d.ts",
"scripts": {
"build": "ferric build",
"bootstrap": "npm run build"
Expand Down
15 changes: 14 additions & 1 deletion packages/ferric/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# `ferric`
# `ferric` (ESM Module)

A wrapper around Cargo making it easier to produce prebuilt binaries targeting iOS and Android matching the [the prebuilt binary specification](https://github.com/callstackincubator/react-native-node-api/blob/main/docs/PREBUILDS.md) as well as [napi.rs](https://napi.rs/) to generate bindings from annotated Rust code.

## Install the project

`npm install --save-dev ferric-cli`

## Add scripts

```json
"scripts": {
"build": "ferric build --cwd folder_path",
"build:release": "npm run build -- --configuration release",
},
```
12 changes: 6 additions & 6 deletions packages/ferric/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
"start": "tsx src/run.ts"
},
"dependencies": {
"@napi-rs/cli": "~3.0.3",
"@commander-js/extra-typings": "^13.1.0",
"bufout": "^0.3.2",
"@commander-js/extra-typings": "14.0.0",
"@napi-rs/cli": "~3.0.4",
"bufout": "0.3.4",
"chalk": "^5.4.1",
"commander": "^13.1.0",
"react-native-node-api": "0.3.2",
"ora": "^8.2.0"
"commander": "14.0.0",
"ora": "^8.2.0",
"react-native-node-api": "0.3.2"
}
}
43 changes: 27 additions & 16 deletions packages/ferric/src/build.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
import path from "node:path";
import fs from "node:fs";
import path from "node:path";

import { Command, Option } from "@commander-js/extra-typings";
import chalk from "chalk";
import { SpawnFailure } from "bufout";
import chalk from "chalk";
import { oraPromise } from "ora";

import {
determineAndroidLibsFilename,
type AndroidTriplet,
createAndroidLibsDirectory,
AndroidTriplet,
createAppleFramework,
determineXCFrameworkFilename,
createXCframework,
createUniversalAppleLibrary,
createXCframework,
determineAndroidLibsFilename,
determineLibraryBasename,
determineXCFrameworkFilename,
prettyPath,
} from "react-native-node-api";

import { UsageError, assertFixable } from "./errors.js";
import { ensureCargo, build } from "./cargo.js";
import { getBlockComment } from "./banner.js";
import { build, ensureCargo } from "./cargo.js";
import { assertFixable, UsageError } from "./errors.js";
import { generateTypeScriptDeclarations } from "./napi-rs.js";
import {
ALL_TARGETS,
ANDROID_TARGETS,
AndroidTargetName,
type AndroidTargetName,
APPLE_TARGETS,
AppleTargetName,
type AppleTargetName,
ensureInstalledTargets,
filterTargetsByPlatform,
} from "./targets.js";
import { generateTypeScriptDeclarations } from "./napi-rs.js";
import { getBlockComment } from "./banner.js";

type EntrypointOptions = {
outputPath: string;
Expand Down Expand Up @@ -97,6 +96,7 @@ const outputPathOption = new Option(
"--output <path>",
"Writing outputs to this directory",
).default(process.cwd());
const cwdPathOption = new Option("--cwd <path>", "Specify project path");
const configurationOption = new Option(
"--configuration <configuration>",
"Build configuration",
Expand All @@ -111,6 +111,7 @@ export const buildCommand = new Command("build")
.addOption(androidTarget)
.addOption(ndkVersionOption)
.addOption(outputPathOption)
.addOption(cwdPathOption)
.addOption(configurationOption)
.addOption(xcframeworkExtensionOption)
.action(
Expand All @@ -120,9 +121,15 @@ export const buildCommand = new Command("build")
android,
ndkVersion,
output: outputPath,
cwd: cwdPath,
configuration,
xcframeworkExtension,
}) => {
const sourcePath =
cwdPath && cwdPath.length > 0
? path.join(outputPath, cwdPath)
: outputPath;
outputPath = path.join(sourcePath, "dist");
try {
const targets = new Set([...targetArg]);
if (apple) {
Expand Down Expand Up @@ -175,7 +182,10 @@ export const buildCommand = new Command("build")
Promise.all(
appleTargets.map(
async (target) =>
[target, await build({ configuration, target })] as const,
[
target,
await build({ configuration, target, sourcePath }),
] as const,
),
),
Promise.all(
Expand All @@ -186,6 +196,7 @@ export const buildCommand = new Command("build")
await build({
configuration,
target,
sourcePath,
ndkVersion,
androidApiLevel: ANDROID_API_LEVEL,
}),
Expand Down Expand Up @@ -256,7 +267,7 @@ export const buildCommand = new Command("build")
{
text: "Assembling XCFramework",
successText: `XCFramework assembled into ${chalk.dim(
path.relative(process.cwd(), xcframeworkOutputPath),
path.relative(outputPath, xcframeworkOutputPath),
)}`,
failText: ({ message }) =>
`Failed to assemble XCFramework: ${message}`,
Expand All @@ -274,7 +285,7 @@ export const buildCommand = new Command("build")
await oraPromise(
generateTypeScriptDeclarations({
outputFilename: declarationsFilename,
createPath: process.cwd(),
createPath: sourcePath,
outputPath,
}),
{
Expand Down
22 changes: 14 additions & 8 deletions packages/ferric/src/cargo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@ import path from "node:path";

import { spawn } from "bufout";
import chalk from "chalk";

import { weakNodeApiPath } from "react-native-node-api";
import { assertFixable, UsageError } from "./errors.js";
import {
AndroidTargetName,
AppleTargetName,
type AndroidTargetName,
type AppleTargetName,
isAndroidTarget,
isAppleTarget,
} from "./targets.js";

import { weakNodeApiPath } from "react-native-node-api";

const APPLE_XCFRAMEWORK_CHILDS_PER_TARGET: Record<AppleTargetName, string> = {
"aarch64-apple-darwin": "macos-arm64_x86_64", // Universal
"x86_64-apple-darwin": "macos-arm64_x86_64", // Universal
Expand Down Expand Up @@ -61,6 +59,7 @@ export function ensureCargo() {

type BuildOptions = {
configuration: "debug" | "release";
sourcePath: string;
} & (
| {
target: AndroidTargetName;
Expand All @@ -75,8 +74,15 @@ type BuildOptions = {
);

export async function build(options: BuildOptions) {
const { target, configuration } = options;
const args = ["build", "--target", target];
const { target, configuration, sourcePath } = options;
const manifestBuildPath = `${sourcePath}/Cargo.toml`;
const args = [
"build",
"--target",
target,
"--manifest-path",
manifestBuildPath,
];
if (configuration.toLowerCase() === "release") {
args.push("--release");
}
Expand All @@ -88,7 +94,7 @@ export async function build(options: BuildOptions) {
},
});
const targetOutputPath = joinPathAndAssertExistence(
process.cwd(),
sourcePath,
"target",
target,
configuration,
Expand Down
Loading