diff --git a/packages/react-native-node-api-cmake/src/android.ts b/packages/react-native-node-api-cmake/src/android.ts index 88f14877..cd1fe4ae 100644 --- a/packages/react-native-node-api-cmake/src/android.ts +++ b/packages/react-native-node-api-cmake/src/android.ts @@ -4,6 +4,16 @@ import path from "node:path"; import { AndroidTriplet } from "react-native-node-api-modules"; +import { isNinjaAvailable } from "./ninja.js"; + +function getCmakeGenerator() { + if (isNinjaAvailable()) { + return "Ninja"; + } else { + return "Unix Makefiles"; + } +} + export const DEFAULT_ANDROID_TRIPLETS = [ "aarch64-linux-android", "armv7a-linux-androideabi", @@ -48,16 +58,9 @@ export function getAndroidConfigureCmakeArgs({ ); const architecture = ANDROID_ARCHITECTURES[triplet]; - const linkerFlags: string[] = [ - // `--no-version-undefined`, - // `--whole-archive`, - // `--no-whole-archive`, - ]; - return [ - // Use the XCode as generator for Apple platforms "-G", - "Ninja", + getCmakeGenerator(), "--toolchain", toolchainPath, "-D", @@ -68,8 +71,6 @@ export function getAndroidConfigureCmakeArgs({ // `CMAKE_INSTALL_PREFIX=${installPath}`, // "-D", // `CMAKE_BUILD_TYPE=${configuration}`, - "-D", - "CMAKE_MAKE_PROGRAM=ninja", // "-D", // "CMAKE_C_COMPILER_LAUNCHER=ccache", // "-D", @@ -84,13 +85,5 @@ export function getAndroidConfigureCmakeArgs({ // `ANDROID_NATIVE_API_LEVEL=${ANDROID_API_LEVEL}`, "-D", "ANDROID_STL=c++_shared", - // Pass linker flags to avoid errors from undefined symbols - // TODO: Link against a weak-node-api to avoid this (or whatever other lib which will be providing the symbols) - // "-D", - // `CMAKE_SHARED_LINKER_FLAGS="-Wl,--allow-shlib-undefined"`, - "-D", - `CMAKE_SHARED_LINKER_FLAGS=${linkerFlags - .map((flag) => `-Wl,${flag}`) - .join(" ")}`, ]; } diff --git a/packages/react-native-node-api-cmake/src/ninja.ts b/packages/react-native-node-api-cmake/src/ninja.ts new file mode 100644 index 00000000..fc815ff0 --- /dev/null +++ b/packages/react-native-node-api-cmake/src/ninja.ts @@ -0,0 +1,39 @@ +import chalk from "chalk"; +import cp from "node:child_process"; + +export function getNinjaVersion(): string | undefined { + try { + const ninjaVersion = cp + .execSync("ninja --version", { + encoding: "utf-8", + stdio: "pipe", + }) + .trim(); + return ninjaVersion; + } catch { + return undefined; + } +} + +let ninjaAvailable: boolean | undefined; + +export function isNinjaAvailable(log = true): boolean { + if (typeof ninjaAvailable === "boolean") { + return ninjaAvailable; + } + + const ninjaVersion = getNinjaVersion(); + ninjaAvailable = typeof ninjaVersion === "string"; + + if (log && ninjaAvailable) { + console.log(chalk.dim(`Using Ninja ${ninjaVersion} for Android builds`)); + } else if (log && !ninjaAvailable) { + console.log( + `Using Unix Makefiles as fallback, as Ninja was not found.\n${chalk.dim( + "Install Ninja for faster builds." + )}` + ); + } + + return ninjaAvailable; +}