@@ -344,7 +344,7 @@ R"( local Local ^%WinDir^%\System32\WinMetadata folder
344344 group.synchronous (args.exists (" synchronous" ));
345345 writer ixx;
346346 write_preamble (ixx);
347- ixx.write (" module;\n #define WINRT_BUILD_MODULE\n #undef WINRT_IMPL_SKIP_INCLUDES \n " );
347+ ixx.write (" module;\n #define WINRT_BUILD_MODULE\n " );
348348 ixx.write (strings::base_includes);
349349 ixx.write (strings::base_std_includes);
350350 ixx.write (" \n export module winrt;\n #define WINRT_EXPORT export\n #define WINRT_IMPL_INCLUDES_HANDLED\n\n " );
@@ -373,6 +373,31 @@ R"( local Local ^%WinDir^%\System32\WinMetadata folder
373373 write_base_h ();
374374 write_base_macros_h ();
375375 ixx.flush_to_file (settings.output_folder + " winrt/winrt.ixx" );
376+
377+ // Generate a companion header that declares which namespaces are
378+ // in the module. Consumer projects include this (via WINRT_MODULE)
379+ // so that cross-namespace #include guards can precisely skip only
380+ // namespaces available from the module, while still including
381+ // component and other non-module namespace deps.
382+ // Only generated alongside the ixx (not for component projections
383+ // which may also set -base but shouldn't produce module metadata).
384+ if (!settings.component )
385+ {
386+ writer module_ns;
387+ write_preamble (module_ns);
388+ module_ns.write (" #pragma once\n " );
389+ for (auto &&[ns, members] : c.namespaces ())
390+ {
391+ if (!has_projected_types (members) || !settings.projection_filter .includes (members))
392+ {
393+ continue ;
394+ }
395+ std::string ns_macro{ ns };
396+ std::replace (ns_macro.begin (), ns_macro.end (), ' .' , ' _' );
397+ module_ns.write (" #define WINRT_MODULE_NS_%\n " , ns_macro);
398+ }
399+ module_ns.flush_to_file (settings.output_folder + " winrt/winrt_module_namespaces.h" );
400+ }
376401 }
377402
378403 if (settings.component )
0 commit comments