Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++20 modules support in MSVC, take 2 #333

Closed
boris-kolpackov opened this issue Oct 12, 2023 · 44 comments
Closed

C++20 modules support in MSVC, take 2 #333

boris-kolpackov opened this issue Oct 12, 2023 · 44 comments
Labels
modules C++ Modules support related.
Milestone

Comments

@boris-kolpackov
Copy link
Member

We've been blocked by MSVC issue 10029154 for a year and half now and I don't believe it makes sense to continue waiting. So we need an alternative plan. Supporting header units without a module mapper or other form of compiler support (like the subject of the above issue) will essentially require us to implement a C++ preprocessor that matches the exact semantics of MSVC, which is definitely not something we would like to take on. As a result, it seems the only alternative available to us is to add support for named modules and leave header units for later (or never; I am getting the feeling that the C++ community is starting to give up on header units and perhaps this is for the best).

So the proposed plan is as follows:

  1. Update build2 to use the new modules-related options in MSVC. We will continue using our existing module dependency extraction machinery, which works fine for named modules (and is used for supporting modules in Clang and in older versions of MSVC).

  2. We will want to support building std and std.compat modules. It feels like the best approach here is to build them on the side similar to how we already build module interfaces of installed libraries. Locating the corresponding module interface files (std.ixx and std.compat.ixx) should be doable: they appear to be installed into the modules\ subdirectory of the MSVC toolchain directory (i.e., it's next to the include\ and lib\ subdirectories). I wonder if there is an environment variable (similar to INCLUDE) that is set by the Visual Studio command prompts?

The first practical step we would need to take in executing this plan is to get a sense of the new command line options that need to be passed when (a) building a module interface and (b) building a translation unit that imports this modules interface. We would also need to figure out if anything special needs to be done to compile std.ixx. Finally, there are also partitions (interface and implementation) and it would be good to understand how they fit in.

@Klaim has already done some work on that: https://github.com/Klaim/cxx20-modules-examples/blob/visualstudio/visualstudio-projects/build2-modules-msvc-notes.md

@GabrielDosReis FYI

@boris-kolpackov boris-kolpackov added this to the 0.17.0 milestone Oct 12, 2023
@boris-kolpackov boris-kolpackov added the modules C++ Modules support related. label Oct 12, 2023
@Klaim
Copy link
Member

Klaim commented Oct 12, 2023

First, in the notes linked above, I added (last year) a note with a link to this document: https://lists.isocpp.org/sg15/att-1346/C___20_Modules_Build_in_Visual_Studio.pdf which summarizes how MSBuild builds modules and find dependent modules. It's short and gives you all the clues for the basic interface I believe.

For the compilation flags, here is an article that summarize in a table all the flags we need (I think):
https://devblogs.microsoft.com/cppblog/using-cpp-modules-in-msvc-from-the-command-line-part-1/
I think this is a good summary of what I found and should be taken as the main info source on the subject, excluding definitions of flags from the doc.

Taking this info and the ones I gathered in the past, and trying to summarize quickly, and removing information about header-units:

To build module files (a):

  • /interface to explicitly state that the source file is a module interface or module intereface partition
  • /internalPartition should be used for module partitions which are not interface
  • /ifcOutput to specify where the IFC file (also known as BMI) should be generated

To consume module files (b):

  • /reference to specify the IFC dependencies to use (with a parameter to specify the name of the module, if necessary)

That's the gist of it (ignoring also how to find the dependencies, this is explained in the first link of this post but build2 already have it's way).

Note that I did not find much documentation for /ifcSearchDir which is used to specify directories where to find IFC files dependencies which have the same name as the module name. I'm not sure if it's helpful in the context of build2 which I suspect has already an equivalent.

Also note that these flags should only work with /std:c++latest or /std:c++20.

I wonder if there is an environment variable (similar to INCLUDE) that is set by the Visual Studio command prompts?

I looked at all the environment variables set in "Developer" presets from Terminal when installing recent VS2022 and preview. Basically this is vs command prompt tools just in the Terminal app.
In both environments, listing all variables, I didnt find any reference to that modules directory. I was assuming it would appear maybe in INCLUDE or EXTERNAL_INCLUDE but it doesnt.
I'll avoid copy pasting all the values here but I can send you the whole set of data privately, in case you want to find useful patterns. But I suspect specifically for this directory, using $VCToolsInstallDir/modules should work.

