Provided by: icmake_13.02.00-1ubuntu1_amd64 

NAME
icmodmap - Initializes the maintenance of C++ projects using modules
SYNOPSIS
icmodmap [Options] [arg]
DESCRIPTION
Although modules have already been available for quite some time, the Gnu g++ compiler still shows a
number of bugs related to C++ modules (cf. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103524). It’s
possible that you stumble across some of these (or new) bugs when using modules. The number of reported
bugs is gradually reducing, and the current state of affairs at least allows you to gain some experience
in using modules.
Modules cannot mutually import each other. Consequently there’s always a linear, non-circular module
hierarchy, which should be acknowledged when compiling files defining and using modules. Icmodmap
determines this order and prepares the construction of programs using modules. Once icmodmap has done its
job your favorite build-utility can be used as before. Just make sure that compilation uses the same C++
standard as used by icmodmap, and provide the -fmodules-ts compiler option when compiling source files.
Icmodmap assumes that modules are defined in separate sub-directories. For your own documentation it’s
advised that filenames containing module (and partition) interface units start with mod (e.g.,
modsupport.cc. If a program defines two modules First and Second (e.g., in sub-directories first and
second and second/modsecond.cc imports module First then first/modfirst.cc must be compiled before
compiling second/modsecond.cc. This requirement is handled by icmodmap. Once the source files containing
module interface units have been compiled the program’s remaining source files can be compiled as usual.
By default icmodmap expect projects using modules to be organized this way:
o The project’s top-level directory contains a file CLASSES, where each line (ignoring (C++)
comment) specifies the name of a sub-directory implementing one of the project’s components. Each
sub-directory can (but does not have to) define a module, a module partition, a class (not part of
a module, but maybe using modules), or other (source) files, maybe using modules;
o If the project defines a program, the project’s top-level directory contains source files (like
main.cc) defining the main function. Icmodmap also recognizes module interface units defined in
the top-level directory (but, for clarity, module interface units should probably be defined in
their own sub-directories).
o Since partitions define sub-components of modules, consider defining partitions in sub-directories
of their module asub-directories. When adopting this organization then these sub-sub-directories
are specified in the CLASSES file. E.g.,
module
module/part1
module/part2
o Modules and partitions may define classes (preferably one class per module, one class per
partition). If so the member functions of those classes can be defined in the module or
partition’s directory.
Icmodmap inspects each directory specified in the CLASSES file, including the top-level directory. It
recognizes interface units and source files implementing module components. It ignores comment, but the
individual parts of specifications can be separated by spaces or tabs but not by comment. E.g., export /*
*/ module Support; is not recognized.
When compiling source files containing interface units the compiler is called using at least the
following options (see also the options --colors, --extension and --subdir in section Options):
/bin/g++ ${ICMAKE_CPPSTD} -fmodules-ts -c -Wall
If the environment variable ttICMAKE_CPP) standard is not defined then the C++ standard used by default
by the compiler is used. To define it use e.g., export ICMAKE_CPPSTD=--std=c++26.
The program’s argument
The program’s argument can be omitted or it can be specified in various ways:
o when not specified icmodmap starts its mapping process, according to its default or explicitly
specified options. E.g, when merely calling icmodmap it locates the project’s source files
containing interface units, determines their compilation order, and compiles those files in the
determined order;
o when specified as clean the project’s gcm.cache sub-directory and the gcm.cache soft-links are
removed. Compiled object files (e.g., files under tmp/o are not removed; removing those files is
left to the used build-utility);
o when specified as - interface unit files are not compiled but their source file names are written
in the required compilation order to the standard output stream
o otherwise icmodmap’s argument is a filename to receive the names of the source files that would
have been written to the standard output stream when argument - would have been specified.
OPTIONS
Icmodmap supports the following options:
o --colors (-c)
by default the compiler is called using the option -fdiagnostics-color=never. When this option is
specified the compiler messages may use colors;
o --dependencies (-d)
the dependencies between modules is shown using this option. Module defining source files are not
compiled. Icmodmap’s output may look like this:
Dependencies:
LOCAL module Square
LOCAL module DepSquare
imports LOCAL module Square
indicating that modules Square and DepSquare are defined by the current project, and the module
DepSquare depends on the module Square.
It’s also possible that modules depend on modules defined by other projects. In that case the
output may look like this:
Dependencies:
LOCAL module Square
imports EXTERN module RectAngle
LOCAL module DepSquare
imports LOCAL module Square
EXTERN module RectAngle
In this example module RectAngle is a module made available by some other project. The local modue
DepSquare, as before, depends on Square. In this example the RectAngle.gcm file must be available
in the project’s gcm.cache directory before module Square can be compiled (it’s normally made
available via a soft-link to the actual file);
o --extension=ext (-x)
ext is the extension of the source files inspected by icmodmap. By default it is .cc;
o --extern=arg (-e)
when modules depend on externally available modules then the locations of the directories
containing those .gcm files can be specified using this option. If those external .gcm files are
all located in a single directory then the location of the that directory (absolute or relative to
the current project’s top-level directory) can be specified by arg.
If those external .gcm files are located in multiple directories then the locations of those
directories are specified in a file which is specified by arg. In this case each of arg’s lines
specifies the location of an external directory, ignoring empty lines and lines starting with //;
o --help (-h)
Provides usage info, returning 0 to the operating system;
o --ignore=list (-i)
use this option instead of using the CLASSES file. When using this option all (one-level deep)
sub-directories (and the project’s top-level directory) are inspected except for those listed in
the list argument. If list must specify multiple directories then surround the space-separated
sub-directory names by quotes. To visit all sub-directories use ’’;
o --library=lib (-l)
lib specifies the path (relative to the project’s top-level directory) of a (library) file
containing the project’s .o files. To determine whether source files defining interface units must
be (re)compiled their timestamps are not only compared to the timestamps of their object files but
also to the timestamp of the library;
o --mark=arg (-m)
arg can be +, ++, or a filename. When this option is used interface units depending on other
modified interface units are also compiled.
If arg is ++ then the last write times of all files implementing or using those interface units
are set to the current time.
If arg is neither + nor ++ then arg is the name of a file it receiving the names of the files
otherwise processed by ’++’;
o --quiet=what (-q)
by default the compiler calls and the dependencies are written to the std. output stream. Specify
’what’ as:
c - to suppress showing the compiler commands;
d - to suppress showing the dependencies;
any other argument: both ’c’ and ’d’.
--verbose suppresses --quiet;
o --subdir (-s)
By default the project’s tmp/o sub-directory receives the compiled interface unit files, using
their CLASSES’ compilation order number prefix (e.g., tmp/o/1modsquare.o, tmp/o/2modepquare.o,
...). When this options is specified the compiled files are located in the same sub-directory as
their source files (in which case an order number prefix is not used);
o --version (-v)
Displays icmodmap’s version.
o --verbose (-V)
Shows additional output when determining the module compilation order and compiling the module
definition files.
EXAMPLE
The following program defines a module Square in its sub-directory square, containing this modsquare.cc
file:
export module Square;
export
{
double square(double value);
class Square
{
double d_amount;
public:
Square(double amount = 0); // initialize
void amount(double value); // change d_amount
double amount() const; // return d_amount
double lastSquared() const; // returns g_squared
double square() const; // returns sqr(d_amount)
};
}
double g_squared;
The main function imports the Square module and uses its facilities. It also imports the iostream
module-compiled system header. That header is not inspected by icmodmap, and must be available before the
main.cc file can be compiled. Here is the main.cc source file:
import Square;
import <iostream>;
int main(int argc, char **argv)
{
std::cout << "the square of " << argc << " is "
<< square(argc) << ’\n’;
Square obj{12};
std::cout << "the square of 12 is " << obj.square() << "\n"
"the last computed square is " <<
obj.lastSquared() << ’\n’;
}
Executing icmodmap -d shows Square as a local module:
Dependencies:
LOCAL module Square
Executing icmodmap -V performs and shows the compilation of square/module.cc as well as the names of the
source files implementing (declaring) its components or merely importing the module:
Defining a soft-link from gcm.cache/usr -> /usr
Inspecting square/
scanning square1.cc
declares module Square
scanning amount1.cc
declares module Square
scanning square.cc
declares module Square
scanning square2.cc
declares module Square
scanning modsquare.cc
defines module Square
scanning amount2.cc
declares module Square
scanning lastsquared.cc
declares module Square
Inspecting ./
scanning main.cc
imports module Square
Compiling...
in square: /bin/g++ --std=c++26 -fdiagnostics-color=never -c
-fmodules-ts -Wall -o ../tmp/o/1modsquare.o modsquare.cc
SEE ALSO
icmake(1).
BUGS
None reported.
COPYRIGHT
This is free software, distributed under the terms of the GNU General Public License (GPL).
AUTHOR
Frank B. Brokken (f.b.brokken@rug.nl).
icmake.13.02.00 1992-2025 icmodmap(1)