From ae4fc878ae25d8f048ac9782e71c6af8901624f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 24 Sep 2025 13:22:37 +0200 Subject: [PATCH 1/7] Use CMake file API to read shared library target paths --- .changeset/evil-vans-love.md | 5 +++ package-lock.json | 1 + packages/cmake-rn/package.json | 1 + packages/cmake-rn/src/cli.ts | 3 ++ packages/cmake-rn/src/platforms/android.ts | 44 ++++++++++++--------- packages/cmake-rn/src/platforms/apple.ts | 45 +++++++++++----------- 6 files changed, 58 insertions(+), 41 deletions(-) create mode 100644 .changeset/evil-vans-love.md diff --git a/.changeset/evil-vans-love.md b/.changeset/evil-vans-love.md new file mode 100644 index 00000000..873d1d86 --- /dev/null +++ b/.changeset/evil-vans-love.md @@ -0,0 +1,5 @@ +--- +"cmake-rn": patch +--- + +Use CMake file API to read shared library target paths diff --git a/package-lock.json b/package-lock.json index 02024acc..16c9a3d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14808,6 +14808,7 @@ "version": "0.4.0", "dependencies": { "@react-native-node-api/cli-utils": "0.1.0", + "cmake-file-api": "0.1.0", "react-native-node-api": "0.5.1" }, "bin": { diff --git a/packages/cmake-rn/package.json b/packages/cmake-rn/package.json index f78644da..91fa1bde 100644 --- a/packages/cmake-rn/package.json +++ b/packages/cmake-rn/package.json @@ -23,6 +23,7 @@ }, "dependencies": { "@react-native-node-api/cli-utils": "0.1.0", + "cmake-file-api": "0.1.0", "react-native-node-api": "0.5.1" }, "peerDependencies": { diff --git a/packages/cmake-rn/src/cli.ts b/packages/cmake-rn/src/cli.ts index 5afa8932..a7d56530 100644 --- a/packages/cmake-rn/src/cli.ts +++ b/packages/cmake-rn/src/cli.ts @@ -13,6 +13,7 @@ import { wrapAction, } from "@react-native-node-api/cli-utils"; import { isSupportedTriplet } from "react-native-node-api"; +import * as cmakeFileApi from "cmake-file-api"; import { getCmakeJSVariables, @@ -327,6 +328,8 @@ async function configureProject( { CMAKE_LIBRARY_OUTPUT_DIRECTORY: outputPath }, ]; + await cmakeFileApi.createSharedStatelessQuery(buildPath, "codemodel", "2"); + await spawn( "cmake", [ diff --git a/packages/cmake-rn/src/platforms/android.ts b/packages/cmake-rn/src/platforms/android.ts index 832f806e..688ddb86 100644 --- a/packages/cmake-rn/src/platforms/android.ts +++ b/packages/cmake-rn/src/platforms/android.ts @@ -8,6 +8,7 @@ import { determineAndroidLibsFilename, AndroidTriplet as Triplet, } from "react-native-node-api"; +import * as cmakeFileApi from "cmake-file-api"; import type { Platform } from "./types.js"; @@ -121,28 +122,35 @@ export const platform: Platform = { const { ANDROID_HOME } = process.env; return typeof ANDROID_HOME === "string" && fs.existsSync(ANDROID_HOME); }, - async postBuild({ outputPath, triplets }, { autoLink }) { - // TODO: Include `configuration` in the output path + async postBuild({ outputPath, triplets }, { autoLink, configuration }) { const libraryPathByTriplet = Object.fromEntries( await Promise.all( - triplets.map(async ({ triplet, outputPath }) => { + triplets.map(async ({ triplet, buildPath }) => { assert( - fs.existsSync(outputPath), - `Expected a directory at ${outputPath}`, + fs.existsSync(buildPath), + `Expected a directory at ${buildPath}`, ); - // Expect binary file(s), either .node or .so - const dirents = await fs.promises.readdir(outputPath, { - withFileTypes: true, - }); - const result = dirents - .filter( - (dirent) => - dirent.isFile() && - (dirent.name.endsWith(".so") || dirent.name.endsWith(".node")), - ) - .map((dirent) => path.join(dirent.parentPath, dirent.name)); - assert.equal(result.length, 1, "Expected exactly one library file"); - return [triplet, result[0]] as const; + const targets = await cmakeFileApi.readCurrentTargetsDeep( + buildPath, + configuration, + "2.0", + ); + const sharedLibraries = targets.filter( + (target) => target.type === "SHARED_LIBRARY", + ); + assert.equal( + sharedLibraries.length, + 1, + "Expected exactly one shared library", + ); + const [sharedLibrary] = sharedLibraries; + const { artifacts } = sharedLibrary; + assert( + artifacts && artifacts.length, + "Expected exactly one artifact", + ); + const [artifact] = artifacts; + return [triplet, path.join(buildPath, artifact.path)] as const; }), ), ) as Record; diff --git a/packages/cmake-rn/src/platforms/apple.ts b/packages/cmake-rn/src/platforms/apple.ts index 00e21c72..7eb71392 100644 --- a/packages/cmake-rn/src/platforms/apple.ts +++ b/packages/cmake-rn/src/platforms/apple.ts @@ -11,6 +11,7 @@ import { } from "react-native-node-api"; import type { Platform } from "./types.js"; +import * as cmakeFileApi from "cmake-file-api"; type XcodeSDKName = | "iphoneos" @@ -136,31 +137,29 @@ export const platform: Platform = { { configuration, autoLink, xcframeworkExtension }, ) { const libraryPaths = await Promise.all( - triplets.map(async ({ outputPath }) => { - const configSpecificPath = path.join(outputPath, configuration); + triplets.map(async ({ buildPath }) => { assert( - fs.existsSync(configSpecificPath), - `Expected a directory at ${configSpecificPath}`, + fs.existsSync(buildPath), + `Expected a directory at ${buildPath}`, ); - // Expect binary file(s), either .node or .dylib - const files = await fs.promises.readdir(configSpecificPath); - const result = files.map(async (file) => { - const filePath = path.join(configSpecificPath, file); - if (filePath.endsWith(".dylib")) { - return filePath; - } else if (file.endsWith(".node")) { - // Rename the file to .dylib for xcodebuild to accept it - const newFilePath = filePath.replace(/\.node$/, ".dylib"); - await fs.promises.rename(filePath, newFilePath); - return newFilePath; - } else { - throw new Error( - `Expected a .node or .dylib file, but found ${file}`, - ); - } - }); - assert.equal(result.length, 1, "Expected exactly one library file"); - return await result[0]; + const targets = await cmakeFileApi.readCurrentTargetsDeep( + buildPath, + configuration, + "2.0", + ); + const sharedLibraries = targets.filter( + (target) => target.type === "SHARED_LIBRARY", + ); + assert.equal( + sharedLibraries.length, + 1, + "Expected exactly one shared library", + ); + const [sharedLibrary] = sharedLibraries; + const { artifacts } = sharedLibrary; + assert(artifacts && artifacts.length, "Expected exactly one artifact"); + const [artifact] = artifacts; + return path.join(buildPath, artifact.path); }), ); const frameworkPaths = libraryPaths.map(createAppleFramework); From 0d6edf65ff365dbb2fc6eed359081b24886731df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 24 Sep 2025 16:48:16 +0200 Subject: [PATCH 2/7] Refactor createAppleFramework into an async function --- packages/ferric/src/build.ts | 4 +++- packages/host/src/node/prebuilds/apple.ts | 13 +++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/ferric/src/build.ts b/packages/ferric/src/build.ts index d5cbaad7..33ab568d 100644 --- a/packages/ferric/src/build.ts +++ b/packages/ferric/src/build.ts @@ -238,7 +238,9 @@ export const buildCommand = new Command("build") if (appleLibraries.length > 0) { const libraryPaths = await combineLibraries(appleLibraries); - const frameworkPaths = libraryPaths.map(createAppleFramework); + const frameworkPaths = await Promise.all( + libraryPaths.map(createAppleFramework), + ); const xcframeworkFilename = determineXCFrameworkFilename( frameworkPaths, xcframeworkExtension ? ".xcframework" : ".apple.node", diff --git a/packages/host/src/node/prebuilds/apple.ts b/packages/host/src/node/prebuilds/apple.ts index 693c90b6..b8bff129 100644 --- a/packages/host/src/node/prebuilds/apple.ts +++ b/packages/host/src/node/prebuilds/apple.ts @@ -45,7 +45,7 @@ type XCframeworkOptions = { autoLink: boolean; }; -export function createAppleFramework(libraryPath: string) { +export async function createAppleFramework(libraryPath: string) { assert(fs.existsSync(libraryPath), `Library not found: ${libraryPath}`); // Write a info.plist file to the framework const libraryName = path.basename(libraryPath, path.extname(libraryPath)); @@ -54,11 +54,11 @@ export function createAppleFramework(libraryPath: string) { `${libraryName}.framework`, ); // Create the framework from scratch - fs.rmSync(frameworkPath, { recursive: true, force: true }); - fs.mkdirSync(frameworkPath); - fs.mkdirSync(path.join(frameworkPath, "Headers")); + await fs.promises.rm(frameworkPath, { recursive: true, force: true }); + await fs.promises.mkdir(frameworkPath); + await fs.promises.mkdir(path.join(frameworkPath, "Headers")); // Create an empty Info.plist file - fs.writeFileSync( + await fs.promises.writeFile( path.join(frameworkPath, "Info.plist"), createPlistContent({ CFBundleDevelopmentRegion: "en", @@ -75,8 +75,9 @@ export function createAppleFramework(libraryPath: string) { ); const newLibraryPath = path.join(frameworkPath, libraryName); // TODO: Consider copying the library instead of renaming it - fs.renameSync(libraryPath, newLibraryPath); + await fs.promises.rename(libraryPath, newLibraryPath); // Update the name of the library + // TODO: Make this call async cp.spawnSync("install_name_tool", [ "-id", `@rpath/${libraryName}.framework/${libraryName}`, From e2ede36a1b8593fb65a307fa650117bb69bce9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 24 Sep 2025 16:48:43 +0200 Subject: [PATCH 3/7] Correcting createAndroidLibsDirectory types --- packages/host/src/node/prebuilds/android.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/host/src/node/prebuilds/android.ts b/packages/host/src/node/prebuilds/android.ts index b24b422b..788e2936 100644 --- a/packages/host/src/node/prebuilds/android.ts +++ b/packages/host/src/node/prebuilds/android.ts @@ -32,7 +32,7 @@ export function determineAndroidLibsFilename(libraryPaths: string[]) { type AndroidLibsDirectoryOptions = { outputPath: string; - libraryPathByTriplet: Record; + libraryPathByTriplet: Partial>; autoLink: boolean; }; From 7dc30789e4b9ecf4cb861faf783c992da44e4144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 24 Sep 2025 16:49:17 +0200 Subject: [PATCH 4/7] Support multiple shared library outputs --- packages/cmake-rn/src/platforms/android.ts | 104 ++++++++++---------- packages/cmake-rn/src/platforms/apple.ts | 105 +++++++++++---------- 2 files changed, 108 insertions(+), 101 deletions(-) diff --git a/packages/cmake-rn/src/platforms/android.ts b/packages/cmake-rn/src/platforms/android.ts index 688ddb86..44db5659 100644 --- a/packages/cmake-rn/src/platforms/android.ts +++ b/packages/cmake-rn/src/platforms/android.ts @@ -5,7 +5,6 @@ import path from "node:path"; import { Option, oraPromise, chalk } from "@react-native-node-api/cli-utils"; import { createAndroidLibsDirectory, - determineAndroidLibsFilename, AndroidTriplet as Triplet, } from "react-native-node-api"; import * as cmakeFileApi from "cmake-file-api"; @@ -123,56 +122,59 @@ export const platform: Platform = { return typeof ANDROID_HOME === "string" && fs.existsSync(ANDROID_HOME); }, async postBuild({ outputPath, triplets }, { autoLink, configuration }) { - const libraryPathByTriplet = Object.fromEntries( - await Promise.all( - triplets.map(async ({ triplet, buildPath }) => { - assert( - fs.existsSync(buildPath), - `Expected a directory at ${buildPath}`, - ); - const targets = await cmakeFileApi.readCurrentTargetsDeep( - buildPath, - configuration, - "2.0", - ); - const sharedLibraries = targets.filter( - (target) => target.type === "SHARED_LIBRARY", - ); - assert.equal( - sharedLibraries.length, - 1, - "Expected exactly one shared library", - ); - const [sharedLibrary] = sharedLibraries; - const { artifacts } = sharedLibrary; - assert( - artifacts && artifacts.length, - "Expected exactly one artifact", - ); - const [artifact] = artifacts; - return [triplet, path.join(buildPath, artifact.path)] as const; - }), - ), - ) as Record; - const androidLibsFilename = determineAndroidLibsFilename( - Object.values(libraryPathByTriplet), - ); - const androidLibsOutputPath = path.resolve(outputPath, androidLibsFilename); + const prebuilds: Record>> = {}; - await oraPromise( - createAndroidLibsDirectory({ - outputPath: androidLibsOutputPath, - libraryPathByTriplet, - autoLink, - }), - { - text: "Assembling Android libs directory", - successText: `Android libs directory assembled into ${chalk.dim( - path.relative(process.cwd(), androidLibsOutputPath), - )}`, - failText: ({ message }) => - `Failed to assemble Android libs directory: ${message}`, - }, - ); + for (const { triplet, buildPath } of triplets) { + assert(fs.existsSync(buildPath), `Expected a directory at ${buildPath}`); + const targets = await cmakeFileApi.readCurrentTargetsDeep( + buildPath, + configuration, + "2.0", + ); + const sharedLibraries = targets.filter( + (target) => target.type === "SHARED_LIBRARY", + ); + assert.equal( + sharedLibraries.length, + 1, + "Expected exactly one shared library", + ); + const [sharedLibrary] = sharedLibraries; + const { artifacts } = sharedLibrary; + assert(artifacts && artifacts.length, "Expected exactly one artifact"); + const [artifact] = artifacts; + // Add prebuild entry, creating a new entry if needed + if (!(sharedLibrary.name in prebuilds)) { + prebuilds[sharedLibrary.name] = {}; + } + prebuilds[sharedLibrary.name][triplet] = path.join( + buildPath, + artifact.path, + ); + } + + for (const [libraryName, libraryPathByTriplet] of Object.entries( + prebuilds, + )) { + const prebuildOutputPath = path.resolve( + outputPath, + `${libraryName}.android.node`, + ); + await oraPromise( + createAndroidLibsDirectory({ + outputPath: prebuildOutputPath, + libraryPathByTriplet, + autoLink, + }), + { + text: `Assembling Android libs directory (${libraryName})`, + successText: `Android libs directory (${libraryName}) assembled into ${chalk.dim( + path.relative(process.cwd(), prebuildOutputPath), + )}`, + failText: ({ message }) => + `Failed to assemble Android libs directory (${libraryName}): ${message}`, + }, + ); + } }, }; diff --git a/packages/cmake-rn/src/platforms/apple.ts b/packages/cmake-rn/src/platforms/apple.ts index 7eb71392..e28c009a 100644 --- a/packages/cmake-rn/src/platforms/apple.ts +++ b/packages/cmake-rn/src/platforms/apple.ts @@ -7,7 +7,6 @@ import { AppleTriplet as Triplet, createAppleFramework, createXCframework, - determineXCFrameworkFilename, } from "react-native-node-api"; import type { Platform } from "./types.js"; @@ -136,54 +135,60 @@ export const platform: Platform = { { outputPath, triplets }, { configuration, autoLink, xcframeworkExtension }, ) { - const libraryPaths = await Promise.all( - triplets.map(async ({ buildPath }) => { - assert( - fs.existsSync(buildPath), - `Expected a directory at ${buildPath}`, - ); - const targets = await cmakeFileApi.readCurrentTargetsDeep( - buildPath, - configuration, - "2.0", - ); - const sharedLibraries = targets.filter( - (target) => target.type === "SHARED_LIBRARY", - ); - assert.equal( - sharedLibraries.length, - 1, - "Expected exactly one shared library", - ); - const [sharedLibrary] = sharedLibraries; - const { artifacts } = sharedLibrary; - assert(artifacts && artifacts.length, "Expected exactly one artifact"); - const [artifact] = artifacts; - return path.join(buildPath, artifact.path); - }), - ); - const frameworkPaths = libraryPaths.map(createAppleFramework); - const xcframeworkFilename = determineXCFrameworkFilename( - frameworkPaths, - xcframeworkExtension ? ".xcframework" : ".apple.node", - ); - - // Create the xcframework - const xcframeworkOutputPath = path.resolve(outputPath, xcframeworkFilename); - - await oraPromise( - createXCframework({ - outputPath: xcframeworkOutputPath, - frameworkPaths, - autoLink, - }), - { - text: "Assembling XCFramework", - successText: `XCFramework assembled into ${chalk.dim( - path.relative(process.cwd(), xcframeworkOutputPath), - )}`, - failText: ({ message }) => `Failed to assemble XCFramework: ${message}`, - }, - ); + const prebuilds: Record = {}; + for (const { buildPath } of triplets) { + assert(fs.existsSync(buildPath), `Expected a directory at ${buildPath}`); + const targets = await cmakeFileApi.readCurrentTargetsDeep( + buildPath, + configuration, + "2.0", + ); + const sharedLibraries = targets.filter( + (target) => target.type === "SHARED_LIBRARY", + ); + assert.equal( + sharedLibraries.length, + 1, + "Expected exactly one shared library", + ); + const [sharedLibrary] = sharedLibraries; + const { artifacts } = sharedLibrary; + assert(artifacts && artifacts.length, "Expected exactly one artifact"); + const [artifact] = artifacts; + // Add prebuild entry, creating a new entry if needed + if (!(sharedLibrary.name in prebuilds)) { + prebuilds[sharedLibrary.name] = []; + } + prebuilds[sharedLibrary.name].push(path.join(buildPath, artifact.path)); + } + + const extension = xcframeworkExtension ? ".xcframework" : ".apple.node"; + + for (const [libraryName, libraryPaths] of Object.entries(prebuilds)) { + const frameworkPaths = await Promise.all( + libraryPaths.map(createAppleFramework), + ); + // Create the xcframework + const xcframeworkOutputPath = path.resolve( + outputPath, + `${libraryName}${extension}`, + ); + + await oraPromise( + createXCframework({ + outputPath: xcframeworkOutputPath, + frameworkPaths, + autoLink, + }), + { + text: `Assembling XCFramework (${libraryName})`, + successText: `XCFramework (${libraryName}) assembled into ${chalk.dim( + path.relative(process.cwd(), xcframeworkOutputPath), + )}`, + failText: ({ message }) => + `Failed to assemble XCFramework (${libraryName}): ${message}`, + }, + ); + } }, }; From 034e66b042570d233634fb340fcd93adb983551e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 24 Sep 2025 16:53:04 +0200 Subject: [PATCH 5/7] Fix precondition for exactly one artifact --- packages/cmake-rn/src/platforms/android.ts | 5 ++++- packages/cmake-rn/src/platforms/apple.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/cmake-rn/src/platforms/android.ts b/packages/cmake-rn/src/platforms/android.ts index 44db5659..71652c3d 100644 --- a/packages/cmake-rn/src/platforms/android.ts +++ b/packages/cmake-rn/src/platforms/android.ts @@ -141,7 +141,10 @@ export const platform: Platform = { ); const [sharedLibrary] = sharedLibraries; const { artifacts } = sharedLibrary; - assert(artifacts && artifacts.length, "Expected exactly one artifact"); + assert( + artifacts && artifacts.length === 1, + "Expected exactly one artifact", + ); const [artifact] = artifacts; // Add prebuild entry, creating a new entry if needed if (!(sharedLibrary.name in prebuilds)) { diff --git a/packages/cmake-rn/src/platforms/apple.ts b/packages/cmake-rn/src/platforms/apple.ts index e28c009a..c93d3d92 100644 --- a/packages/cmake-rn/src/platforms/apple.ts +++ b/packages/cmake-rn/src/platforms/apple.ts @@ -153,7 +153,10 @@ export const platform: Platform = { ); const [sharedLibrary] = sharedLibraries; const { artifacts } = sharedLibrary; - assert(artifacts && artifacts.length, "Expected exactly one artifact"); + assert( + artifacts && artifacts.length === 1, + "Expected exactly one artifact", + ); const [artifact] = artifacts; // Add prebuild entry, creating a new entry if needed if (!(sharedLibrary.name in prebuilds)) { From 52ec31d5445dcbc97ec10b7b144dcef190930f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Sun, 28 Sep 2025 13:28:54 +0200 Subject: [PATCH 6/7] Take array of triplet + path when creating Android prebuilds --- packages/cmake-rn/src/platforms/android.ts | 21 +++++++++++---------- packages/ferric/src/build.ts | 14 ++++++-------- packages/host/src/node/prebuilds/android.ts | 8 ++++---- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/packages/cmake-rn/src/platforms/android.ts b/packages/cmake-rn/src/platforms/android.ts index 71652c3d..655c1d7b 100644 --- a/packages/cmake-rn/src/platforms/android.ts +++ b/packages/cmake-rn/src/platforms/android.ts @@ -122,7 +122,10 @@ export const platform: Platform = { return typeof ANDROID_HOME === "string" && fs.existsSync(ANDROID_HOME); }, async postBuild({ outputPath, triplets }, { autoLink, configuration }) { - const prebuilds: Record>> = {}; + const prebuilds: Record< + string, + { triplet: Triplet; libraryPath: string }[] + > = {}; for (const { triplet, buildPath } of triplets) { assert(fs.existsSync(buildPath), `Expected a directory at ${buildPath}`); @@ -148,17 +151,15 @@ export const platform: Platform = { const [artifact] = artifacts; // Add prebuild entry, creating a new entry if needed if (!(sharedLibrary.name in prebuilds)) { - prebuilds[sharedLibrary.name] = {}; + prebuilds[sharedLibrary.name] = []; } - prebuilds[sharedLibrary.name][triplet] = path.join( - buildPath, - artifact.path, - ); + prebuilds[sharedLibrary.name].push({ + triplet, + libraryPath: path.join(buildPath, artifact.path), + }); } - for (const [libraryName, libraryPathByTriplet] of Object.entries( - prebuilds, - )) { + for (const [libraryName, libraries] of Object.entries(prebuilds)) { const prebuildOutputPath = path.resolve( outputPath, `${libraryName}.android.node`, @@ -166,7 +167,7 @@ export const platform: Platform = { await oraPromise( createAndroidLibsDirectory({ outputPath: prebuildOutputPath, - libraryPathByTriplet, + libraries, autoLink, }), { diff --git a/packages/ferric/src/build.ts b/packages/ferric/src/build.ts index 33ab568d..2bd0bded 100644 --- a/packages/ferric/src/build.ts +++ b/packages/ferric/src/build.ts @@ -204,15 +204,13 @@ export const buildCommand = new Command("build") ); if (androidLibraries.length > 0) { - const libraryPathByTriplet = Object.fromEntries( - androidLibraries.map(([target, outputPath]) => [ - ANDROID_TRIPLET_PER_TARGET[target], - outputPath, - ]), - ) as Record; + const libraries = androidLibraries.map(([target, outputPath]) => ({ + triplet: ANDROID_TRIPLET_PER_TARGET[target], + libraryPath: outputPath, + })); const androidLibsFilename = determineAndroidLibsFilename( - Object.values(libraryPathByTriplet), + libraries.map(({ libraryPath }) => libraryPath), ); const androidLibsOutputPath = path.resolve( outputPath, @@ -222,7 +220,7 @@ export const buildCommand = new Command("build") await oraPromise( createAndroidLibsDirectory({ outputPath: androidLibsOutputPath, - libraryPathByTriplet, + libraries, autoLink: true, }), { diff --git a/packages/host/src/node/prebuilds/android.ts b/packages/host/src/node/prebuilds/android.ts index 788e2936..ec26408b 100644 --- a/packages/host/src/node/prebuilds/android.ts +++ b/packages/host/src/node/prebuilds/android.ts @@ -32,24 +32,24 @@ export function determineAndroidLibsFilename(libraryPaths: string[]) { type AndroidLibsDirectoryOptions = { outputPath: string; - libraryPathByTriplet: Partial>; + libraries: { triplet: AndroidTriplet; libraryPath: string }[]; autoLink: boolean; }; export async function createAndroidLibsDirectory({ outputPath, - libraryPathByTriplet, + libraries, autoLink, }: AndroidLibsDirectoryOptions) { // Delete and recreate any existing output directory await fs.promises.rm(outputPath, { recursive: true, force: true }); await fs.promises.mkdir(outputPath, { recursive: true }); - for (const [triplet, libraryPath] of Object.entries(libraryPathByTriplet)) { + for (const { triplet, libraryPath } of libraries) { assert( fs.existsSync(libraryPath), `Library not found: ${libraryPath} for triplet ${triplet}`, ); - const arch = ANDROID_ARCHITECTURES[triplet as AndroidTriplet]; + const arch = ANDROID_ARCHITECTURES[triplet]; const archOutputPath = path.join(outputPath, arch); await fs.promises.mkdir(archOutputPath, { recursive: true }); // Strip the ".node" extension from the library name From 4d0b7dfbd68a454453b542f955e5e39289695639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Sun, 28 Sep 2025 21:26:29 +0200 Subject: [PATCH 7/7] Use bufout spawn in createAppleFramework --- packages/host/src/node/prebuilds/apple.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/host/src/node/prebuilds/apple.ts b/packages/host/src/node/prebuilds/apple.ts index b8bff129..f3b1efde 100644 --- a/packages/host/src/node/prebuilds/apple.ts +++ b/packages/host/src/node/prebuilds/apple.ts @@ -2,7 +2,6 @@ import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; import os from "node:os"; -import cp from "node:child_process"; import { spawn } from "@react-native-node-api/cli-utils"; @@ -77,12 +76,13 @@ export async function createAppleFramework(libraryPath: string) { // TODO: Consider copying the library instead of renaming it await fs.promises.rename(libraryPath, newLibraryPath); // Update the name of the library - // TODO: Make this call async - cp.spawnSync("install_name_tool", [ - "-id", - `@rpath/${libraryName}.framework/${libraryName}`, - newLibraryPath, - ]); + await spawn( + "install_name_tool", + ["-id", `@rpath/${libraryName}.framework/${libraryName}`, newLibraryPath], + { + outputMode: "buffered", + }, + ); return frameworkPath; }