We would also need to figure out if anything special needs to be done to compile std.ixx.

I'll investigate.

@Klaim
Copy link
Member

Klaim commented Oct 12, 2023

About std and std.compat:

I asked on MSVC's STL discord if there is anything special to know about building these modules, for now there is no direct answer but it will probably come soon. I highly suspect that nothing special is needed.

Meanwhile, I proceeded as follow to have a basic check of how MSBuild does it:

  1. New empty C++ project in Visual Studio 2022 Preview

Source main.cpp:

import std;


int main()
{
    std::print("Hello, world with modules!");
}
  1. I edited the project settings to enable automatic compilation of std module: option "C/C++/Language/Build ISO C++23 Standard Library Modules" set to "Yes". Set standard to > C++20: /std:c++latest. No idea what are the corresponding flags for MSBuild but I suspect we dont care.

  2. Here is what the IDE states about the project:

  • Compilation flags (Release):
/permissive- /ifcOutput "x64\Release\" /GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"x64\Release\vc143.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /std:c++latest /FC /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\test_basic_modules.pch" /diagnostics:column 
  • Compilation flags (Debug):
/JMC /permissive- /ifcOutput "x64\Debug\" /GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc143.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++latest /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\test_basic_modules.pch" /diagnostics:column 
  • Linker flags (Release):
/OUT:"C:\Users\Klaim\source\repos\test_basic_modules\x64\Release\test_basic_modules.exe" /MANIFEST /LTCG:incremental /NXCOMPAT /PDB:"C:\Users\Klaim\source\repos\test_basic_modules\x64\Release\test_basic_modules.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /OPT:REF /PGD:"C:\Users\Klaim\source\repos\test_basic_modules\x64\Release\test_basic_modules.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Release\test_basic_modules.exe.intermediate.manifest" /LTCGOUT:"x64\Release\test_basic_modules.iobj" /OPT:ICF /ERRORREPORT:PROMPT /ILK:"x64\Release\test_basic_modules.ilk" /NOLOGO /TLBID:1 
  • Linker flags (Debug):
/OUT:"C:\Users\Klaim\source\repos\test_basic_modules\x64\Debug\test_basic_modules.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\Klaim\source\repos\test_basic_modules\x64\Debug\test_basic_modules.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /INCREMENTAL /PGD:"C:\Users\Klaim\source\repos\test_basic_modules\x64\Debug\test_basic_modules.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\test_basic_modules.exe.intermediate.manifest" /LTCGOUT:"x64\Debug\test_basic_modules.iobj" /ERRORREPORT:PROMPT /ILK:"x64\Debug\test_basic_modules.ilk" /NOLOGO /TLBID:1 

Keep in mind that these flags are augmented with other flags which are "default".

  1. Here is the "detailed" output of MSBuild to build this project: https://pastebin.com/2nfAagG2

This is very verbose but the lower output level will not give the command lines.

First appearance of cl.exe:

1>    C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.33126\bin\HostX64\x64\CL.exe /c /ZI /JMC /nologo /W3 /WX- /diagnostics:column /sdl /FS /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /std:c++latest /permissive- /ifcOutput "C:\Users\Klaim\source\repos\test_basic_modules\test_basic_modules\x64\Debug\microsoft\STL\std.compat.ixx.ifc" /scanDependencies "x64\Debug\microsoft/STL\\" /Fo"x64\Debug\microsoft/STL\std.compat.ixx.obj" /Fd"x64\Debug\vc143.pdb" /external:W3 /Gd /interface /FC /errorReport:prompt  /TP "C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.33126\modules\std.compat.ixx"

then

