includefile(release.yo)

htmlbodyopt(text)(#27408B)
htmlbodyopt(bgcolor)(#FFFAF0)
whenhtml(mailto(Frank B. Brokken: f.b.brokken@rug.nl))

DEFINEMACRO(lsvoption)(3)(\
    bf(--ARG1)=tt(ARG3) (bf(-ARG2))\
)
DEFINEMACRO(lsoption)(2)(\
    bf(--ARG1) (bf(-ARG2))\
)

DEFINEMACRO(icm)(0)(bf(icmodmap))
DEFINEMACRO(Icm)(0)(bf(Icmodmap))

DELETEMACRO(tt)
DEFINEMACRO(tt)(1)(em(ARG1))

COMMENT( man-request, section, date, distribution file, general name)
manpage(icmodmap)(1)(_CurYrs_)(icmake._CurVers_)
        (initializes C++ projects using modules)

COMMENT( man-request, larger title )
manpagename(icmodmap)(Initializes the maintenance of C++ projects using
                      modules)

COMMENT( all other: add after () )
manpagesynopsis()
       icm() tt([Options] [arg])

manpagedescription()

Although modules have already been available for quite some time, the Gnu
tt(g++) compiler still shows a number of bugs related to C++ modules
(cf. tt(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. Icm() determines this order and
prepares the construction of programs using modules. Once icm() has done its
job your favorite build-utility can be used as before. Just make sure that
compilation uses the same bf(C++) standard as used by icm(), and provide the
tt(-fmodules-ts) compiler option when compiling source files. 

Icm() 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 tt(mod) (e.g., tt(modsupport.cc). If a
program defines two modules tt(First) and tt(Second) (e.g., in sub-directories
tt(first) and tt(second) and tt(second/modsecond.cc) imports module tt(First)
then tt(first/modfirst.cc) must be compiled before compiling
tt(second/modsecond.cc). This requirement is handled by icm(). Once the source
files containing module interface units have been compiled the program's
remaining source files can be compiled as usual.

By default icm() expect projects using modules to be organized this way:
    itemization(
    it() The project's top-level directory contains a file tt(CLASSES), where
        each line (ignoring (bf(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;
    it() If the project defines a program, the project's top-level directory
        contains source files (like tt(main.cc)) defining the tt(main)
        function. Icm() 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).
    it() 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 tt(CLASSES) file. E.g.,
 verb(
    module
    module/part1
    module/part2
 )
    it() 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.
    )

Icm() inspects each directory specified in the tt(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.,
tt(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 tt(--colors,
--extension) and tt(--subdir) in section bf(Options)):
 verb(    /bin/g++ ${ICMAKE_CPPSTD} -fmodules-ts -c -Wall)
    If the environment variable ttICMAKE_CPP) standard is not defined then the
bf(C++) standard used by default by the compiler is used. To define it use
e.g., tt(export ICMAKE_CPPSTD=--std=c++26).

manpagesection(The program's argument)

The program's argument can be omitted or it can be specified in various ways:
    itemization(
    it() when not specified icm() starts its mapping process, according to
        its default or explicitly specified options. E.g, when merely calling
        icm() it locates the project's source files containing interface
        units, determines their compilation order, and compiles those files in
        the determined order;
    it() when specified as tt(clean) the project's tt(gcm.cache) sub-directory
        and the tt(gcm.cache) soft-links are removed. Compiled object files
        (e.g., files under tt(tmp/o) are not removed; removing those files is
        left to the used build-utility);
    it() 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
    it() otherwise icm()'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.
    )

manpageoptions()

  tt(Icmodmap) supports the following options:
    itemization(
    it() lsoption(colors)(c)nl() 
       by default the compiler is called using the option
        tt(-fdiagnostics-color=never). When this option is specified the
        compiler messages may use colors;

    it() lsoption(dependencies)(d)nl()
        the dependencies between modules is shown using this option. Module
        defining source files are not compiled. bf(Icmodmap's) output may look
        like this:
 verb(    Dependencies:
       LOCAL module Square
       LOCAL module DepSquare
           imports LOCAL module Square
 )
       indicating that modules tt(Square) and tt(DepSquare) are defined by
        the current project, and the module tt(DepSquare) depends on the
        module tt(Square).

        It's also possible that modules depend on modules defined by other
        projects. In that case the output may look like this:
 verb(    Dependencies:
       LOCAL module Square
           imports EXTERN module RectAngle
       LOCAL module DepSquare
           imports LOCAL module Square
       EXTERN module RectAngle
 )
       In this example module tt(RectAngle) is a module made available by some
        other project. The local modue tt(DepSquare), as before, depends on
        tt(Square). In this example the tt(RectAngle.gcm) file must be
        available in the project's tt(gcm.cache) directory before module
        tt(Square) can be compiled (it's normally made available via a
        soft-link to the actual file);

    it() lsvoption(extension)(x)(ext)nl()
       tt(ext) is the extension of the source files inspected by icm(). By
        default it is tt(.cc);

    it() lsvoption(extern)(e)(arg)nl()
       when modules depend on externally available modules then the locations
        of the directories containing those tt(.gcm) files can be specified
        using this option. If those external tt(.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 tt(arg).

       If those external tt(.gcm) files are located in multiple directories
        then the locations of those directories are specified in a file which
        is specified by tt(arg). In this case each of tt(arg's) lines
        specifies the location of an external directory, ignoring  empty
        lines and lines starting with tt(//);

    it() lsoption(help)(h)nl()
       Provides usage info, returning 0 to the operating system;

    it() lsvoption(ignore)(i)(list)nl()
       use this option instead of using the tt(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
        tt(list) argument. If tt(list) must specify multiple directories then
        surround the space-separated sub-directory names by quotes. To visit
        all sub-directories use tt('');

    it() lsvoption(library)(l)(lib)nl()
       tt(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;

    it() lsvoption(mark)(m)(arg)nl()
       tt(arg) can be +, ++, or a filename. When this option is used interface
        units depending on other modified interface units are also compiled.

       If tt(arg) is ++ then the last write times of em(all) files
        implementing or using those interface units are set to the current
        time.  

       If tt(arg) is neither + nor ++ then tt(arg) is the name of a file it
        receiving the names of the files otherwise processed by '++';

    it() lsvoption(quiet)(q)(what)nl()
       by default the compiler calls and the dependencies are written to the
        std. output stream. Specify 'what' as:nl()
        c - to suppress showing the compiler commands;nl()
        d - to suppress showing the dependencies;nl()
        any other argument: both 'c' and 'd'.nl()
        tt(--verbose) suppresses --quiet;

    it() lsoption(subdir)(s)nl()
       By default the project's tt(tmp/o) sub-directory receives the compiled
        interface unit files, using their tt(CLASSES') compilation order
        number prefix (e.g., tt(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);

    it() lsoption(version)(v)nl()
       Displays icm()'s version.

    it() lsoption(verbose)(V)nl()
       Shows additional output when determining the module compilation order
        and compiling the module definition files.
    )

manpagesection(EXAMPLE)

    The following program defines a module tt(Square) in its sub-directory
tt(square), containing this tt(modsquare.cc) file:

        verbinclude(example/square/modsquare.cc)

    The tt(main) function imports the tt(Square) module and uses its
facilities. It also imports the tt(iostream) module-compiled system
header. That header is not inspected by icm(), and must be available before
the tt(main.cc) file can be compiled. Here is the tt(main.cc) source file:

        verbinclude(example/main.cc)

Executing tt(icmodmap -d) shows tt(Square) as a local module:
 verb(    Dependencies:
       LOCAL module Square
 )

Executing tt(icmodmap -V) performs and shows the compilation of
tt(square/module.cc) as well as the names of the source files implementing
(declaring) its components or merely importing the module:
 verb(
    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 
 )

manpageseealso()
    bf(icmake)(1).

manpagebugs()
    None reported.

includefile(trailer.inc)



