Grapevine_Disease_Detection/VinEye/plugins/withCmakeFix.js
Yanis f247748adc chore(android): propagate CMake fix to native subprojects
The withCmakeFix plugin now also modifies the root android/build.gradle
via withProjectBuildGradle, iterating over subprojects with
plugins.withId('com.android.library') / plugins.withId('com.android.application').
Using plugins.withId (vs subprojects { afterEvaluate {} }) avoids the
"Cannot run Project.afterEvaluate when the project is already evaluated"
error caused by gradle-plugins (kotlin, expo-gradle-plugin, ...) being
evaluated before the closure runs.

This unblocks the native CMake build of react-native-fast-tflite,
react-native-nitro-modules, react-native-screens, expo-modules-core, etc.
on Windows where the path-too-long issue affected subproject .o files.

Build verified: BUILD SUCCESSFUL in 15m 17s, 842 tasks, 0 errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 11:30:55 +02:00

88 lines
2.6 KiB
JavaScript

const {
withAppBuildGradle,
withProjectBuildGradle,
} = require("expo/config-plugins");
const NINJA_PATH =
"C:\\\\Users\\\\Client\\\\AppData\\\\Local\\\\Android\\\\Sdk\\\\cmake\\\\4.1.2\\\\bin\\\\ninja.exe";
const CMAKE_ARGS = [
`"-DCMAKE_MAKE_PROGRAM=${NINJA_PATH}"`,
`"-DCMAKE_OBJECT_PATH_MAX=1024"`,
`"-DCMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS=1"`,
`"-DCMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES=1"`,
`"-DCMAKE_CXX_RESPONSE_FILE_LINK_FLAG=@"`,
`"-DCMAKE_NINJA_FORCE_RESPONSE_FILE=1"`,
];
const CMAKE_BLOCK = `
externalNativeBuild {
cmake {
arguments ${CMAKE_ARGS.join(",\n ")}
}
}
`;
const APP_MARKER = "// CMAKE_FIX_INJECTED";
const ROOT_MARKER = "// CMAKE_FIX_SUBPROJECTS_INJECTED";
const SUBPROJECTS_BLOCK = `
${ROOT_MARKER}
subprojects { subproject ->
def applyCmakeFix = {
try {
subproject.android {
defaultConfig {
externalNativeBuild {
cmake {
arguments ${CMAKE_ARGS.join(",\n ")}
}
}
}
}
} catch (Exception e) {
println "[CMAKE_FIX] Skipping " + subproject.name + ": " + e.message
}
}
subproject.plugins.withId('com.android.library', applyCmakeFix)
subproject.plugins.withId('com.android.application', applyCmakeFix)
}
`;
function injectAppCmakeFix(buildGradle) {
if (buildGradle.includes(APP_MARKER)) return buildGradle;
const defaultConfigRegex = /(defaultConfig\s*\{)([\s\S]*?)(\n\s*\})/m;
const match = buildGradle.match(defaultConfigRegex);
if (!match) {
throw new Error(
"[withCmakeFix] Impossible de trouver le bloc defaultConfig dans build.gradle"
);
}
const [, openTag, body, closeTag] = match;
const newBlock = `${openTag}${body}\n ${APP_MARKER}${CMAKE_BLOCK}${closeTag}`;
return buildGradle.replace(defaultConfigRegex, newBlock);
}
function injectRootSubprojectsFix(buildGradle) {
if (buildGradle.includes(ROOT_MARKER)) return buildGradle;
return `${buildGradle.trimEnd()}\n${SUBPROJECTS_BLOCK}\n`;
}
module.exports = function withCmakeFix(config) {
config = withAppBuildGradle(config, (config) => {
config.modResults.contents = injectAppCmakeFix(config.modResults.contents);
return config;
});
config = withProjectBuildGradle(config, (config) => {
config.modResults.contents = injectRootSubprojectsFix(
config.modResults.contents
);
return config;
});
return config;
};