Skip to content

Commit eb56247

Browse files
committed
Add some Copilot instructions for future sessions.
1 parent 9250b45 commit eb56247

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

.github/copilot-instructions.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
applyTo: "strings/**,cppwinrt/**,nuget/**,test/test_module_winrt/**,test/test_cpp20_module/**,test/test_component_module/**"
3+
---
4+
5+
# C++20 Module Code Generation
6+
7+
## When Modifying strings/*.h Files
8+
9+
These files are embedded as string literals by the prebuild step. They are NOT
10+
normal headers:
11+
12+
1. Changes require rebuilding prebuild → cppwinrt → regenerating projection
13+
2. The natvis project includes these files directly via its pch.h — add any new
14+
files there too
15+
3. `WINRT_EXPORT` prefixes `namespace winrt` (public) AND `namespace winrt::impl`
16+
(for component template specialization). Both expansions are needed.
17+
4. `base_module_macros.h` is the single source of truth for macros shared between
18+
module and header modes. Don't duplicate definitions — use `#ifndef` guards.
19+
20+
## Module-Aware Code Generation (-module flag)
21+
22+
When `settings.component_module` is true:
23+
24+
### module.g.cpp
25+
- Keeps `#include "pch.h"` (PCH is compatible with modules)
26+
- Replaces `#include "winrt/base.h"` with `import winrt;`
27+
- `import std;` is conditional: `#ifdef WINRT_IMPORT_STD`
28+
29+
### .g.h (component base template)
30+
- Emits `#include "winrt/base_macros.h"` for macros
31+
- Emits conditional `import std;` + unconditional `import winrt;`
32+
- Emits `#define WINRT_IMPL_SKIP_INCLUDES` then includes component's own headers
33+
- Does NOT include platform namespace headers (they come from the module)
34+
35+
### .g.cpp (factory + optimized constructors)
36+
- In module mode, emits ONLY the `winrt_make_*` factory function
37+
- Constructor/static overrides are omitted (they come from the component's
38+
projection header, which is included by the .g.h after import winrt)
39+
40+
## WINRT_IMPL_SKIP_INCLUDES
41+
42+
Generated namespace headers guard cross-namespace `#include` dependencies with:
43+
```cpp
44+
#ifndef WINRT_IMPL_SKIP_INCLUDES
45+
#include "winrt/base.h"
46+
#endif
47+
```
48+
49+
- Cross-namespace dependencies (other namespaces' impl headers): GUARDED
50+
(`write_depends_guarded` / `write_root_include_guarded`)
51+
- Self-namespace dependencies (own impl headers): NOT guarded
52+
(`write_depends` / `write_root_include`)
53+
- base.h include in version assert: GUARDED with base_macros.h fallback
54+
55+
## Test Project Architecture
56+
57+
- `test_module_winrt` — Static lib that builds winrt.ixx. Generates projection
58+
to its own "Generated Files" directory. Other module projects reference its
59+
IFC and OBJ.
60+
- `test_cpp20_module` — Consumer test app. References test_module_winrt's IFC/OBJ.
61+
Uses PCH for non-winrt headers (catch.hpp, Windows.h).
62+
- `test_component_module` — Component DLL. References test_module_winrt's IFC/OBJ.
63+
Has its own MIDL/cppwinrt steps for component projection.
64+
65+
All module test projects use v143 toolset. `import std;` requires `BuildStlModules=true`
66+
and either v145 toolset or `/std:c++latest` on v143.

0 commit comments

Comments
 (0)