Skip to content

Commit 2388b41

Browse files
committed
Create frameworks in a xcframework named after the framework
1 parent 87c0c44 commit 2388b41

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

packages/react-native-node-api-cmake/src/apple.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import assert from "node:assert/strict";
22
import cp from "node:child_process";
33
import fs from "node:fs";
4+
import path from "node:path";
45

56
import type { SupportedTriplet } from "./triplets.js";
67

@@ -108,11 +109,36 @@ export function getAppleBuildArgs() {
108109

109110
type XCframeworkOptions = {
110111
libraryPaths: string[];
112+
frameworkPaths: string[];
111113
outputPath: string;
112114
};
113115

116+
export function createFramework(libraryPath: string) {
117+
assert(fs.existsSync(libraryPath), `Library not found: ${libraryPath}`);
118+
// Write a info.plist file to the framework
119+
const libraryName = path.basename(libraryPath, path.extname(libraryPath));
120+
const frameworkPath = path.join(
121+
path.dirname(libraryPath),
122+
`${libraryName}.framework`
123+
);
124+
// Create the framework from scratch
125+
fs.rmSync(frameworkPath, { recursive: true, force: true });
126+
fs.mkdirSync(frameworkPath);
127+
fs.mkdirSync(path.join(frameworkPath, "Headers"));
128+
const newLibraryPath = path.join(frameworkPath, libraryName);
129+
fs.renameSync(libraryPath, newLibraryPath);
130+
// Update the name of the library
131+
// cp.spawnSync("install_name_tool", [
132+
// "-id",
133+
// `@rpath/${libraryName}`,
134+
// newLibraryPath,
135+
// ]);
136+
return frameworkPath;
137+
}
138+
114139
export function createXCframework({
115140
libraryPaths,
141+
frameworkPaths,
116142
outputPath,
117143
}: XCframeworkOptions) {
118144
// Delete any existing xcframework to prevent the error:
@@ -124,7 +150,8 @@ export function createXCframework({
124150
"xcodebuild",
125151
[
126152
"-create-xcframework",
127-
...libraryPaths.flatMap((libraryPath) => ["-library", libraryPath]),
153+
...libraryPaths.flatMap((p) => ["-library", p]),
154+
...frameworkPaths.flatMap((p) => ["-framework", p]),
128155
"-output",
129156
outputPath,
130157
],
@@ -133,4 +160,27 @@ export function createXCframework({
133160
}
134161
);
135162
assert.equal(status, 0, "Failed to create xcframework");
163+
// Write a file to mark the xcframework is a Node-API module
164+
fs.writeFileSync(
165+
path.join(outputPath, "react-native-node-api-module"),
166+
"",
167+
"utf8"
168+
);
169+
}
170+
171+
/**
172+
* Determine the filename of the xcframework based on the framework paths.
173+
* Ensuring that all framework paths have the same base name.
174+
*/
175+
export function determineXCFrameworkFilename(frameworkPaths: string[]) {
176+
const frameworkNames = frameworkPaths.map((p) =>
177+
path.basename(p, path.extname(p))
178+
);
179+
const candidates = new Set<string>(frameworkNames);
180+
assert(
181+
candidates.size === 1,
182+
"Expected all frameworks to have the same name"
183+
);
184+
const [name] = candidates;
185+
return `${name}.xcframework`;
136186
}

packages/react-native-node-api-cmake/src/cli.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import { Command, Option } from "@commander-js/extra-typings";
77
import { SUPPORTED_TRIPLETS, SupportedTriplet } from "./triplets.js";
88
import { getNodeApiHeadersPath, getNodeAddonHeadersPath } from "./headers.js";
99
import {
10+
createFramework,
1011
createXCframework,
11-
isAppleTriplet,
12-
getAppleConfigureCmakeArgs,
13-
getAppleBuildArgs,
1412
DEFAULT_APPLE_TRIPLETS,
13+
determineXCFrameworkFilename,
14+
getAppleBuildArgs,
15+
getAppleConfigureCmakeArgs,
16+
isAppleTriplet,
1517
} from "./apple.js";
1618

1719
// TODO: Add automatic ccache support
@@ -123,14 +125,17 @@ export const program = new Command("react-native-node-api-cmake")
123125
}
124126
});
125127
});
128+
const frameworkPaths = libraryPaths.map(createFramework);
129+
const xcframeworkFilename = determineXCFrameworkFilename(frameworkPaths);
126130
// Create the xcframework
127131
createXCframework({
128132
outputPath: path.join(
129133
// Defaults to storing the xcframework next to the CMakeLists.txt file
130134
globalOptions.out || globalOptions.source,
131-
"node-api.xcframework"
135+
xcframeworkFilename
132136
),
133-
libraryPaths,
137+
libraryPaths: [],
138+
frameworkPaths,
134139
});
135140
}
136141
});

0 commit comments

Comments
 (0)