3.23.1 Module Mapper

A module mapper provides a server or file that the compiler queries to determine the mapping between module names and CMI files. It is also used to build CMIs on demand. Mapper functionality is in its infancy and is intended for experimentation with build system interactions.

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:


An optional hostname and a numeric port number to connect to. If the hostname is omitted, the loopback address is used. If the hostname corresponds to multiple IPV6 addresses, these are tried in turn, until one is successful. If your host lacks IPv6, this form is non-functional. If you must use IPv4 use -fmodule-mapper='|ncat ipv4host port'.


A local domain socket. If your host lacks local domain sockets, this form is non-functional.

|program[?ident] [args...]

A program to spawn, and communicate with on its stdin/stdout streams. Your PATH environment variable is searched for the program. Arguments are separated by space characters, (it is not possible for one of the arguments delivered to the program to contain a space). An exception is if program begins with @. In that case program (sans @) is looked for in the compiler’s internal binary directory. Thus the sample mapper-server can be specified with @g++-mapper-server.


Named pipes or file descriptors to communicate over. The first form, <>, communicates over stdin and stdout. The other forms allow you to specify a file descriptor or name a pipe. A numeric value is interpreted as a file descriptor, otherwise named pipe is opened. The second form specifies a bidirectional pipe and the last form allows specifying two independent pipes. Using file descriptors directly in this manner is fragile in general, as it can require the cooperation of intermediate processes. In particular using stdin & stdout is fraught with danger as other compiler options might also cause the compiler to read stdin or write stdout, and it can have unfortunate interactions with signal delivery from the terminal.


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.

As shown, an optional ident may suffix the first word of the option, indicated by a ‘?’ prefix. The value is used in the initial handshake with the module server, or to specify a prefix on mapping file lines. In the server case, the main source file name is used if no ident is specified. In the file case, all non-blank lines are significant, unless a value is specified, in which case only lines beginning with ident are significant. The ident must be separated by whitespace from the module name. Be aware that ‘<’, ‘>’, ‘?’, and ‘|’ characters are often significant to the shell, and therefore may need quoting.

The mapper is connected to or loaded lazily, when the first module mapping is required. The networking protocols are only supported on hosts that provide networking. If no mapper is specified a default is provided.

A project-specific mapper is expected to be provided by the build system that invokes the compiler. It is not expected that a general-purpose server is provided for all compilations. As such, the server will know the build configuration, the compiler it invoked, and the environment (such as working directory) in which that is operating. As it may parallelize builds, several compilations may connect to the same socket.

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.

The mapper protocol was published as “A Module Mapper” https://wg21.link/p1184. The implementation is provided by libcody, https://github.com/urnathan/libcody, which specifies the canonical protocol definition. A proof of concept server implementation embedded in make was described in ”Make Me A Module”, https://wg21.link/p1602.