As mentioned above, even /clang:
doesn’t work correctly with clang-cl
.
Out of curiosity, has there been any progress on this—or at least the latter proposal to add the clang.exe
flags to clang-cl.exe
via /clang:
or -Xclang
?
No. We don’t have any progress on this. And it seems like we don’t have concrete plans here since we lack developers who works on windows.
I’m not experienced with the whole llvm ecosystem so i don’t understand the talk here but is there reliable working way in which i can use to compile my modules?
Also is there a way in which i dont have to reference every module one by one manually and also not have to precompile the modules in a seperate command?
-Xclang is completely fine with me i just need a working solution.
I’m not experienced with the whole llvm ecosystem so i don’t understand the talk here but is there reliable working way in which i can use to compile my modules?
If you’re talking about clang-cl.exe
, we don’t know that yet.
Also is there a way in which i dont have to reference every module one by one manually and also not have to precompile the modules in a seperate command?
This should be the job of build systems. Maybe you can try out cmake3.28.
okay, i use the standard visual studio build system but, apparently due to the lack of support of modules in clang-cl, i cannot use them.
I guess i have to wait for the support then, i’ll probably just don’t use modules until some solution appears. If you or anyone discovers something new, please tell me. Header only library stuff sucks
Some embrassing things about clang-cl is that we don’t have developers on the windows environment. So maybe users of clang-cl can only tried to test that like the OP does.
More testing reveals that I needed to additionally pass .\Hello.pcm
itself as an input file.
Therefore, the following works, and produces Hello.exe
(with a strange warning):
> clang-cl.exe /std:c++20 .\Hello.cppm /clang:--precompile /Fo.\Hello.pcm
> clang-cl.exe /std:c++20 .\use.cpp /clang:-fprebuilt-module-path=. .\Hello.pcm /Fe.\Hello.exe
clang-cl: warning: argument unused during compilation: '/std:c++20' [-Wunused-command-line-argument]
> .\Hello.exe
Hello World!
The following also works:
> clang-cl.exe /std:c++20 .\Hello.cppm /clang:--precompile /Fo.\Hello.pcm
> clang-cl.exe /std:c++20 .\use.cpp /clang:"-fmodule-file=Hello=.\Hello.pcm" .\Hello.pcm /Fe.\Hello.exe
clang-cl: warning: argument unused during compilation: '/std:c++20' [-Wunused-command-line-argument]
> .\Hello.exe
Hello World!
So, clang-cl.exe
supports at least the minimal example.
I guess the warning comes from the linking stage. If you can remove the warning finally, I think you can add a section about hello world example in the document .
@ChuanqiXu that is my next step. I’d additionally add that @JVApen’s idea of directly supporting these -fmodule
flags in the clang-cl.exe
driver is a good idea. I’ve been recently building and debugging the driver, and it seems fairly trivial to support them—just need to add them to the relevant .inc
file, seemingly.
It seems there is existing demand for clang-cl
to implement MSVC’s flags as listed in the OP:
Even though as mentioned in those threads, clang-cl
is exactly the same binary as clang
, and as discovered here we can forward GNU-style module arguments, it is considerably easier for consumers (both on the command-line, and script consumers like CMake) to use MSVC’s flags as-is with clang-cl
, like everything else.
I’d like some input from the Clang maintainers on this.
It’s already clear that BMIs are non-compatible across compilers and compiler versions, so it shouldn’t be expected that clang-cl
BMIs will actually map to MSVC’s ‘IFC’ format. This is a first step we can take, and as mentioned, simply map existing MSVC options to GNU-like Clang module options.
As a longer term solution, MSVC’s IFC SDK has been open-sourced, which LLVM could use to implement these options for full compatibility.
Side note: I think it’s unfortunate on MSVC’s part that they’ve used the ifc
prefix which really ought to be an implementation detail.
Thoughts are welcome.
Notable detail here is that IFC SDK is licensed under Apache 2.0 with LLVM exception, which clears licensing concerns of using this third-party code.
it is considerably easier for consumers (both on the command-line, and script consumers like CMake) to use MSVC’s flags as-is with
clang-cl
, like everything else.
Yes, but we can’t do that for ifc-related options if we don’t implement IFC actually.
As a longer term solution, MSVC’s IFC SDK has been open-sourced, which LLVM could use to implement these options for full compatibility.
Yes, we could. But we can’t make a promise due to the limited human resources.
With this pull request, the --precompile
and -fmodule-*
options are now available in clang-cl.exe
as well. As mentioned, I have tested with the ‘hello world’ example, which works OK. A set of proper test cases is required, and I’m working through how to set such test cases up.
The real end goal is to support MSVC’s IFC options by actually emitting IFCs, but I think this is a decent workaround.
Thanks. While it looks true that it may be best to support IFC format in clang technically, from my experience and observation, from the resources we have, it’ll be super hard. Not only implementing it, but also maintaining it. What I want to say is, it may be better to not expect that (support IFC in clang) will happen in any recent times.
I’ll suggest build system vendors to use --precompile
and -fmodule-*
options for clang-cl instead of waiting for clang-cl to implement MSVC’s options formally.
It’d be great if we could get input from build system vendors about their take on this as well, if they agree with the direction, or if they’d prefer for us to use the existing MSVC style options, even if the internal binary representation is different. (Isn’t the binary representation of compiled modules more or less compiler version specific anyway?)
It doesn’t really matter much to me as a build system (it’s a single set of variable changes in CMake). I feel like without actual cl
compatibility, cl
flags might not be the wisest choice though. If -ifcFormat:2
or whatever happens, I have no idea what that means if other -ifc*
flags are actually Clang’s module format. Similarly for things like -fclang-minimal-modules
or the like.
I specifically asked build system authors about their thoughts on the situation in this Reddit thread, and received few truly relevant responses from truly relevant stakeholders.
I went ahead and ‘implemented’ the clang
options in clang-cl
because after about a couple weeks of poking around, it boiled down to a couple of one-liners in the options setup.
Personally I think it would be a lofty goal for Clang to implement IFC (from what I recall, Microsoft would like it to become a universal binary standard to describe C++ source), but what I’ve done works today.
After sitting on this for about a year, I’m now not entirely sure of the value of mapping /ifc
options to clang
’s -fmodule*
options; there are subtle but important differences.
As of LLVM 19.1.0-rc3, these PRs have now been merged in and are available for use.
It looks like I have to pick this up again.
clang-cl
doesn’t seem to like the /Fo
flag for dyndep files nor for built-module interfaces. Instead, it requires the more verbose /clang:-o /clang:<file>
. The bug seems to come from Driver.cpp:5902. When /Fo
(or even a naked -o
without a preceding /clang:
) is provided, this condition evaluates to false, and the primary-output
field in the resulting P1689 JSON file is "-"
, which seems to come from this return value. Likewise, when a BMI is requested as the output with /Fo
, that BMI file is never output, even though the compilation appears to succeed (with a warning flag); see the following Ninja build output for an example (taken from the CMake tests):
[5/7] C:\PROGRA~1\LLVM\bin\clang-cl.exe /nologo -TP /DWIN32 /D_WINDOWS /EHsc /Ob0 /Od /RTC1 -std:c++20 -MDd -Zi --precompile /showIncludes @CMakeFiles\CXXModules__export_transitive_modules1@synth_40747d24b8d6.dir\61935f85daf0.bmi.modmap /FoCMakeFiles\CXXModules__export_transitive_modules1@synth_40747d24b8d6.dir\61935f85daf0.bmi /Fd"" -c -- R:\cmake\Tests\RunCMake\CXXModules\examples\export-transitive-modules1-build\importable.cxx
clang-cl: warning: argument unused during compilation: '-TP' [-Wunused-command-line-argument]
[6/7] C:\PROGRA~1\LLVM\bin\clang-cl.exe /nologo -TP /DWIN32 /D_WINDOWS /EHsc /Ob0 /Od /RTC1 -std:c++20 -MDd -Zi /showIncludes @CMakeFiles\export_transitive_modules.dir\importable.cxx.obj.modmap /FoCMakeFiles\export_transitive_modules.dir\importable.cxx.obj /FdCMakeFiles\export_transitive_modules.dir\export_transitive_modules.pdb -c -- R:\cmake\Tests\RunCMake\CXXModules\examples\export-transitive-modules-build\importable.cxx
FAILED: CMakeFiles/export_transitive_modules.dir/importable.cxx.obj CMakeFiles/export_transitive_modules.dir/importable.pcm
C:\PROGRA~1\LLVM\bin\clang-cl.exe /nologo -TP /DWIN32 /D_WINDOWS /EHsc /Ob0 /Od /RTC1 -std:c++20 -MDd -Zi /showIncludes @CMakeFiles\export_transitive_modules.dir\importable.cxx.obj.modmap /FoCMakeFiles\export_transitive_modules.dir\importable.cxx.obj /FdCMakeFiles\export_transitive_modules.dir\export_transitive_modules.pdb -c -- R:\cmake\Tests\RunCMake\CXXModules\examples\export-transitive-modules-build\importable.cxx
clang-cl: warning: argument unused during compilation: '-TP' [-Wunused-command-line-argument]
R:\cmake\Tests\RunCMake\CXXModules\examples\export-transitive-modules-build\importable.cxx(2,1): fatal error: module file 'CMakeFiles\CXXModules__export_transitive_modules1@synth_40747d24b8d6.dir\61935f85daf0.bmi' not found: module file not found
2 | import module1;
| ^
1 error generated.
Despite the error, this build silently fails in step [5/7]
because CMakeFiles\CXXModules__export_transitive_modules1@synth_40747d24b8d6.dir\61935f85daf0.bmi
file is never output, despite being requested with /Fo
.
I’d like some clarity on whether this really is a driver bug, or is intended behaviour with respect to the /Fo
flag.