<div dir="ltr">Thanks for designing/working on/contributing this! (I think it's a rather neat thing & do hope it takes off/becomes adopted as the solution for this complicated new compiler surface area required by C++20 modules)</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, May 19, 2020 at 12:48 AM Nathan Sidwell via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
these files are the GCC implementation of the p1184 (wg21.link/p1184) <br>
protocol.  Although part of GCC, they are entirely authored by me, so I <br>
hereby relicense[*] them under the Apache-2.0 with LLVM exception <br>
license, in the hope they may be useful in Clang's implementation.  I <br>
also append the current documentation.<br>
<br>
Iain and I are discussing whether a separate upstream project, from <br>
whence both GCC and Clang can sync, may be the best approach.<br>
<br>
nathan<br>
<br>
[*] Contributions to the FSF give back to the contributor a license to <br>
that code, allowing them to relicense as desired.<br>
<br>
-- <br>
Nathan Sidwell<br>
<br>
@node C++ Module Mapper<br>
@subsection Module Mapper<br>
@cindex C++ Module Mapper<br>
<br>
A module mapper provides a line-based server or file that the<br>
compiler queries to determine the mapping between module names and CMI<br>
files.  It is also used to build CMIs on demand.  A mapper may be<br>
specified with the @option{-fmodule-mapper=@var{val}} option or<br>
@env{CXX_MODULE_MAPPER} environment variable.  The value may have<br>
one of the following forms:<br>
<br>
@table @gcctabopt<br>
<br>
@item @r{[}@var{hostname}@r{]}:@var{port}@r{[}?@var{ident}@r{]}<br>
An optional hostname and a numeric port number to connect to.  If the<br>
hostname is omitted, the loopback address is used.  If the hostname<br>
corresponds to multiple IPV6 addresses, these are tried in turn, until<br>
one is successful.  If your host lacks ipv6, this form is<br>
non-functional.  If you must use ipv4 @emph{get with the 21st century},<br>
or failing that use @option{-fmodule-mapper='|ncat @var{ipv4host}<br>
@var{port}'}.<br>
<br>
@item =@var{socket}@r{[}?@var{ident}@r{]}<br>
A local domain socket.  If your host lacks local domain sockets, this<br>
form is non-functional.<br>
<br>
@item |@var{program}@r{[}?@var{ident}@r{]} @r{[}@var{args...}@r{]}<br>
A program to spawn, and communicate with on its stdin/stdout streams.<br>
Your @var{PATH} environment variable is searched for the program.<br>
Arguments are separated by space characters, (it is not possible for<br>
one of the arguments delivered to the program to contain a space).<br>
<br>
@item <>@r{[}?@var{ident}@r{]}<br>
@item <>@var{fdinout}@r{[}?@var{ident}@r{]}<br>
@item <@var{fdin}>@var{fdout}@r{[}?@var{ident}@r{]}<br>
File descriptors to communicate over.  The first form, @option{<>},<br>
communicates over stdin and stdout.  The second form specifies a<br>
bidirectional file descriptor and the last form allows specifying<br>
two independent descriptors.  Note that other compiler options might<br>
cause the compiler to read stdin or write stdout.<br>
<br>
@item @var{file}@r{[}?@var{ident}@r{]}<br>
A mapping file consisting of space-separated module-name, filename<br>
pairs, one per line.  Only the mappings for the direct imports and any<br>
module export name need be provided.  If other mappings are provided,<br>
they override those stored in any imported CMI files.  A repository<br>
root may be specified in the mapping file by using @samp{$root} as the<br>
module name in the first active line.<br>
<br>
@end table<br>
<br>
As shown, an optional @var{ident} may suffix the first word of the<br>
option, indicated by a @samp{?} prefix.  The value is used in the<br>
initial handshake with the module server, or to specify a prefix on<br>
mapping file lines.  In the server case, the main source file name is<br>
used if no @var{ident} is specified.  In the file case, all non-blank<br>
lines are significant, unless a value is specified, in which case only<br>
lines beginning with @var{ident} are significant.  The @var{ident}<br>
must be separated by whitespace from the module name.  Be aware that<br>
@samp{<}, @samp{>}, @samp{?}  and @samp{|} characters are often<br>
significant to the shell, and therefore may need quoting.<br>
<br>
The mapper is connected to or loaded lazily, when the first module<br>
mapping is required.  The networking protocols are only supported on<br>
hosts that provide networking.  If no mapper is specified a default is<br>
provided.<br>
<br>
Messages consist of whitespace-separated tokens and a possible final<br>
filename.  As filenames are the last item on a line, they may contain<br>
embeded or trailing spaces without difficulty (they cannot begin with<br>
a space).  All non-ascii characters are expected to be UTF8 encoded.  Each<br>
line is terminated by a line-feed (@code{0xa}) character.  The server<br>
should accept and respond to the following commands:<br>
<br>
@table @gcctabopt<br>
<br>
@item DONE @var{module}<br>
The compilation has completed the interface of @var{module}.  There is<br>
no response.  It is now safe to read the generated CMI.  Note that the<br>
compilation may not have completed the object-file generation of the<br>
interface unit.<br>
<br>
@item EXPORT @var{module}<br>
The compilation is of a module interface unit, and will generate a CMI<br>
for @var{module}.  The response should be @samp{OK @var{cmipath}}.<br>
<br>
@item HELLO @var{ver} @var{kind} @var{ident}<br>
This is the first command.  It informs the server of the name of the<br>
source being compiled.  Response is either @samp{HELLO<br>
@var{ver} @var{agent} @var{repopath}}, or @samp{ERROR @var{msg}}.<br>
<br>
@item IMPORT @var{module}<br>
A query for an import (including for a module implementation unit).<br>
The response is @samp{OK @var{cmipath}} to indicate a CMI file.  If<br>
the request is not fulfilable, the response is @samp{ERROR<br>
[@var{msg}]}.  Usually an error response will cause compilation to<br>
terminate.<br>
<br>
@item INCLUDE @var{header}<br>
A @code{#include} directive for @var{header} is about to be processed.<br>
The response informs the compiler how to treat the inclusion.  A<br>
response of @samp{TEXT} causes textual inclusion.  A response of<br>
@samp{IMPORT} causes importation as a header unit and a subsequent<br>
@samp{IMPORT} query will then be forthcoming.<br>
<br>
@end table<br>
<br>
It is recommended that any unrecognized command causes an @samp{ERROR}<br>
response with a suitable message.<br>
<br>
Requests and responses may be batched.  If a request line begins with<br>
a @samp{+} character, before waiting for a response another request<br>
should be made.  That too may begin with @samp{+}.  The final request<br>
of the batch should begin with @samp{-}, and may be empty.  Similarly<br>
responses may be batched, both in response to a set of batched<br>
requests.  Each non-ultimate line of a batched response begins with a<br>
@samp{+}.  The final line should begin with @samp{-}, and may<br>
otherwise be empty.  Responses to a batched request are in request<br>
order.  Servers should not commence responses until all requests of a<br>
batch have been received.  There may be a fixed-capacity pipe between<br>
client and server, and sending responses before the client has started<br>
reading could result in deadlock.<br>
<br>
The following metavariables were used:<br>
<br>
@table @gcctabopt<br>
<br>
@item @var{cmipath}<br>
Pathname of a CMI file.<br>
<br>
@item @var{from}<br>
The source path of the file containing the import or include.<br>
<br>
@item @var{module}<br>
A module name.  Header unit names are absolute pathnames, or<br>
pathnames prefixed with @samp{./}.  Header units are resolved using<br>
the include path.<br>
<br>
@item @var{msg}<br>
A human readable message.  This may contain whitespace.<br>
<br>
@item @var{ident}<br>
An identity provided when invoking the compiler.  This may be helpful<br>
to distinguish different connections to a common server.<br>
<br>
@item @var{ver}<br>
A numeric version number, currently 0.<br>
<br>
@end table<br>
<br>
A project-specific mapper is expected to be provided by the build<br>
system that invokes the compiler.  It is not expected that a<br>
general-purpose server is provided for all compilations.  As such, the<br>
server will know the build configuration, the compiler it invoked, and<br>
the environment (such as working directory) in which that is<br>
operating.  As it may parallelize builds, several compilations may<br>
connect to the same socket.<br>
<br>
When delivering paths to the compiler, paths relative to the a<br>
repository-root directory should be used.  This server informs the<br>
compiler of this root in the initial handshake, using a path relative<br>
to the compiler's working directory, or an absolute one.  Compilers<br>
may embed the path of a direct import CMI file into an output CMI.<br>
This path will be relative to the repository.  Such a path reduces the<br>
server traffic, but requires the build system to recreate the same<br>
directory structure within the repository across a parellelized build<br>
system.<br>
<br>
The default mapper generates CMI files in a @samp{gcm.cache}<br>
directory.  CMI files have a @samp{.gcm} suffix.  The module unit name<br>
is used directly to provide the basename.  Header units construct a<br>
relative path using the underlying header file name.  If the path is<br>
already relative, a @samp{!} directory is prepended.  Internal<br>
@samp{..} components are translated to @samp{!!}.  No attempt is made<br>
to canonicalize these filenames beyond that done by the preprocessor's<br>
include search algorithm, as in general it is ambiguous when symbolic<br>
links are present.<br>
<br>
The mapper protocol was published as ``A Module Mapper''<br>
@uref{http//wg21.link/p1184}.  It is intended that build systems will<br>
provide their own mappers.<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>