diff --git a/.changeset/better-pets-help.md b/.changeset/better-pets-help.md new file mode 100644 index 00000000..904acf2c --- /dev/null +++ b/.changeset/better-pets-help.md @@ -0,0 +1,5 @@ +--- +"ferric-cli": patch +--- + +Add x86_64 ios simulator target and output universal libraries for iOS simulators. diff --git a/.changeset/large-hornets-burn.md b/.changeset/large-hornets-burn.md new file mode 100644 index 00000000..c7ad76f4 --- /dev/null +++ b/.changeset/large-hornets-burn.md @@ -0,0 +1,5 @@ +--- +"ferric-cli": patch +--- + +It's no longer required to pass "build" to ferric, as this is default now diff --git a/packages/ferric/src/build.ts b/packages/ferric/src/build.ts index a3eb1684..4dd26d87 100644 --- a/packages/ferric/src/build.ts +++ b/packages/ferric/src/build.ts @@ -311,34 +311,54 @@ export const buildCommand = new Command("build") ), ); +async function createUniversalAppleLibraries(libraryPathGroups: string[][]) { + const result = await oraPromise( + Promise.all( + libraryPathGroups.map(async (libraryPaths) => { + if (libraryPaths.length === 0) { + return []; + } else if (libraryPaths.length === 1) { + return libraryPaths; + } else { + return [await createUniversalAppleLibrary(libraryPaths)]; + } + }), + ), + { + text: "Combining arch-specific libraries into universal libraries", + successText: "Combined arch-specific libraries into universal libraries", + failText: (error) => + `Failed to combine arch-specific libraries: ${error.message}`, + }, + ); + return result.flat(); +} + async function combineLibraries( libraries: Readonly<[AppleTargetName, string]>[], ): Promise { const result = []; const darwinLibraries = []; + const iosSimulatorLibraries = []; for (const [target, libraryPath] of libraries) { if (target.endsWith("-darwin")) { darwinLibraries.push(libraryPath); + } else if ( + target === "aarch64-apple-ios-sim" || + target === "x86_64-apple-ios" // Simulator despite name missing -sim suffix + ) { + iosSimulatorLibraries.push(libraryPath); } else { result.push(libraryPath); } } - if (darwinLibraries.length === 0) { - return result; - } else if (darwinLibraries.length === 1) { - return [...result, darwinLibraries[0]]; - } else { - const universalPath = await oraPromise( - createUniversalAppleLibrary(darwinLibraries), - { - text: "Combining Darwin libraries into a universal library", - successText: "Combined Darwin libraries into a universal library", - failText: (error) => - `Failed to combine Darwin libraries: ${error.message}`, - }, - ); - return [...result, universalPath]; - } + + const combinedLibraryPaths = await createUniversalAppleLibraries([ + darwinLibraries, + iosSimulatorLibraries, + ]); + + return [...result, ...combinedLibraryPaths]; } export function isAndroidSupported() { diff --git a/packages/ferric/src/cargo.ts b/packages/ferric/src/cargo.ts index b4a06f16..7b665b98 100644 --- a/packages/ferric/src/cargo.ts +++ b/packages/ferric/src/cargo.ts @@ -21,10 +21,12 @@ import { const APPLE_XCFRAMEWORK_CHILDS_PER_TARGET: Record = { "aarch64-apple-darwin": "macos-arm64_x86_64", // Universal "x86_64-apple-darwin": "macos-arm64_x86_64", // Universal + "aarch64-apple-ios": "ios-arm64", "aarch64-apple-ios-sim": "ios-arm64_x86_64-simulator", // Universal + "x86_64-apple-ios": "ios-arm64_x86_64-simulator", // Universal + // "aarch64-apple-ios-macabi": "", // Catalyst - // "x86_64-apple-ios": "ios-x86_64", // "x86_64-apple-ios-macabi": "ios-x86_64-simulator", // "aarch64-apple-tvos": "tvos-arm64", // "aarch64-apple-tvos-sim": "tvos-arm64-simulator", @@ -216,6 +218,10 @@ export function getTargetEnvironmentVariables({ }; } else if (isAppleTarget(target)) { const weakNodeApiFrameworkPath = getWeakNodeApiFrameworkPath(target); + assert( + fs.existsSync(weakNodeApiFrameworkPath), + `Expected weak-node-api framework at ${weakNodeApiFrameworkPath}`, + ); return { CARGO_ENCODED_RUSTFLAGS: [ "-L", diff --git a/packages/ferric/src/program.ts b/packages/ferric/src/program.ts index 422c4ecc..d47d0479 100644 --- a/packages/ferric/src/program.ts +++ b/packages/ferric/src/program.ts @@ -6,4 +6,4 @@ import { buildCommand } from "./build.js"; export const program = new Command("ferric") .hook("preAction", () => printBanner()) .description("Rust Node-API Modules for React Native") - .addCommand(buildCommand); + .addCommand(buildCommand, { isDefault: true }); diff --git a/packages/ferric/src/targets.ts b/packages/ferric/src/targets.ts index b7696a10..0e548de6 100644 --- a/packages/ferric/src/targets.ts +++ b/packages/ferric/src/targets.ts @@ -16,10 +16,12 @@ export type AndroidTargetName = (typeof ANDROID_TARGETS)[number]; export const APPLE_TARGETS = [ "aarch64-apple-darwin", "x86_64-apple-darwin", + "aarch64-apple-ios", "aarch64-apple-ios-sim", + "x86_64-apple-ios", // Simulator (despite the missing -sim suffix) + // "aarch64-apple-ios-macabi", // Catalyst - // "x86_64-apple-ios", // "x86_64-apple-ios-macabi", // Catalyst // TODO: Re-enabled these when we know how to install them 🙈 diff --git a/packages/host/src/node/prebuilds/apple.ts b/packages/host/src/node/prebuilds/apple.ts index 9054965e..1aeb9658 100644 --- a/packages/host/src/node/prebuilds/apple.ts +++ b/packages/host/src/node/prebuilds/apple.ts @@ -131,11 +131,17 @@ export function determineXCFrameworkFilename( } export async function createUniversalAppleLibrary(libraryPaths: string[]) { + assert( + libraryPaths.length > 0, + "Expected at least one library to create a universal library", + ); // Determine the output path const filenames = new Set(libraryPaths.map((p) => path.basename(p))); assert( filenames.size === 1, - "Expected all darwin libraries to have the same name", + `Expected libraries to have the same name, but got: ${[...filenames].join( + ", ", + )}`, ); const [filename] = filenames; const lipoParentPath = fs.realpathSync(