---
name: "icmodmap"
section: "1"
platform: "linux"
package: "icmake"
version: "13.07.00-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/icmodmap"
---

# icmodmap(1)

Initializes the maintenance of C++ projects using modules

## 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)](/icmake/1.md).

## 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**).
