PrevUpHome

day-25: Special: c++ modules gcc


The gcc used for this article is 16.0.0, built from gcc git source code. (Apr 24, 2025).

Alias gpp:

alias gpp="path/to/the/g++ -fmodules-ts -std=c++26"

First: import std;

import declaration: import module units, module partitions, header units.

hello.cpp :

import std;

int main()
{
	std::cout << "Hello, c++ modules!" << std::endl;
}

Compile at the first time:

(a little slow)

> gpp -fsearch-include-path bits/std.cc hello.cpp -o hello
> ./hello
Hello, c++ modules!

It will create gcm.cache/std.gcm at current working directory.

Compile not at the first time:

(very fast)

After the cache is generated at the first time, the compiling is super fast.

> gpp hello.cpp -o hello
> ./hello
Hello, c++ modules!

The cache ./gcm.cache can be removed and you repeat above steps again, it works, you can try it!

The cache ./gcm.cache/std.gcm will be reused for the rest parts of this article conveniently.

Next: Make a c++ module

export declaration:

c++ module declaration starts with a keyword export or module.

E.X:

export module module-name;

Declares a primary module interface unit and export, its name is module-name .

export namespace.

Make a c++ module, source code: my_class.cpp

my_class.cpp :

export module my_module;

import std;

export namespace my_space
{
	class my_class
	{
	public:
		void greeting() const
		{
			std::cout << "Cheers, c++!" << std::endl;
		}
	};
}

Use the module, source code: main.cpp

main.cpp :

import my_module;

int main()
{
	my_space::my_class my_object;
	my_object.greeting();
}

Compile them :

> gpp main.cpp my_class.cpp -o main
> ./main
Cheers, c++!

Next: Modules Shared Library

Just compile the module source c++ file to shared library.

my_cpp.cpp :

export module my_module;
export import std;
export namespace my_space
{
	class my_class
	{
	private:
		int __x;
	public:
		my_class(int x__): __x{x__} {}
	public:
		int get() const {return __x;}
	};
}

main.cpp :

import my_module;
int main()
{
	my_space::my_class object{234};
	std::cout << "get: " << object.get() << std::endl;
}

Compile :

> gpp my_cpp.cpp -c -fPIC -shared -o libmy_cpp.so
> gpp main.cpp -L./ -lmy_cpp -o main
> ./main
get: 234

Next: Module Partition

A module partition can be imported by module units of the same named module.

In this example, :my_partition can be imported by my_module, it can not be imported by other module.

my_cpp_part.cpp :

export module my_module:my_partition;

export namespace my_space
{
	class my_class_2
	{
	public:
		int get() const
		{
			return -112233;
		}
	};
}

my_cpp.cpp :

export module my_module;

export import :my_partition;

export namespace my_space
{
	class my_class
	{
	public:
		int get() const
		{
			return 3333;
		}
	};
}

main.cpp :

import my_module;
import std;

int main()
{
	my_space::my_class obj1;
	std::cout << "v: " << obj1.get() << std::endl;
	my_space::my_class_2 obj2;
	std::cout << "v: " << obj2.get() << std::endl;
}

Compile :

(compile order is important, my_cpp.cpp depends on my_cpp_part.cpp)

> gpp my_cpp_part.cpp my_cpp.cpp -c -fPIC
> gpp *.o -shared -o libmy_cpp.so
> gpp main.cpp -L./ -lmy_cpp -o main
> ./main
v: 3333
v: -112233

Next: Header Unit

First, precompile :

> gpp -xc++-system-header boost/parser/parser.hpp
> gpp -xc++-system-header iostream

Then, use :

import <boost/parser/parser.hpp>;
import <iostream>;

int main()
{
	std::cout << "Hello, c++!" << std::endl;
}

Compile :

> gpp program.cpp -o program

Next: Split Definitions for Shared Library

my_cpp.cpp :

export module my_module;
export namespace my_space
{
	class my_class
	{
	public:
		void greeting() const;
		void cheers() const;
		int get() const;
		virtual ~my_class();
	};
}

my_cpp_src.cpp :

module my_module;
import std;
my_space::my_class::~my_class()
{
	std::cout << "Bye, c++!" << std::endl;
}
void my_space::my_class::greeting() const
{
	std::cout << "Greeting, c++!" << std::endl;
}
void my_space::my_class::cheers() const
{
	std::cout << "Cheers, c++!" << std::endl;
}
int my_space::my_class::get() const
{
	return 12345;
}

main.cpp :

import my_module;
import std;
int main()
{
	my_space::my_class my_object;
	my_object.greeting();
	my_object.cheers();
	std::cout << "get: " << my_object.get() << std::endl;
}

Compile :

> gpp my_cpp.cpp my_cpp_src.cpp -c -fPIC
> gpp my_cpp.o my_cpp_src.o -shared -o libmy_cpp.so
> gpp main.cpp -L./ -lmy_cpp -o main
> ./main
Greeting, c++!
Cheers, c++!
get: 12345
Bye, c++!

About Module Declaration

Declare Primary Module Unit

(Name is A)

export module A;

(Name is A.B)

export module A.B;

Declare Module Implementation Unit

module A;
module A.B;

constexpr and template

constexpr and template declared api can not be splitted into two declaration and definition module files.

Next: c++ Modules in B2 Build System

c++ modules gcc can be used in b2 build by flags settings trick.

First: About import std;

First, generate gcm.cache/std.gcm cache in current working directory like talked in the beginning of this article, I am a little lazy of how to make it by a b2 jamfile trick.

c++ source files

The same c++ source files of previous section of this article will used for this project:

(Split Definitions for Shared Library)

File: jamroot

The file jamroot in current working directory:

project : requirements <cxxflags>"-fmodules-ts" : default-build <cxxstd>26 ;
lib my_cpp : my_cpp.cpp my_cpp_src.cpp ;
exe main : main.cpp : <library>my_cpp ;

Build the project

Build:

> b2 -q -j7

Trick: run above command twice, the first run will generate errors, the second run will be OK.

Make sure the toolset used for this project is gcc. Visual c++ and clang++ has different compiler flags.

Run program:

> ls ./bin/gcc-latest/debug/cxxstd-26-iso/
libmy_cpp.so  main  main.o  my_cpp.o  my_cpp_src.o
>
>
>
> ./bin/gcc-latest/debug/cxxstd-26-iso/main
Greeting, c++!
Cheers, c++!
get: 12345
Bye, c++!

Last: Glossary

Module Declaration

...

Module definition

...

Export Declaration

...

Import Declaration

...

Translation Unit

...

Module Unit

A module unit is a translation unit which has a module declaration.

Module Partition Unit

A module partition unit is a module unit which is included by a module unit and starts with a colon : , and is placed after the module name.

For example,

export module A:B;
export module A;

Module Name

Module name is the name of the module unit, which consists of one or more identifiers separated by dots. Note that module partition unit is also module unit.

For example,

// Module name is A
export module A;
// Module name is A.B.C
export module A.B.C;

Date

Written on Apr 24, 2025

Back to index

Index

cpp/c++

c++ std::exception:

std::cout.write(err.data(), err.size());

std::cout << std::endl;

caught:

  ===================================
  #  The c++ programming language.  #
  #                                 #
  #  Join c++                       #
  #  Deck                           #
  ===================================

Home: cppfx.xyz


PrevUpHome