|
| 1 | +# C++/WinRT Repository - Copilot Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +C++/WinRT is a C++ language projection for Windows Runtime APIs. The `cppwinrt.exe` |
| 6 | +code generator reads WinRT metadata (.winmd) and produces C++ headers and a C++20 |
| 7 | +module interface unit (winrt.ixx). |
| 8 | + |
| 9 | +## Repository Structure |
| 10 | + |
| 11 | +- `cppwinrt/` — The code generator source (cppwinrt.exe) |
| 12 | +- `strings/` — Handwritten C++ fragments embedded into generated output by the prebuild step |
| 13 | +- `prebuild/` — Embeds strings/*.h content into strings.h/strings.cpp as string literals |
| 14 | +- `nuget/` — NuGet package files (props, targets, rules) for customer integration |
| 15 | +- `natvis/` — Debugger visualizer (directly includes strings/*.h, not generated output) |
| 16 | +- `test/` — Test projects |
| 17 | +- `_build/` — Build output |
| 18 | +- `docs/` — Documentation including modules.md and modules-internals.md |
| 19 | + |
| 20 | +## Build System |
| 21 | + |
| 22 | +- Uses MSBuild with Visual Studio. Build from a VS Developer PowerShell. |
| 23 | +- `Directory.Build.Props` sets shared properties (toolset, output paths, language standard). |
| 24 | +- `$(OutDir)` = `$(SolutionDir)_build\$(Platform)\$(Configuration)\` |
| 25 | +- `$(IntDir)` = `$(SolutionDir)_build\$(Platform)\$(Configuration)\temp\$(ProjectName)\` |
| 26 | +- The prebuild step must run before cppwinrt can compile (it generates strings.h/strings.cpp). |
| 27 | + |
| 28 | +### Key Build Commands |
| 29 | + |
| 30 | +```powershell |
| 31 | +# Build just the code generator |
| 32 | +msbuild cppwinrt.sln /t:cppwinrt /p:Configuration=Debug /p:Platform=x64 /v:minimal |
| 33 | +
|
| 34 | +# Build a test project (pass SolutionDir for path resolution) |
| 35 | +msbuild test\test_cpp20\test_cpp20.vcxproj /p:Configuration=Debug /p:Platform=x64 /p:SolutionDir=d:\Repos\GitHub\cppwinrt\ |
| 36 | +
|
| 37 | +# Generate SDK projection |
| 38 | +.\_build\x64\Debug\cppwinrt.exe -in sdk -out .\_build\x64\Debug\ |
| 39 | +``` |
| 40 | + |
| 41 | +## Code Generator Architecture |
| 42 | + |
| 43 | +### String Fragment System |
| 44 | + |
| 45 | +The `strings/base_*.h` files are NOT headers that get #included at build time. |
| 46 | +They are embedded as string literals by the prebuild step into `strings.cpp`. |
| 47 | +The code generator writes them into generated output files (base.h, winrt.ixx, etc.). |
| 48 | + |
| 49 | +When modifying strings/*.h files: |
| 50 | +1. Rebuild `prebuild` and then `cppwinrt` to pick up changes |
| 51 | +2. Regenerate the projection (`cppwinrt.exe -in sdk -out ...`) |
| 52 | +3. Then rebuild test projects |
| 53 | + |
| 54 | +### Text Writer System |
| 55 | + |
| 56 | +- `text_writer.h` — Base writer with `%` placeholder substitution |
| 57 | +- `type_writers.h` — The `writer` class with `write_root_include`, `write_depends`, etc. |
| 58 | +- `code_writers.h` — High-level writers: `write_version_assert`, `write_open_file_guard`, etc. |
| 59 | +- `file_writers.h` — File-level orchestration: `write_base_h`, `write_namespace_h`, etc. |
| 60 | +- `component_writers.h` — Component stub generation: `write_module_g_cpp`, `write_component_g_h`, etc. |
| 61 | + |
| 62 | +### Generated File Layers (per namespace) |
| 63 | + |
| 64 | +- `.0.h` — Forward declarations, enums, ABI, consume structs, template specializations |
| 65 | +- `.1.h` — Interface type definitions |
| 66 | +- `.2.h` — Class/struct/delegate type definitions |
| 67 | +- Main `.h` — Consume definitions, produce implementations, std::hash specializations |
| 68 | + |
| 69 | +## C++20 Modules |
| 70 | + |
| 71 | +See `docs/modules.md` for user-facing documentation and `docs/modules-internals.md` |
| 72 | +for maintainer details. |
| 73 | + |
| 74 | +### Key Design Decisions |
| 75 | + |
| 76 | +- `winrt::impl` is exported from the module so component headers can specialize |
| 77 | + templates (`category`, `abi`, `guid_v`, etc.) after `import winrt;` |
| 78 | +- `base_includes.h` has platform headers only; `base_std_includes.h` has std library |
| 79 | + headers. The ixx global module fragment uses both as raw #includes. base.h uses |
| 80 | + the std includes conditionally (import std vs #include). |
| 81 | +- `base_module_macros.h` provides macros that don't cross module boundaries |
| 82 | + (WINRT_EXPORT, WINRT_IMPL_EMPTY_BASES, etc.). It's the single source of truth; |
| 83 | + `base_macros.h` has `#ifndef` fallbacks for direct consumers like natvis. |
| 84 | +- Generated component files (`.g.h`, `module.g.cpp`) use `import winrt;` when |
| 85 | + `-module` flag is passed. `import std;` is conditional on `WINRT_IMPORT_STD`. |
| 86 | +- The natvis project includes strings/*.h directly — any new strings/ files must |
| 87 | + be added to natvis/pch.h too. |
| 88 | + |
| 89 | +### Common Pitfalls |
| 90 | + |
| 91 | +- `<intrin.h>` transitively includes STL headers on newer MSVC. Can't use |
| 92 | + `import std;` in the ixx purview because it conflicts with these transitive includes. |
| 93 | +- `#pragma once` prevents re-inclusion but macros from included headers DO persist |
| 94 | + from the global module fragment into the purview. |
| 95 | +- PCH + conditional compilation: `#include "pch.h"` must be the FIRST non-comment |
| 96 | + line in a file. It cannot be inside `#ifdef` blocks. |
| 97 | +- `PlatformToolset` in `Directory.Build.Props` overrides per-project settings in |
| 98 | + the Globals PropertyGroup. To override, set it in Configuration PropertyGroups. |
| 99 | +- `WINRT_EXPORT` must be defined before any code that uses it. When strings/ files |
| 100 | + are included directly (natvis), `base_module_macros.h` must come before `base_macros.h`. |
| 101 | +- `extern "C++"` is needed on exported `__declspec(selectany)` variables |
| 102 | + (`winrt_to_hresult_handler` etc.) to prevent module linkage. |
0 commit comments