1>    C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.33126\bin\HostX64\x64\CL.exe /c /ZI /JMC /nologo /W3 /WX- /diagnostics:column /sdl /FS /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /std:c++latest /permissive- /ifcOutput "C:\Users\Klaim\source\repos\test_basic_modules\test_basic_modules\x64\Debug\microsoft\STL\std.ixx.ifc" /scanDependencies "x64\Debug\microsoft/STL\\" /Fo"x64\Debug\microsoft/STL\std.ixx.obj" /Fd"x64\Debug\vc143.pdb" /external:W3 /Gd /interface /FC /errorReport:prompt  /TP "C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.38.33126\modules\std.ixx"

Which looks to me like it's normal module build of these std files.

@Klaim
Copy link
Member

Klaim commented Oct 12, 2023

I got confirmation from STL (the maintainer) that there is nothing special to do to build std and std.compat, just build it as any other module.

@GabrielDosReis
Copy link

Building modules std and std.compat is no different from building any other modules part of a project/program/library. My recommendation is that they should be built with macro definitions and compiler flags consistent with the consumption side. For MSVC, the source files std.ixx and std.compat.ixx are found in the directory modules sibling to include. That is a contract with customers. See also example at my repo cmake-for-module, specifically https://github.com/GabrielDosReis/cmake-for-modules/blob/main/CXXModuleExperimentalSupport.cmake.

As for /reference switches, you might be interested in the ifc reference map switch /ifcMap along withe a IFC map file format, exemplified at https://devblogs.microsoft.com/cppblog/integrating-c-header-units-into-office-using-msvc-2-n/#ifc-ref

@GabrielDosReis
Copy link

2. I wonder if there is an environment variable (similar to INCLUDE) that is set by the Visual Studio command prompts?

No environment variables. I have been discouraging that for modules. If you have an MSVC toolset and you can locate its include directory, say D, then the standard library modules source files are located at D/../modules/, that is modules is sibling directory to include.

@boris-kolpackov
Copy link
Member Author

boris-kolpackov commented Dec 5, 2023

Filling in some blanks in the MSVC documentation on implementation partitions support (referred to as "internal partitions"):

  1. /internalPartition causes the production of the .ifc file.

  2. /ifcOutput and /ifcOnly work with /internalPartition:

    cl /std:c++20 /TP /internalPartition /ifcOutput int.ifc /c int.mxx
    
  3. /reference works for internal partition BUT only without an explicit module name specification:

    cl /std:c++20 /TP /interface /reference int.ifc /ifcOutput m.ifc /c m.mxx
    

    CORRECTION: Specifying the full partition name also works:

    cl /std:c++20 /TP /interface /reference m:internals=int.ifc /ifcOutput m.ifc /c m.mxx
    
  4. Looks like there is no requirement to pass transitive /reference for internal partitions:

    cl /std:c++20 /TP /reference m=m.ifc /c main.cxx
    

Tested with 17.6.

@GabrielDosReis None of this is document, AFAICS.

@mathstuf FYI.

@boris-kolpackov
Copy link
Member Author

I am trying to decide if we should use /Zc:preprocessor (new/conforming preprocessor) by default if modules are enabled. Some data points:

  1. In 17.6 it's not enabled, neither in /std:c++20 nor in /std:c++latest.

  2. Based on the above command lines, it doesn't look like Visual Studio projects enable it even if modules are enabled. @Klaim Could you re-check this with the latest version?

  3. As I understand, if one tries to use header units (/headerUnit, /exportHeader), this option is enabled implicitly.

@GabrielDosReis Are there any plans to enable the new preprocessor by default at some point?

@Klaim
Copy link
Member

Klaim commented Dec 5, 2023

Based on the above command lines, it doesn't look like Visual Studio projects enable it even if modules are enabled. @Klaim Could you re-check this with the latest version?

