c++ modules g++ clang++ Linux

Just wondering if anyone has experience with the above?

In my mind, it would be great if modules corresponding to each of the STL header files could exist in a standard location similar to the current header files. Ideally, one should only have to have the following in a file, without any further effort:

import <iostream>;

Using g++ the method I used was to have a header file:

1
2
//mod-iostream.h
#include <iostream> 


Which I compile into a module. I the idea was to do this for each STL header file.

However, on my system it creates files in a ~/projects/module-test/,/gcmcache folder . Note the comma, I am guessing that is a little bug -> did they mean to have .gcmcache as a hidden folder? So I am thinking this setup is geared toward users creating their own modules from their own code.

I have tried to copy/move/create these files to the same directory as the STL headers, but to no avail, they seem tied to the cwd. In hindsight it does mention this in the documentation. This is a little painful in that one would have to at least copy the created files from one project to another.

With clang++, it has a whole procedure for module mapping - I am yet to try this out. Clang++ also has other procedures which create pre-compiled module files (*.pcm) as an intermediate compilation/linking step.

So with both g++ and clang++ there are hoops to jump through. I realise that all this is experimental at the moment, but MS seems to compiled all the STL headers, it would be great if g++ and clang++ could do the same.

Has anyone else done anything different to the above?

Btw, I have just built g++ 12.0 and clang++ 15.0 , so will see how that goes.

I found this:
https://blog.ecosta.dev/en/tech/cpp-modules-with-clang

Will try it !
Last edited on
Update:

In the manual for g++ :

https://gcc.gnu.org/onlinedocs/gcc-11.2.0/gcc/C_002b_002b-Module-Mapper.html#C_002b_002b-Module-Mapper

There is this:

gplusmanual wrote:
You can specify a mapper with the -fmodule-mapper=val option or CXX_MODULE_MAPPER environment variable. The value may have one of the following forms:

... snip

file[?ident]

A mapping file consisting of space-separated module-name, filename pairs, one per line. Only the mappings for the direct imports and any module export name need be provided. If other mappings are provided, they override those stored in any imported CMI files. A repository root may be specified in the mapping file by using ‘$root’ as the module name in the first active line. Use of this option will disable any default module->CMI name mapping.


In turns out that the comma in the local directory name is not a bug:

gplusmanual wrote:
The default mapper generates CMI files in a ‘gcm.cache’ directory. CMI files have a ‘.gcm’ suffix. The module unit name is used directly to provide the basename. Header units construct a relative path using the underlying header file name. If the path is already relative, a ‘,’ directory is prepended. Internal ‘..’ components are translated to ‘,,’. No attempt is made to canonicalize these filenames beyond that done by the preprocessor’s include search algorithm, as in general it is ambiguous when symbolic links are present.


I will try that, see if I can make a bunch *.gcm files, put them in the same directory as the STL headers and compile with -fmodule-mapper= STL-module-map

I am hoping that I can put all the exports into one file, as in:

1
2
3
4
5
module iostream;
export import iostream;
module vector;
export import vector;
// and so on 


I am hoping this will create individual gcm files, because before it created a gcm file based on my header file name.
Last edited on
I haven't experimented with modules yet. From what I've heard support is lacking and not production ready.

It seems like in the future all we will have to do is import std; I'm looking forward to that.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2465r3.pdf
Last edited on
Thanks Peter for your reply :+)

I read Bjarne's paper: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2412r0.pdf

Interesting how quick it is, but I wonder why it doesn't create a huge amount of work for the linker? Although I notice that the iostream.o file I made is only 2200 bytes -> amazing as this the whole thing before it knows what's in the actual code main.cpp. It looks like the import statement in main.cpp throws out what it doesn't need? the iostream.gcm file was 5.1MB

I managed to compile modules following the instructions here:

https://reddit.fun/143442/g-11-2-0-failed-to-read-compiled-module-bad-file-data

The only complication I had was due to me having two versions of g++ (11.2.1 and 12.0.1) so I had to specify the library:

$ g++12 -fmodules-ts -std=c++20 main.cpp iostream.o -L/usr/local/lib/gcc/x86_64-pc-linux-gnu/lib64/ -o test

$ ./test
Hello World!


Right, so now I can make a module with all the STL headers, and try to put the object file in the $PATH
Last edited on
MS is already pushing generic standard library module imports:
https://docs.microsoft.com/en-us/cpp/cpp/modules-cpp?view=msvc-170

