|
| 1 | +import assert from "node:assert/strict"; |
| 2 | +import fs from "node:fs"; |
| 3 | +import path from "node:path"; |
| 4 | + |
| 5 | +import { determineLibraryBasename } from "../path-utils.js"; |
| 6 | +import { NodeTriplet } from "./triplets.js"; |
| 7 | + |
| 8 | +type OSArchName = |
| 9 | + | `${typeof process.platform}-${typeof process.arch}` |
| 10 | + | "darwin-arm64;x86_64"; |
| 11 | + |
| 12 | +const DIRECTORY_NAMES_PER_TARGET = { |
| 13 | + "arm64;x86_64-apple-darwin": "darwin-arm64;x86_64", |
| 14 | + "arm64-apple-darwin": "darwin-arm64", |
| 15 | + "x86_64-apple-darwin": "darwin-x64", |
| 16 | +} satisfies Record<NodeTriplet, OSArchName>; |
| 17 | + |
| 18 | +/** |
| 19 | + * Determine the filename of the Android libs directory based on the framework paths. |
| 20 | + * Ensuring that all framework paths have the same base name. |
| 21 | + */ |
| 22 | +export function determineNodeLibsFilename(libraryPaths: string[]) { |
| 23 | + const libraryName = determineLibraryBasename(libraryPaths); |
| 24 | + return `${libraryName}.nodejs.node`; |
| 25 | +} |
| 26 | + |
| 27 | +type NodeLibsDirectoryOptions = { |
| 28 | + outputPath: string; |
| 29 | + libraryPathByTriplet: Record<NodeTriplet, string>; |
| 30 | + autoLink: boolean; |
| 31 | +}; |
| 32 | + |
| 33 | +export async function createNodeLibsDirectory({ |
| 34 | + outputPath, |
| 35 | + libraryPathByTriplet, |
| 36 | + autoLink, |
| 37 | +}: NodeLibsDirectoryOptions) { |
| 38 | + // Delete and recreate any existing output directory |
| 39 | + await fs.promises.rm(outputPath, { recursive: true, force: true }); |
| 40 | + await fs.promises.mkdir(outputPath, { recursive: true }); |
| 41 | + for (const [triplet, libraryPath] of Object.entries(libraryPathByTriplet) as [ |
| 42 | + NodeTriplet, |
| 43 | + string, |
| 44 | + ][]) { |
| 45 | + assert( |
| 46 | + fs.existsSync(libraryPath), |
| 47 | + `Library not found: ${libraryPath} for triplet ${triplet}`, |
| 48 | + ); |
| 49 | + // Create the architecture-specific directory |
| 50 | + const osArch = DIRECTORY_NAMES_PER_TARGET[triplet]; |
| 51 | + const osArchOutputPath = path.join(outputPath, osArch); |
| 52 | + await fs.promises.mkdir(osArchOutputPath, { recursive: true }); |
| 53 | + // Strip the ".so" extension from the library name |
| 54 | + const libraryName = path.basename(libraryPath, ".so"); |
| 55 | + const nodeSuffixedName = |
| 56 | + path.extname(libraryName) === ".node" |
| 57 | + ? libraryName |
| 58 | + : `${libraryName}.node`; |
| 59 | + const libraryOutputPath = path.join(osArchOutputPath, nodeSuffixedName); |
| 60 | + await fs.promises.copyFile(libraryPath, libraryOutputPath); |
| 61 | + } |
| 62 | + if (autoLink) { |
| 63 | + // Write a file to mark the Android libs directory is a Node-API module |
| 64 | + await fs.promises.writeFile( |
| 65 | + path.join(outputPath, "react-native-node-api-module"), |
| 66 | + "", |
| 67 | + "utf8", |
| 68 | + ); |
| 69 | + } |
| 70 | + return outputPath; |
| 71 | +} |
0 commit comments