Checked with VS 2022 17.8.2 and 17.9.0-preview 1: no /Zc:preprossessor in cl commands generated by default.
For each, I created a simple empty project, added a main.cpp and a mymodule.ixx with an exported function (I used .ixx so that it's the default automatic modules build being set), then enabled modules through the C++20 flag/option. The detailed (verbose) output of MSBuild when building mymodule.ixx does not show that flag and I can see it is not set in the project's properties by default. However the flag is documented there:
image

Looks like for now it's more targeted at C users.

@mathstuf
Copy link

mathstuf commented Dec 5, 2023

/reference works for internal partition BUT only without an explicit module name specification:

Interesting; I've not seen this in CMake. Maybe this case isn't being tested? I'll check today.

Looks like there is no requirement to pass transitive /reference for internal partitions:

This sounds odd as well; I'll also test this.

@mathstuf
Copy link

mathstuf commented Dec 5, 2023

-internalPartition and -reference modname=modname.ifc works for me:

> type CMakeFiles\internal-partitions.dir\partition.cxx.obj.modmap
-internalPartition
-ifcOutput CMakeFiles\internal-partitions.dir\importable-internal_partition.ifc
-reference internal=CMakeFiles\internal-partitions.dir\internal.ifc

Using

Microsoft (R) C/C++ Optimizing Compiler Version 19.36.32535 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

@mathstuf
Copy link

mathstuf commented Dec 5, 2023

Looks like there is no requirement to pass transitive /reference for internal partitions:

This sounds odd as well; I'll also test this.

Manually mucking with response files, this seems true, but I feel like I can make this matter…

@mathstuf
Copy link

mathstuf commented Dec 5, 2023

Manually mucking with response files, this seems true, but I feel like I can make this matter…

Yes, if you use a type from an internal partition in an exported API, the internal partition needs resolved. So, in general, you do need the internal partition references. See the changes in this MR: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/9039

@boris-kolpackov
Copy link
Member Author

boris-kolpackov commented Dec 6, 2023

-internalPartition and -reference modname=modname.ifc works for me:

Yes, you are right, I just retested and specifying the full partition name also works.

Yes, if you use a type from an internal partition in an exported API, the internal partition needs resolved.

Interesting, thanks! Looks like the same requirement in Clang.

@boris-kolpackov
Copy link
Member Author

@Klaim Thanks for re-checking!

Looks like for now it's more targeted at C users.

And C++ header unit users. We could try to build our 400+ packages with this flag and see if there are any regressions.

@boris-kolpackov
Copy link
Member Author

Capturing more information as I discover it: MSVC replaces the module keyword with __preprocessed_module in the preprocessed source code (/P). This happens for module m;, export module m;, and module :private;. It also removes the leading module; marker (which I suspect is the reason why it needs to replace the following module with __preprocessed_module). This behavior is identical for both the old and new (/Zc:preprocessor) preprocessors. AFAICS, this is not documented anywhere.

@GabrielDosReis
Copy link

For new IFC-related, note /ifcMap

@GabrielDosReis
Copy link

2. I wonder if there is an environment variable (similar to INCLUDE) that is set by the Visual Studio command prompts?

There is no environment variable. The modules/ directory (for standard library modules) sibling to the include/ directory is a "contract" of the layout that tools can depend on.

@GabrielDosReis
Copy link

  • /reference to specify the IFC dependencies to use (with a parameter to specify the name of the module, if necessary)

I would recommend using /ifcMap to avoid overloading the command line. Plus, it consolidates IFC reference mapping at a single place. In the future, it might allow other #include-translation related technology

@GabrielDosReis
Copy link

4. Looks like there is no requirement to pass transitive /reference for internal partitions

No, MSVC does not implement or guarantee any "transitive /reference" - you might observe some happy accidents or bugs, but there is no transitive reference.

@GabrielDosReis
Copy link

@GabrielDosReis None of this is document, AFAICS.

Thanks. I will work with the doc team to fix what is missing.

@GabrielDosReis
Copy link

@GabrielDosReis Are there any plans to enable the new preprocessor by default at some point?

As usual, Windows SDKs are the main blockers here. Please could you file a bug/request on DevCom and send me the link - that makes it easier for me to work with internally.

@GabrielDosReis
Copy link

Checked with VS 2022 17.8.2 and 17.9.0-preview 1: no /Zc:preprossessor in cl commands generated by default.

MSVC supports named modules with the old non-conforming preprocessor. However, it requires /Zc:preprocessor for header units. Turning that on by default in /std:c++latest depends a lot on the shape of various SDKs that ship independently of DevDiv.

@GabrielDosReis
Copy link

Looks like for now it's more targeted at C users.

An unfortunate editing oversight when the C conformance work was done and the doc was update.

@GabrielDosReis
Copy link

Yes, if you use a type from an internal partition in an exported API, the internal partition needs resolved. So, in general, you do need the internal partition references.

Yes, you do. There is no transitive /reference - though happy accidents can happen.

@GabrielDosReis
Copy link

Capturing more information as I discover it: MSVC replaces the module keyword with __preprocessed_module in the preprocessed source code (/P). This happens for module m;, export module m;, and module :private;. It also removes the leading module; marker (which I suspect is the reason why it needs to replace the following module with __preprocessed_module). This behavior is identical for both the old and new (/Zc:preprocessor) preprocessors. AFAICS, this is not documented anywhere.

The standards text say that module introduces a preprocessing directive. After translation phase 4, you get module-keyword. __preprocessed_module is not documented because it is an internal keyword that we don't recommend users to depend on.

@GabrielDosReis
Copy link

One thing I would encourage you to provide is ability for a user to specify (at the build definition level) their own IFC mapping for a given header unit reference or a module name reference. For instance, a user may need to specify that the IFC for the header unit <vector> is std.ifc instead of the build system going off trying to forcefully build an IFC for the <vector> header unit.

@boris-kolpackov
Copy link
Member Author

@GabrielDosReis Thanks for the feedback, please see me replies below:

I would recommend using /ifcMap to avoid overloading the command line.

I would really like to provide the mapping in a file but the way /ifcMap does it doesn't really work for me. Specifically, I would like to reuse the per-translation unit file (.d) that we already have and which we use to track auxiliary dependency information (included headers, command line options, environment, etc.). I am able to do that for GCC because its file-based mapping file is line-oriented and allows me to specify a "cookie" to distinguish mapping lines from other information. For details, see: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Module-Mapper.html (the last argument variant).

In contrast, /ifcMap expects a TOML file (which suggest it's expected to be written manually by the user). I could of course auto-generate it, by that means I will need to have an additional file per translation unit, which is a major drawback. If I cannot reuse the existing .d file, my next best solution is to just generate a response file on the fly but only if the command line is too long.

Let me know if you would be amenable to supporting something similar to the GCC's format and I would be happy to file an issue.

Please could you file a bug/request on DevCom and send me the link - that makes it easier for me to work with internally.

Here you go: https://developercommunity.visualstudio.com/t/Please-clarify-ifwhen-Zc:preprocessor/10537317

One thing I would encourage you to provide is ability for a user to specify (at the build definition level) their own IFC mapping for a given header unit reference or a module name reference.

We may do this later if there is strong demand but I am really not a fan of this approach. It gives the false (IMO) sense that the user can manually arrange for this to work reliably. For example, the user can already specify the /ifcMap option on the command line and map <vector> to std.ifc, but nobody is going to make sure that when std.ifc changes, all the TUs that import <vector> are going to be rendered out of date.

I am hoping that the need for header units will greatly diminish with support for import std; (which build2 now supports automatically for both MSVC and Clang/libc++).

@mathstuf
Copy link

mathstuf commented Dec 8, 2023

It gives the false (IMO) sense that the user can manually arrange for this to work reliably.

I agree that users specifying this is probably a bit far. It's something far more under the direction of the header unit provider than the consumer. As such, I expect CMake's import std; support to do this if the stdlib in question supports it (and it doesn't do things like force-include but instead pulls macros from somewhere in the .ifc that aren't used when imported by name or something).

@boris-kolpackov
Copy link
Member Author

pulls macros from somewhere in the .ifc that aren't used when imported by name or something

Dual-personality header unit/named module BMIs, how hard can that be? ;-)

But, yes, interesting idea to automatically translate standard library header inclusion to import std;.

@mathstuf
Copy link

mathstuf commented Dec 8, 2023

Dual-personality header unit/named module BMIs, how hard can that be? ;-)