VS does support changing #include <iostream> to import <iostream>; for importing module libraries.

MS module documentation is also advocating a custom module interface file have an extension of .ixx, though VS does support .cppm.

One thing to note is using the MS recommended generic import libraries generates several build warnings.

I believe I'll continue using the "regular" import libraries.

Creating standard library modules manually looks like "work!" to me. :)
Last edited on
Thanks George :+)

Creating standard library modules manually looks like "work!" to me. :)


Yes, I guess you are lucky in that MS has already done it. Hopefully future versions of g++ and clang++ will provide something that is easy to use directly without any extra work.

Despite the complication that modules are tied to the compiler and it's version and the c++ dialect, it looks like the source used to make the object files will be the same. For me, I have g++ 11.2.1 and 12.0.1 and clang++ 13.0 and 15.0 , with c++20 and c++23, so that is some 8 combinations. I think I will only build 2 of them: g++12 with c++23 and clang++15 with c++23, which fits with my policy of always trying to have the latest & greatest :+)

So far all of this has been about creating modules for the STL, exporting my own modules is another story. Also, there is getting it to work with cmake, I found this:

https://stackoverflow.com/questions/57300495/how-to-use-c20-modules-with-cmake

There is also the build2 system, but that is yet another build system - I am still trying to get my head around cmake :+)
To be honest the current way modules are being done, change an #include to an import doesn't seem all that much of a benefit vs. the old way of headers/implementation files. Especially when the clear benefit of modules, the all-encompassing import std; module idea instead of individual modules causes Visual Studio fits.

It's rather weird for C++20 VS is fully compliant, with every other compiler is playing catch-up. In the past with previous C++ standard, and so far with C++23 compliance, VS has been and is well behind the curve compared to other major compilers.

Even without modules some really neat C++20 features like std::format MinGW/GCC don't have the <format> header available. There are some decent new things C++20 brought to the programming toolbox.
Last edited on
re C++23. VS is slightly ahead on C++23 library feature implementation - but, yes, way behind on C++23 core language features. Ahh...
Considering C++23 isn't yet formally adopted and finalized the implementation or lack of it isn't that great of a concern to me. That C++20 has <NOT> been fully implemented yet by all compilers is more than a bit disappointing.
Last edited on
[can't delete]
Last edited on
Ooops, my bad, I missed a word. Edited to correct.

Very early morning here, I haven't had any coffee yet.

That's my excuse, and I'm stickin' to it!
One thing I have noticed with VS and modules...

Importing the standard library headers as modules in newly written code VS compiles the stdlib modules with the first build. Every build afterwards only changed source modules, user written for example, gets re-compiled.

Import the (at this time) non-standard std.whatever modules and VS doesn't compile the modules with the initial project/solution build. The warnings VS vomits up show the stdlib modules are already precompiled with differing settings from what VS sets as default when creating a new C++ project/solution.

The current MS setup with modules kinda busts the idea that using modules saves compile time over the old school header/source setup. *shrug*

Any non-MS documentation on modules that I've run across use the scheme of importing stdlib headers as modules.

Maybe a future standard revision will broach the import std; idea as being worthwhile so every compiler will implement it. I know it would be less cumbersome than the current #include setup that can cause issues when forgetting to include a particular stdlib header or implicitly including headers in other headers.

<rant>I wish every compiler was fully compliant with a standard approved almost 2 years ago. I'd like to test my C++20 code in more than VS.</rant>

M'ok, I'm done now. :)
> Maybe a future standard revision will broach the import std;

P2465
import std; imports everything in namespace std from C++ headers (e.g.
std::sort from <algorithm>) and C wrapper headers (e.g. std::fopen from
<cstdio>). It also imports ::operator new etc. from <new>.

import std.compat; imports all of the above, plus the global namespace
counterparts for the C wrapper headers (e.g. ::fopen).

http://open-std.org/JTC1/SC22/WG21/docs/papers/2022/p2465r3.pdf


> I wish every compiler was fully compliant with a standard approved almost 2 years ago.
> I'd like to test my C++20 code in more than VS.

Even with the laggards GNU and LLVM, things are a lot faster now than it used to be some years earlier. Microsoft has raced ahead; they have more resources than the others.
Well with VS, modules are still experimental (even in VS2022) and have to be specifically enabled via a project property setting. I'm guessing that MS are going to change their implementation at some point which would involve re-compilation of modules to be compatible... They did the same previously with eg std::filesystem.
Well with VS, modules are still experimental (even in VS2022) and have to be specifically enabled via a project property setting.

