From 2a7d7774f32408e5f6b1df45f8a4c1c11b20c9c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:29:21 +0000 Subject: [PATCH 1/4] Initial plan From 7c6247ff4312997cb164d73b669468c02acf43a6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:38:35 +0000 Subject: [PATCH 2/4] Fix init-windows template to use conditional codegen includes Co-authored-by: anupriya13 <54227869+anupriya13@users.noreply.github.com> --- vnext/templates/cpp-lib/windows/MyLib/MyLib.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/vnext/templates/cpp-lib/windows/MyLib/MyLib.h b/vnext/templates/cpp-lib/windows/MyLib/MyLib.h index 01c66a13e79..d28071f0bcb 100644 --- a/vnext/templates/cpp-lib/windows/MyLib/MyLib.h +++ b/vnext/templates/cpp-lib/windows/MyLib/MyLib.h @@ -6,7 +6,12 @@ #if __has_include("codegen/Native{{ pascalName }}DataTypes.g.h") #include "codegen/Native{{ pascalName }}DataTypes.g.h" #endif -#include "codegen/Native{{ pascalName }}Spec.g.h" +// TODO: Update this include to match your actual TurboModule name +// For example, if your module is named 'MyCustomModule', use: +// #include "codegen/NativeMyCustomModuleSpec.g.h" +#if __has_include("codegen/Native{{ pascalName }}Spec.g.h") + #include "codegen/Native{{ pascalName }}Spec.g.h" +#endif #include "NativeModules.h" @@ -18,7 +23,16 @@ namespace winrt::{{ namespaceCpp }} REACT_MODULE({{ pascalName }}) struct {{ pascalName }} { + // TODO: Update this to match your actual TurboModule spec name + // For example, if your module is named 'MyCustomModule', use: + // using ModuleSpec = {{ namespaceCpp }}Codegen::MyCustomModuleSpec; +#ifdef __has_include +#if __has_include("codegen/Native{{ pascalName }}Spec.g.h") + using ModuleSpec = {{ namespaceCpp }}Codegen::{{ pascalName }}Spec; +#endif +#else using ModuleSpec = {{ namespaceCpp }}Codegen::{{ pascalName }}Spec; +#endif REACT_INIT(Initialize) void Initialize(React::ReactContext const &reactContext) noexcept; From b02696d6ddfa0eaf49bbd3698417841bd99f24a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 Aug 2025 13:51:32 +0000 Subject: [PATCH 3/4] Automatically detect existing codegen spec files instead of using hardcoded names Co-authored-by: anupriya13 <54227869+anupriya13@users.noreply.github.com> --- vnext/templates/cpp-lib/template.config.js | 24 +++++++++++++++++++ vnext/templates/cpp-lib/windows/MyLib/MyLib.h | 20 ++++++++-------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/vnext/templates/cpp-lib/template.config.js b/vnext/templates/cpp-lib/template.config.js index 592005498f9..46e37c4d197 100644 --- a/vnext/templates/cpp-lib/template.config.js +++ b/vnext/templates/cpp-lib/template.config.js @@ -93,6 +93,24 @@ 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 = { @@ -104,6 +122,12 @@ async function getFileMappings(config = {}, options = {}) { namespace: namespace, namespaceCpp: namespaceCpp, + // Codegen spec files information + existingSpecFiles: existingSpecFiles, + hasExistingSpecFiles: existingSpecFiles.length > 0, + firstSpecFile: existingSpecFiles.length > 0 ? existingSpecFiles[0] : null, + firstSpecName: firstSpecName, + rnwVersion: rnwVersion, rnwPathFromProjectRoot: path .relative(projectRoot, rnwPath) diff --git a/vnext/templates/cpp-lib/windows/MyLib/MyLib.h b/vnext/templates/cpp-lib/windows/MyLib/MyLib.h index d28071f0bcb..bb7a54320be 100644 --- a/vnext/templates/cpp-lib/windows/MyLib/MyLib.h +++ b/vnext/templates/cpp-lib/windows/MyLib/MyLib.h @@ -6,12 +6,14 @@ #if __has_include("codegen/Native{{ pascalName }}DataTypes.g.h") #include "codegen/Native{{ pascalName }}DataTypes.g.h" #endif -// TODO: Update this include to match your actual TurboModule name -// For example, if your module is named 'MyCustomModule', use: -// #include "codegen/NativeMyCustomModuleSpec.g.h" +{{#hasExistingSpecFiles}} +#include "codegen/{{ firstSpecFile }}" +{{/hasExistingSpecFiles}} +{{^hasExistingSpecFiles}} #if __has_include("codegen/Native{{ pascalName }}Spec.g.h") #include "codegen/Native{{ pascalName }}Spec.g.h" #endif +{{/hasExistingSpecFiles}} #include "NativeModules.h" @@ -23,16 +25,14 @@ namespace winrt::{{ namespaceCpp }} REACT_MODULE({{ pascalName }}) struct {{ pascalName }} { - // TODO: Update this to match your actual TurboModule spec name - // For example, if your module is named 'MyCustomModule', use: - // using ModuleSpec = {{ namespaceCpp }}Codegen::MyCustomModuleSpec; -#ifdef __has_include +{{#hasExistingSpecFiles}} + using ModuleSpec = {{ namespaceCpp }}Codegen::{{ firstSpecName }}; +{{/hasExistingSpecFiles}} +{{^hasExistingSpecFiles}} #if __has_include("codegen/Native{{ pascalName }}Spec.g.h") using ModuleSpec = {{ namespaceCpp }}Codegen::{{ pascalName }}Spec; #endif -#else - using ModuleSpec = {{ namespaceCpp }}Codegen::{{ pascalName }}Spec; -#endif +{{/hasExistingSpecFiles}} REACT_INIT(Initialize) void Initialize(React::ReactContext const &reactContext) noexcept; From a0980732a3ecbf654724e007e289bc64fec6439b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 30 Sep 2025 03:21:52 +0000 Subject: [PATCH 4/4] Add explanatory comments about Mustache template syntax for C++ developers Co-authored-by: sundaramramaswamy <29264916+sundaramramaswamy@users.noreply.github.com> --- vnext/templates/cpp-lib/windows/MyLib/MyLib.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vnext/templates/cpp-lib/windows/MyLib/MyLib.h b/vnext/templates/cpp-lib/windows/MyLib/MyLib.h index bb7a54320be..6ebc8576f1a 100644 --- a/vnext/templates/cpp-lib/windows/MyLib/MyLib.h +++ b/vnext/templates/cpp-lib/windows/MyLib/MyLib.h @@ -6,6 +6,9 @@ #if __has_include("codegen/Native{{ pascalName }}DataTypes.g.h") #include "codegen/Native{{ pascalName }}DataTypes.g.h" #endif +// Note: The following lines use Mustache template syntax ({{#variable}}, {{^variable}}, {{/variable}}) +// 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}} @@ -25,6 +28,8 @@ namespace winrt::{{ namespaceCpp }} REACT_MODULE({{ pascalName }}) struct {{ pascalName }} { + // Note: Mustache template syntax below ({{#variable}}, {{^variable}}, {{/variable}}) will be + // processed during project generation to produce standard C++ code based on detected codegen files. {{#hasExistingSpecFiles}} using ModuleSpec = {{ namespaceCpp }}Codegen::{{ firstSpecName }}; {{/hasExistingSpecFiles}}