From 65f4f21395c53441ae9fd94c84a856c2138db7f8 Mon Sep 17 00:00:00 2001 From: Vivek JM Date: Thu, 28 May 2026 12:06:11 +0530 Subject: [PATCH] Fix cpp-lib codegen spec include --- ...-7112639b-0ad7-4170-80f2-edc5d8cd5ae0.json | 7 +++ vnext/templates/cpp-lib/template.config.js | 47 ++++++++++--------- vnext/templates/cpp-lib/windows/MyLib/MyLib.h | 30 ++++-------- 3 files changed, 40 insertions(+), 44 deletions(-) create mode 100644 change/react-native-windows-7112639b-0ad7-4170-80f2-edc5d8cd5ae0.json diff --git a/change/react-native-windows-7112639b-0ad7-4170-80f2-edc5d8cd5ae0.json b/change/react-native-windows-7112639b-0ad7-4170-80f2-edc5d8cd5ae0.json new file mode 100644 index 00000000000..e1f1d1ba37d --- /dev/null +++ b/change/react-native-windows-7112639b-0ad7-4170-80f2-edc5d8cd5ae0.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Use codegenConfig name for C++ library template codegen includes", + "packageName": "react-native-windows", + "email": "vivekjm77@gmail.com", + "dependentChangeType": "patch" +} diff --git a/vnext/templates/cpp-lib/template.config.js b/vnext/templates/cpp-lib/template.config.js index dd1eb6f82c8..4d88dc326ac 100644 --- a/vnext/templates/cpp-lib/template.config.js +++ b/vnext/templates/cpp-lib/template.config.js @@ -8,6 +8,7 @@ const crypto = require('crypto'); const existsSync = require('fs').existsSync; +const readFileSync = require('fs').readFileSync; const path = require('path'); const username = require('username'); const util = require('util'); @@ -16,6 +17,23 @@ const glob = util.promisify(require('glob')); const templateUtils = require('../templateUtils'); +function getCodegenProjectName(projectRoot, fallbackName) { + try { + const packageJson = JSON.parse( + readFileSync(path.join(projectRoot, 'package.json'), 'utf8'), + ); + const codegenName = packageJson?.codegenConfig?.name; + if (typeof codegenName === 'string' && codegenName.length > 0) { + return codegenName.replace(/[^a-zA-Z]/g, ''); + } + } catch (e) { + // Fall back to the existing project-name behavior if package.json is missing + // or malformed. Other template paths still handle package.json validation. + } + + return fallbackName; +} + function resolveArgs(config = {}, options = {}) { const projectRoot = config?.root ?? process.cwd(); @@ -85,6 +103,10 @@ async function getFileMappings(config = {}, options = {}) { libConfig?.project?.windows?.projects[0]?.projectName ?? libOptions?.name ?? 'MyLib'; + const codegenProjectName = getCodegenProjectName( + projectRoot, + `${templateUtils.pascalCase(projectName)}Spec`, + ); const namespace = libOptions?.namespace ?? projectName; const namespaceCpp = namespace.replace(/\./g, '::'); const projectGuid = @@ -93,24 +115,6 @@ async function getFileMappings(config = {}, options = {}) { .replace('}', '') ?? crypto.randomUUID(); const currentUser = username.sync(); // Gets the current username depending on the platform. - // Check for existing codegen spec files - const codegenPath = path.join(projectRoot, 'windows', projectName, 'codegen'); - let existingSpecFiles = []; - let firstSpecName = null; - if (existsSync(codegenPath)) { - try { - const specFiles = await glob('*Spec.g.h', {cwd: codegenPath}); - existingSpecFiles = specFiles; - if (specFiles.length > 0) { - // Extract the spec name from filename (e.g., "NativeMyModuleSpec.g.h" -> "MyModuleSpec") - const firstFile = specFiles[0]; - firstSpecName = firstFile.replace(/^Native/, '').replace(/\.g\.h$/, ''); - } - } catch (e) { - // If we can't read the codegen directory, continue with empty array - } - } - const cppNugetPackages = []; const replacements = { @@ -119,14 +123,13 @@ async function getFileMappings(config = {}, options = {}) { name: projectName, pascalName: templateUtils.pascalCase(projectName), + codegenProjectName, namespace: namespace, namespaceCpp: namespaceCpp, // Codegen spec files information - existingSpecFiles: existingSpecFiles, - hasExistingSpecFiles: existingSpecFiles.length > 0, - firstSpecFile: existingSpecFiles.length > 0 ? existingSpecFiles[0] : null, - firstSpecName: firstSpecName, + codegenSpecFile: `Native${codegenProjectName}.g.h`, + codegenDataTypesFile: `Native${codegenProjectName}DataTypes.g.h`, rnwVersion: rnwVersion, rnwPathFromProjectRoot: path diff --git a/vnext/templates/cpp-lib/windows/MyLib/MyLib.h b/vnext/templates/cpp-lib/windows/MyLib/MyLib.h index 21b7bb402ef..0c725b09ccf 100644 --- a/vnext/templates/cpp-lib/windows/MyLib/MyLib.h +++ b/vnext/templates/cpp-lib/windows/MyLib/MyLib.h @@ -3,20 +3,13 @@ #include "pch.h" #include "resource.h" -#if __has_include("codegen/Native{{ pascalName }}DataTypes.g.h") - #include "codegen/Native{{ pascalName }}DataTypes.g.h" +#if __has_include("codegen/{{ codegenDataTypesFile }}") + #include "codegen/{{ codegenDataTypesFile }}" #endif -// Note: The following lines use Mustache template syntax which will be processed during -// project generation to produce standard C++ code. If existing codegen spec files are found, -// use the actual filename; otherwise use conditional includes. -{{#hasExistingSpecFiles}} -#include "codegen/{{ firstSpecFile }}" -{{/hasExistingSpecFiles}} -{{^hasExistingSpecFiles}} -#if __has_include("codegen/Native{{ pascalName }}Spec.g.h") - #include "codegen/Native{{ pascalName }}Spec.g.h" + +#if __has_include("codegen/{{ codegenSpecFile }}") + #include "codegen/{{ codegenSpecFile }}" #endif -{{/hasExistingSpecFiles}} #include "NativeModules.h" @@ -28,16 +21,9 @@ namespace winrt::{{ namespaceCpp }} REACT_MODULE({{ pascalName }}) struct {{ pascalName }} { - // Note: Mustache template syntax below will be processed during project generation - // to produce standard C++ code based on detected codegen files. -{{#hasExistingSpecFiles}} - using ModuleSpec = {{ namespaceCpp }}Codegen::{{ firstSpecName }}; -{{/hasExistingSpecFiles}} -{{^hasExistingSpecFiles}} -#if __has_include("codegen/Native{{ pascalName }}Spec.g.h") - using ModuleSpec = {{ namespaceCpp }}Codegen::{{ pascalName }}Spec; +#if __has_include("codegen/{{ codegenSpecFile }}") + using ModuleSpec = {{ namespaceCpp }}Codegen::{{ codegenProjectName }}; #endif -{{/hasExistingSpecFiles}} REACT_INIT(Initialize) void Initialize(React::ReactContext const &reactContext) noexcept; @@ -49,4 +35,4 @@ struct {{ pascalName }} React::ReactContext m_context; }; -} // namespace winrt::{{ namespaceCpp }} \ No newline at end of file +} // namespace winrt::{{ namespaceCpp }}