Not true in my experience with VS2022*. Import stdlib headers as modules (import <iostream>; for example), and enabling the experimental module support is NOT required. I do it all the time.

Only when importing the "wrapper modules" does VS2022 require the setting to be enabled.

The proposed(?) wrapper modules as outlined in JLBorges' pdf aren't implemented in VS, yet either. I know, I tried.

Is that working group paper officially part of the standard, or just a proposal at this time?

The only wrapper modules available are the MS created ones I mentioned earlier.
https://docs.microsoft.com/en-us/cpp/cpp/modules-cpp?view=msvc-170

Several reasons why I don't use the MS wrapper modules, having to endure off-putting warnings of incompatible command-line settings as well having to enable experimental support when I don't have to with the stdlib headers consumed as modules.

*I still have VS2019 installed, which is supposed to have similar module support to VS2022, but I haven't used VS2019 in quite some time for mashing up C++20 code.

Well, I just tested some code in VS2019 I know worked in VS2022 without enabling the experimental support, and 2019 worked just fine without the experimental support being enabled.
box.cppm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
export module box;

import <compare>;

export class Box
{
public:
   Box() = default;
   Box(double l, double w, double h) : m_length { l }, m_width { w }, m_height { h } {}

   double volume() const { return m_length * m_width * m_height; }

   double getLength() const { return m_length; }
   double getWidth()  const { return m_width; }
   double getHeight() const { return m_height; }

   std::partial_ordering operator<=>(const Box& otherBox) const
   {
      return volume() <=> otherBox.volume();
   }
   std::partial_ordering operator<=>(double otherVolume) const
   {
      return volume() <=> otherVolume;
   }

   bool operator==(const Box& otherBox) const
   {
      return m_length == otherBox.m_length
         && m_width == otherBox.m_width
         && m_height == otherBox.m_height;
   }

private:
   double m_length { 1.0 };
   double m_width  { 1.0 };
   double m_height { 1.0 };
};

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import <iostream>;
import <format>;
import <string_view>;
import <vector>;

import box;

void show(const Box& box)
{
   std::cout << std::format("Box({:.1f}, {:.1f}, {:.1f})",
                            box.getLength(), box.getWidth(), box.getHeight());
}
void show(const Box& box1, std::string_view relationship, const Box& box2)
{
   show(box1); std::cout << relationship; show(box2); std::cout << std::endl;
}

int main()
{
   const std::vector boxes { Box {2.0, 1.5, 3.0}, Box {1.0, 3.0, 5.0},
                            Box {1.0, 2.0, 1.0}, Box {2.0, 3.0, 2.0} };
   const Box theBox        { 3.0, 1.0, 4.0 };

   for (const auto& box : boxes)
      if (theBox > box) show(theBox, " is greater than ", box);  // > works

   std::cout << std::endl;

   for (const auto& box : boxes)
      if (theBox != box) show(theBox, " is not equal to ", box); // != works

   std::cout << std::endl;

   for (const auto& box : boxes)
      if (6.0 <= box)   // yes, even double <= Box works!!
      {
         std::cout << "6 is less than or equal to "; show(box); std::cout << std::endl;
      }
}

2019's Intellisense is more prone to "dying" trying to digest modules than 2022.
> Is that working group paper officially part of the standard, or just a proposal at this time?

It is just a proposal at this time. AFAIK, almost certain to be accepted into the standard.


> Only when importing the "wrapper modules" does VS2022 require the setting to be enabled.
> Several reasons why I don't use the MS wrapper modules ...

This is one good reason.

Is there any implementation experience?

Not yet.

The experimental named modules that MSVC has been shipping for a while are a repackaging of the existing library (with no distinction between std::sort and std::_Internal_helper_functions) and divide it into subsets (instead of the "only std" and "std plus global" design here).
http://open-std.org/JTC1/SC22/WG21/docs/papers/2022/p2465r3.pdf
Ooooh, I like this question and answer in that pdf!

Are any macros provided by the Standard Library modules?
No, and this is intentional.


M'ok, just WTF is <meow.h>/<cmeow>?!? Is this some generic place-holder name, or an actual header file I've never seen?
Generic place-holder name.
I now want a header for a C library (and its C++ equivalent) for synthesizing cat meows.
Topic archived. No new replies allowed.