Provided by: icmake_13.02.00-1ubuntu1_amd64 bug

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)