Overall? Sounds easier than implementing header units… Moves a lot of the work from build systems to compilers though.

@boris-kolpackov
Copy link
Member Author

Sounds easier than implementing header units.

Probably, but it's a solution most likely to be limited to std. I also feel that remapping something like #include <vector> to import std; will likely break some code (e.g., that does using namespace std;) due to the presence of additional names.

@mathstuf
Copy link

I also feel that remapping something like #include to import std; will likely break some code (e.g., that does using namespace std;) due to the presence of additional names.

Headers doing this were already at risk of:

#include <vector>
#include "header_using_std_namespace.h" // assuming it uses `vector` somewhere

Source TUs might have been more isolated before, but were also at risk of a transitive include coming in over time.

@GabrielDosReis
Copy link

In contrast, /ifcMap expects a TOML file (which suggest it's expected to be written manually by the user).

No. The expectation isn't that the IFC reference map is manually authored. Rather, what experience has consistently shown is that deploying header units at scale is an iterative process and ability to quickly look at the mapping and do a local edits of a file that might have been automatically generated is most useful.

Summary: you can generate the IFC reference map by a tool; there is no expectation that is it manually written by the user.

@GabrielDosReis
Copy link

If I cannot reuse the existing .d file, my next best solution is to just generate a response file on the fly but only if the command line is too long.

Response files work too! I was pointing out the IFC reference map as a more scalable way (from the CL processing perspective), but there is no obligation to take advantage of it if you find it not appropriate for your purposes.

@GabrielDosReis
Copy link

Let me know if you would be amenable to supporting something similar to the GCC's format and I would be happy to file an issue.

At this point, that is not something the team is prioritizing.

@GabrielDosReis
Copy link

Here you go: https://developercommunity.visualstudio.com/t/Please-clarify-ifwhen-Zc:preprocessor/10537317

Thanks!
The team is looking at it. As usual, the culprits are major codebases and libraries on Windows that have gotten conformable with the non-conforming preprocessor over decades.

@GabrielDosReis
Copy link

For example, the user can already specify the /ifcMap option on the command line and map <vector> to std.ifc, but nobody is going to make sure that when std.ifc changes, all the TUs that import <vector> are going to be rendered out of date.

I am not sure I understand. The idea isn't that the build2 user explicitly supply the IFC reference map that maps says map <vector> to std.ifc. Rather the suggestion is that build2 provides a declarative mechanism for the user to say "all uses of <vector> can be translated to uses std. So, if std.ifc ever changes, then those uses are also out of date. No?

Anyway, the mechanism is there, if you ever finds it useful for build2 users.

@GabrielDosReis
Copy link

I am hoping that the need for header units will greatly diminish with support for import std;

std is one use, but not the only one. "Large" libraries like Qt or Boost to can benefit from it. Most of them have been decomposed in "small" headers, not always because of underlying runtime boundary decomposition concerns, but because of compile-time processing concerns. A big BMI is almost always faster to process than a large number of small BMIs in the same file.

@GabrielDosReis
Copy link

It's something far more under the direction of the header unit provider than the consumer.

Exactly!

And it is beyond just standard library modules.

@GabrielDosReis
Copy link

Dual-personality header unit/named module BMIs, how hard can that be? ;-)

Actually, it is not really about replacing an unnamed module by a named module. It is about subsuming a large collection of small BMIs with a single large BMI.

@helmesjo
Copy link

helmesjo commented May 8, 2024

@GabrielDosReis FYI: https://developercommunity.visualstudio.com/t/Unable-to-mix-import-std-with-standard/10541166

FYI, this has apparently now been fixed and is pending release (above issue was marked as duplicate of the following):
https://developercommunity.visualstudio.com/t/VS2022-175-Preview-3---Compiler-bug-wit/10256508

@Klaim
Copy link
Member

Klaim commented May 8, 2024

FYI, this has apparently now been fixed and is pending release (above issue was marked as duplicate of the following): https://developercommunity.visualstudio.com/t/VS2022-175-Preview-3---Compiler-bug-wit/10256508

Note that bugs related with this fix were found in 17.10-previews too and has been fixed but not released yet.

@boris-kolpackov
Copy link
Member Author

Ok, I believe named modules support in MSVC (including import std;) is now in a good shape for the 0.17.0 release so I am going to close this meta-issue. If you encounter any problems in this area, please file specific issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
modules C++ Modules support related.
Development

No branches or pull requests

5 participants