<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <meta name="title" content="Generalized Module (Dependency?) Mapper"/>

  <title>Generalized Module (Dependency?) Mapper</title>

  <style type="text/css">
html
{
  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
  font-weight: normal;
  font-size: 18px;
  line-height: 1.4em;
  letter-spacing: 0.01em;

  color: #292929;
}

body {margin: 0;} /* There is non-0 default margin for body. */

/* See notes on what's going on here. */
body {min-width: 17em;}
@media only screen and (min-width: 360px)
{
  body {min-width: 19em;}
}

/*
 * Header (optional).
 */

#header-bar
{
  width: 100%;

  background: rgba(0, 0, 0, 0.04);
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);

  padding: .4em 0 .42em 0;
  margin: 0 0 1.4em 0;
}

#header
{
  /* Same as in #content. */
  max-width: 41em;
  margin: 0 auto 0 auto;
  padding: 0 .4em 0 .4em;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;

  width: 100%;
  display: table;
  border: none;
  border-collapse: collapse;
}

#header-logo, #header-menu
{
  display: table-cell;
  border: none;
  padding: 0;
  vertical-align: middle;
}

#header-logo {text-align: left;}
#header-menu {text-align: right;}

/* These overlap with #header's margin because of border collapsing. */
#header-logo {padding-left: .4em;}
#header-menu {padding-right: .4em;}

#header-logo a
{
  color: #000;
  text-decoration: none;
  outline: none;
}
#header-logo a:visited {color: #000;}
#header-logo a:hover, #header-logo a:active {color: #000;}

#header-menu a
{
  font-size: 0.889em;
  line-height: 1.4em;
  text-align: right;
  margin-left: 1.2em;
  white-space: nowrap;
  letter-spacing: 0;
}

#header-menu a
{
  color: #000;
  outline: none;
}
#header-menu a:visited {color: #000;}
#header-menu a:hover, #header-menu a:active
{
  color: #3870c0;
  text-decoration: none;
}

/* Flexbox-based improvements though the above works reasonably well. */
#header-menu-body
{
  width: 100%;

  display: -webkit-inline-flex;
  display: inline-flex;

  -webkit-flex-flow: row wrap;
  flex-flow: row wrap;

  -webkit-justify-content: flex-end;
  justify-content: flex-end;
}

/* Whether we want it (and at which point) depends on the size of the menu. */
/*
@media only screen and (max-width: 567px)
{
  #header-menu-body
  {
    -webkit-flex-direction: column;
    flex-direction: column;
  }
}
*/

/*
 * Content.
 */

#content
{
  max-width: 41em;
  margin: 0 auto 0 auto;
  padding: 0 .4em 0 .4em; /* Space between text and browser frame. */

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

/*
 * Footer (optional).
 */

#footer
{
  color: #767676;
  font-size: 0.7223em;
  line-height: 1.3em;
  margin: 2.2em 0 1em 0;
  text-align: center;
}

#footer a
{
  color: #767676;
  text-decoration: underline;
}
#footer a:visited {color: #767676;}
#footer a:hover, #footer a:active {color: #3870c0;}

/* Screen size indicator in the footer. The before/after content is in case
   we don't have any content in the footer. Margin is to actually see the
   border separate from the browser frame. */

/*
#footer:before {content: "\A0";}
#footer:after {content: "\A0";}

#footer
{
  border-left: 1px solid;
  border-right: 1px solid;
  margin-left: 1px;
  margin-right: 1px;
}

@media only screen and (max-width: 359px)
{
  #footer {border-color: red;}
}

@media only screen and (min-width: 360px) and (max-width: 567px)
{
  #footer {border-color: orange;}
}

@media only screen and (min-width: 568px) and (max-width: 1023px)
{
  #footer {border-color: blue;}
}

@media only screen and (min-width: 1024px)
{
  #footer {border-color: green;}
}
*/

/*
 * Common elements.
 */

p, li, dd {text-align: justify;}
.code {text-align: left;} /* Manually aligned. */
pre {text-align: left;}   /* If it is inside li/dd. */

/* Notes. */

.note
{
  color: #606060;
}

div.note
{
  margin: 2em 0 2em 0; /* The same top/bottom margings as pre box. */

  padding-left: 0.5em;
  border: 0.25em;
  border-left-style: solid;
  border-color: #808080;

  page-break-inside: avoid;
}

div.note :first-child {margin-top:    0;}
div.note :last-child  {margin-bottom: 0;}

span.note::before {content: "[Note: "}
span.note::after  {content: "]"}

/* Links. */
a
{
  color: #3870c0;
  /*color: #4078c0;*/
  text-decoration: none;
}

a:hover, a:active
{
/*color: #006fbf;*/
/*color: #0087e7;*/
  text-decoration: underline;
}

a:visited
{
/*color: #003388;*/
  color: #00409c;
}

/* Standard paragraph. */

p, pre {margin: 1em 0 1em 0;}

/* Standard lists. */
ul, ol, dl {margin: 1em 0 1em 0;}
ul li, ol li {margin: 0 0 .4em 0;}
ul li {list-style-type: circle;}
dl dt {margin: 0 0 0 0;}
dl dd {margin: 0 0 .6em 1.8em;}

code, pre
{
  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 0.92em;
  letter-spacing: 0;
}

pre {white-space: pre-wrap;}
@media only screen and (max-width: 567px)
{
  pre {word-break: break-all;}
}

/* Use page rather than system font settings. */
input
{
  font-family: inherit;
  font-weight: inherit;
  font-size:   inherit;
  line-height: inherit;
}

/* Note: see also p-code-box.css. */

pre
{
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 0.2em;
  padding: .8em .4em .8em .4em;
  margin: 2em -.4em 2em -.4em; /* Use margins of #content. */
}

/* Note: see also p-code-box.css if changing anything here. */

code
{
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 0.2em;
  padding: .2em .32em .18em .32em;
}

/* This is the pre-like paragraph produced by CLI for code-only fragments. */

/* Note: see also pre-box.css. */

.code
{
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 0.2em;
  padding: .8em .4em .8em .4em;
  margin: 2em -.4em 2em -.4em; /* Use margins of #content. */
}

/* Undo code-box.css inside .code. */
.code code
{
  background-color: transparent;
  border-radius: 0;
  padding: 0;
}


/* Bases:
 *
 * common.css
 * pre-box.css
 * code-box.css
 *
 */

#content
{
  max-width: 43.6em;
  padding-left: 3em; /* Reserve for headings. */
}

h1
{
  font-weight: normal;
  font-size: 2em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -1.4em;
}

h1.preface
{
  margin-left: -.56em;
}

h2
{
  font-weight: normal;
  font-size: 1.556em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -.8em;
}

h3
{
  font-weight: normal;
  font-size: 1.3em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -.2em;
}

/* Title page */

#titlepage {
  margin: 0 0 4em 0;
  border-bottom: 1px solid black;
}

#titlepage .title {
  font-weight: normal;
  font-size: 2.333em;
  line-height: 1.4em;
  letter-spacing: 0;
  text-align: center;
  margin: 2em 0 2em 0;
}

#titlepage p {
  font-size: 0.889em;
  line-height: 1.4em;
  margin: 2em 0 .6em 0;
}

table.toc
{
  border-style      : none;
  border-collapse   : separate;
  border-spacing    : 0;

  margin            : 0.2em 0 0.2em 0;
  padding           : 0 0 0 0;
}

table.toc tr
{
  padding           : 0 0 0 0;
  margin            : 0 0 0 0;
}

table.toc * td, table.toc * th {
  border-style      : none;
  margin            : 0 0 0 0;
  vertical-align    : top;
}

table.toc * th
{
  font-weight       : normal;
  padding           : 0 0.8em 0 0;
  text-align        : left;
  white-space       : nowrap;
}

table.toc * table.toc th
{
  padding-left      : 1em;
}

table.toc * td
{
  padding           : 0 0 0 0;
  text-align        : left;
}

table.toc * td.preface
{
  padding-left      : 1.35em;
}


#titlepage .title
{
  font-size: 2em;
}

/*
 * Property list table.
 */
.proplist
{
  width: calc(100%); /* Fill the page. */

  table-layout: fixed;

  border: none;
  border-spacing: 0 0;
}

.proplist th, .proplist td {padding: .1em 0 .1em 0;}

.proplist th
{
  font-weight: normal;
  text-align: left;

  width: 7em;
}
.proplist th:after {content: ":";}

/*
 * Before/after table.
 */
.proplist
{
  width: calc(100%); /* Fill the page. */

  table-layout: fixed;

  border: none;
  border-spacing: 0 0;
}

.proplist th, .proplist td {padding: .1em 0 .1em 0;}

/*
 * Before/after table.
 */
.ba
{
  width: calc(100%); /* Fill the page. */
  table-layout: fixed;

  border: none;
  border-spacing: 0 0;

  margin: 2em 0 2em 0;
}

.ba th, .ba td {padding: 0;}

.ba th
{
  text-align: left;
  border-bottom: 1px solid #666666;
}

.ba td pre {margin: .5em 0 .5em 0;}

.ba .b {width: 50%; padding-right: 1em;}
.ba .a {width: 50%; padding-left:  1em;}
  </style>

</head>
<body>
<div id="content">

  <div id="titlepage">
    <div class="title">Generalized Module (Dependency?) Mapper</div>

    <table class="proplist">
      <tbody>
	<tr><th>Document</th><td><a href="https://wg21.link/P1842R0">P1842R0</a></td></tr>
	<tr><th>Audience</th><td>SG15</td></tr>
	<tr><th>Authors</th><td>Boris Kolpackov (Code Synthesis / build2)</td></tr>
	<tr><th>Reply-To</th><td>boris@codesynthesis.com</td></tr>
	<tr><th>Date</th><td>2019-08-04</td></tr>
      </tbody>
    </table>
  </div>
  <h1 id="abstract">Abstract</h1>

  <p><i>This paper suggests generalizing the module mapper protocol described
  in <a href="https://wg21.link/p1184">P1184</a> to also handle headers as
  well as potential future translation unit dependencies such as
  <code>std::embed</code> (<a
  href="https://wg21.link/p1040">P1040</a>).</i></p>

  <h1 id="toc">Contents</h1>

  <table class="toc">
    <tr><th>1</th><td><a href="#background">Background</a></td></tr>
    <tr><th>2</th><td><a href="#comm">Communication</a></td></tr>
    <tr><th>3</th><td><a href="#proto">Protocol</a>
      <table class="toc">
        <tr><th>3.1</th><td><a href="#proto-dynamic">Dynamic Mapper</a>
          <table class="toc">
            <tr><th>3.1.1</th><td><a
href="#proto-dynamic-import"><code>IMPORT</code></a></td></tr>
            <tr><th>3.1.2</th><td><a
href="#proto-dynamic-include"><code>INCLUDE</code></a></td></tr>
          </table>
        </td></tr>
        <tr><th>3.2</th><td><a href="#proto-static">Static
Mapper</a></td></tr>
      </table>
    </td></tr>
    <tr><th>4</th><td><a href="#qna">Questions and Answers</a>
      <table class="toc">
        <tr><th>4.1</th><td><a href="#qna-impl">Is there implementation
experience?</a></td></tr>
        <tr><th>4.2</th><td><a href="#qna-usage">Is there usage
experience?</a></td></tr>
      </table>
    </td></tr>
    <tr><th>5</th><td><a href="#ack">Acknowledgments</a></td></tr>
  </table>

  <h1 id="background">1 Background</h1>

  <p>Because header units affects the preprocessor, they introduce a
  significant complication to the dependency graph discovery (refer to <a
  href="https://wg21.link/p1184">P1184</a> for details). A dynamic module
  mapper is currently the only approach that we know of that allows dealing
  with this complication in the general case (that is, without relying on a
  pre-compilation step or manual dependency specification) and without
  requiring an additional mechanism in the compiler (such as the ability to
  preprocess with isolation textual headers in lieu of loading BMIs). As a
  result, in <code>build2</code>, we have decided to use the module mapper
  approach to handle header units and include translation.</p>

  <p>Our initial attempt used GCC's module mapper to discover and handle
  header unit importation and the <code>-M</code> option family for header
  dependency discovery. However, it quickly became clear that there is a
  significant overlap between the two mechanisms. In fact, because of the
  include translation, the mapper gets notified about most headers reported by
  <code>-M</code>: the only exceptions are the predefined (forced) and command
  line (<code>-include</code>) headers.</p>

  <p>More importantly, the mapper approach seemed like a promising way to
  resolve many long-standing issues with handling auto-generated headers. To
  give some background, in the <code>-M</code> option family, auto-generated
  headers are normally handled using <code>-MG</code> which instructs the
  compiler to not fail on encountering non-existent headers. The build system
  then detects such headers in the <code>-M</code> output, generates them, and
  re-executes the compiler.</p>

  <p>However, this approach, besides being inefficient, also has many issues
  and corner cases (listed in the order of increased difficulty to deal
  with):</p>

  <ul>
  <li>Outdated header: The build system has to detect when an auto-generated
  header exists but is out of date, update it, and, again, re-execute the
  compiler.</li>

  <li>Wrong header: If the auto-generated header does not exist, the compiler
  may find and include an identically-named but unrelated header that is found
  in one of the further <code>-I</code> directories.</li>

  <li>Outdated/wrong header causes an error: Including an outdated or wrong
  header may trigger a fatal preprocessor error (e.g., via an
  <code>#error</code> directive) that would disappear if only the header could
  be regenerated.</li>
  </ul>

  <p>In contrast, the mapper approach would have the ability to sidestep all
  these issues because it would give the build system a chance to act
  <i>before</i> preprocessing a header.</p>

  <p>Finally, the mapper can also be easily extended to handle potential
  future dependencies of translation units, such as those in the
  <code>std::embed</code> proposal (<a
  href="https://wg21.link/p1040">P1040</a>).</p>

  <p>The following sections describe the generalized module mapper (now more
  accurately called <i>dependency mapper</i>) that we have <a
  href="#qna-impl">implemented in GCC</a> and then used in <code>build2</code>
  with good results.</p>

  <h1 id="comm">2 Communication</h1>

  <p>GCC currently supports several module mapper communication media:</p>

  <ol>
  <li>File.</li>

  <li>Pipe (including compiler's <code>stdin</code>/<code>stdout</code>).</li>

  <li>Program to spawn and then communicate via its
  <code>stdin</code>/<code>stdout</code>.</li>

  <li>Socket/port to connect to (UNIX, IP).</li>
  </ol>

  <p>The last two communication media may understandably raise security
  concerns. We, however, believe they can be omitted or made optional by an
  implementation if non-intrusive support for legacy build systems is not a
  priority.</p>

  <p>To elaborate, in our experience, the most natural way to integrate the
  module mapper functionality into a build system is using the first two media
  (file and/or pipe). The build system spawns the compiler process and using a
  pipe is the most straightforward and efficient way of establishing
  bi-directional communication. Only when the build system cannot be easily
  modified, might other communication media be necessary.</p>

  <h1 id="proto">3 Protocol</h1>

  <p>For the remainder of the paper we refer to the file-based mapper as
  <i>static</i> and the rest &#8211; as <i>dynamic</i>. The dynamic mapper
  uses the line-based request-response protocol. The static mapper, due to its
  nature, has a separate, more limited protocol. Refer to <a
  href="https://wg21.link/p1184">P1184</a> for the protocol basics and to the
  following sections for the generalizations.</p>

  <div class="note">
  <p>Theoretically, a static mapper can be implemented via something other
  than a file. For example, the compiler may read the static mapping from its
  <code>stdin</code>.</p>
  </div>

  <p>An implementation can reasonably be expected to support multiple static
  mappers and a single dynamic mapper for the same compilation.</p>

  <p>One notable protocol feature described in <a
  href="https://wg21.link/p1184">P1184</a> is request batching in the dynamic.
  However, with the relaxation of the preamble rules around macro importation,
  the compiler's ability to request multiple mappings in parallel is now
  limited to contiguous non-header unit imports. It is therefore unclear
  whether the extra complexity (both in the compiler and in the build system)
  justifies the now limited benefit. As a result, we propose that if
  implemented, this feature be made optional and its use negotiated via the
  <i>impl-extra</i> field in the <code>HELLO</code> request/response (see
  below).</p>

  <h2 id="proto-dynamic">3.1 Dynamic Mapper</h2>

  <p>The generalized protocol uses quoting to distinguish between modules and
  headers. The <code><b>""</b></code> and <code><b>&lt;></b></code> quoting
  are used for the corresponding styles of <code>include</code> and
  <code>import</code> directives while <code><b>''</b></code> is used for the
  predefined (forced) and command line inclusion as well as in the contexts
  where translation or re-search is not allowed (in other words,
  <code><b>''</b></code> implies final/immutable inclusion/importation).</p>

  <p>Protocol synopsis (leading <code><b>></b></code> marks a request from the
  compiler to the mapper and <code><b>&lt;</b></code> &#8211; a response).</p>

  <p class="code"><code>> <b>HELLO</b> <i>ver</i> <i>kind</i> <i>ident</i>
  [<i>impl-extra</i>...]
  <br/>
  <br/>
  &#160;&#160;&#160;&lt; <b>HELLO</b> <i>ver</i> <i>kind</i> <i>ident</i>
  [<i>impl-extra</i>...]
  <br/>
  &#160;&#160;&#160;&lt; <b>ERROR</b> <i>msg</i>
  <br/>
  <br/>
  > <b>EXPORT</b> <i>mod-name</i>
  <br/>
  > <b>EXPORT</b> <b>'</b><i>hdr-name</i><b>'</b>
  <br/>
  <br/>
  &#160;&#160;&#160;&lt; <b>EXPORT</b> <i>bmi</i>
  <br/>
  &#160;&#160;&#160;&lt; <b>ERROR</b> <i>msg</i>
  <br/>
  <br/>
  > <b>DONE</b> <i>mod-name</i>
  <br/>
  > <b>DONE</b> <b>'</b><i>hdr-name</i><b>'</b>
  <br/>
  <br/>
  > <b>IMPORT</b> <i>mod-name</i>
  <br/>
  > <b>IMPORT</b> <b>&lt;</b><i>hdr-name</i><b>></b> [<i>hdr-path</i>]
  <br/>
  > <b>IMPORT</b> <b>"</b>hdr-name<b>"</b> [<i>hdr-path</i>]
  <br/>
  > <b>IMPORT</b> <b>'</b><i>hdr-name</i><b>'</b> <i>hdr-path</i>
  <br/>
  <br/>
  &#160;&#160;&#160;&lt; <b>SEARCH</b>
  <br/>
  &#160;&#160;&#160;&lt; <b>IMPORT</b> [<i>bmi</i>]
  <br/>
  &#160;&#160;&#160;&lt; <b>ERROR</b> <i>msg</i>
  <br/>
  <br/>
  > <b>INCLUDE</b> <b>&lt;</b><i>hdr-name</i><b>></b> [<i>hdr-path</i>]
  <br/>
  > <b>INCLUDE</b> <b>"</b>hdr-name<b>"</b> [<i>hdr-path</i>]
  <br/>
  > <b>INCLUDE</b> <b>'</b><i>hdr-name</i><b>'</b> <i>hdr-path</i>
  <br/>
  <br/>
  &#160;&#160;&#160;&lt; <b>SEARCH</b>
  <br/>
  &#160;&#160;&#160;&lt; <b>INCLUDE</b>
  <br/>
  &#160;&#160;&#160;&lt; <b>IMPORT</b> [<i>bmi</i>]
  <br/>
  &#160;&#160;&#160;&lt; <b>ERROR</b> <i>msg</i></code></p>

  <p>Example exchange translating <code>&lt;stdio.h></code> inclusion to an
  import :</p>

  <pre>> HELLO 0 GCC main.cxx
&lt; HELLO 0 build2 .
> INCLUDE 'stdc-predef.h' /usr/include/stdc-predef.h
&lt; INCLUDE
> INCLUDE &lt;stdio.h> /usr/include/stdio.h
&lt; IMPORT
> IMPORT '/usr/include/stdio.h'
&lt; IMPORT stdio.gcm</pre>

  <p>Example exchange importing an auto-generated header:</p>

  <pre>> HELLO 0 GCC main.cxx
&lt; HELLO 0 build2 .
> INCLUDE 'stdc-predef.h' /usr/include/stdc-predef.h
&lt; INCLUDE
> IMPORT &lt;foo/data.h>
&lt; SEARCH
&lt; IMPORT &lt;foo/data.h> libfoo/foo/data.h
&lt; IMPORT libfoo/foo/data.gcm</pre>

  <h3 id="proto-dynamic-import">3.1.1 <code>IMPORT</code></h3>

  <p class="code"><code> > <b>IMPORT</b> <i>mod-name</i>
  <br/>
  > <b>IMPORT</b> <b>&lt;</b><i>hdr-name</i><b>></b> [<i>hdr-path</i>]
  <br/>
  > <b>IMPORT</b> <b>"</b>hdr-name<b>"</b> [<i>hdr-path</i>]
  <br/>
  > <b>IMPORT</b> <b>'</b><i>hdr-name</i><b>'</b> <i>hdr-path</i>
  <br/>
  <br/>
  &#160;&#160;&#160;&lt; <b>SEARCH</b>
  <br/>
  &#160;&#160;&#160;&lt; <b>IMPORT</b> [<i>bmi</i>]
  <br/>
  &#160;&#160;&#160;&lt; <b>ERROR</b> <i>msg</i></code></p>

  <p>The first form of the <code>IMPORT</code> request is made when importing
  a module or a module partition. Valid responses are <code>IMPORT</code> and
  <code>ERROR</code>.</p>

  <p>The next two forms are used for importing header units that were imported
  using <code><b>&lt;></b></code> and <code><b>""</b></code> importation
  styles, respectively. If the compiler was able to resolve this header name
  to the header path, then this path is included into the request as
  <i>hdr-path</i>. Otherwise, <i>hdr-path</i> is absent. Valid responses for
  these two forms are <code>SEARCH</code>, <code>IMPORT</code>, and
  <code>ERROR</code>. The <code>SEARCH</code> response causes the compiler to
  re-search the header name and re-issue the <code>IMPORT</code> request with
  the (presumably) new header path.</p>

  <div class="note">
  <p>Instead of requesting the compiler to re-search the header, the response
  could have included the desired header path directly. The difficult part
  about supporting something like this would be the need to reverse-map the
  returned path to an include directory so that mechanisms such as
  <code>include_next</code>, system header status, etc., all work correctly.
  And it seems the only way to do this reliably would be to search for files
  in the include directories and see if one of them matches the returned path
  in the same heavy-handed way as <code>#pragma&#160;once</code> (comparing
  file contents, etc).</p>
  </div>

  <p>If the header is not found (<i>hdr-path</i> is absent), then the
  <code>IMPORT</code> response should cause the compiler to issue the usual
  "header not found" diagnostics. In this case the <i>bmi</i> field is ignored
  and can be omitted.</p>

  <p>The last form is used to import header units that cannot be re-searched.
  For example, this form of the <code>IMPORT</code> request is issued for
  include directives that have been translated to import (see below).</p>

  <h3 id="proto-dynamic-include">3.1.2 <code>INCLUDE</code></h3>

  <p class="code"><code>> <b>INCLUDE</b> <b>&lt;</b><i>hdr-name</i><b>></b>
  [<i>hdr-path</i>]
  <br/>
  > <b>INCLUDE</b> <b>"</b>hdr-name<b>"</b> [<i>hdr-path</i>]
  <br/>
  > <b>INCLUDE</b> <b>'</b><i>hdr-name</i><b>'</b> <i>hdr-path</i>
  <br/>
  <br/>
  &#160;&#160;&#160;&lt; <b>SEARCH</b>
  <br/>
  &#160;&#160;&#160;&lt; <b>INCLUDE</b>
  <br/>
  &#160;&#160;&#160;&lt; <b>IMPORT</b> [<i>bmi</i>]
  <br/>
  &#160;&#160;&#160;&lt; <b>ERROR</b> <i>msg</i></code></p>

  <p>The first two forms of the <code>INCLUDE</code> request are analogous to
  the corresponding <code>IMPORT</code> forms. The <code>INCLUDE</code>
  response signals that the header should be textually included while the
  <code>IMPORT</code> response signals that it should be translated to an
  import. The <code>IMPORT</code> response may optionally specify the BMI. If
  the BMI is omitted then the compiler should issue a separate
  <code>IMPORT</code> request.</p>

  <div class="note">
  <p>Replying with just <code>IMPORT</code> could be useful if, for example,
  the mapping is split between dynamic and static mappers.</p>
  </div>

  <p>Similar to <code>IMPORT</code>, if the header is not found
  (<i>hdr-path</i> is absent), then the <code>INCLUDE</code> or
  <code>IMPORT</code> response should cause the compiler to issue the usual
  "header not found" diagnostics. In this case the <i>bmi</i> field in the
  <code>IMPORT</code> response is ignored and can be omitted.</p>

  <p>The last form is used to include headers that can neither be re-searched
  nor translated.</p>

  <h2 id="proto-static">3.2 Static Mapper</h2>

  <p>The static mapper specifies one module or header to BMI mapping per line
  in the following form:</p>

  <p class="code"><code>[<i>prefix</i>] <i>mod-name</i> <i>bmi</i>
  <br/>
  [<i>prefix</i>] <b>'</b><i>hdr-path</i><b>'</b> <i>bmi</i>
  <br/>
  [<i>prefix</i>] <b>!'</b><i>hdr-path</i><b>'</b> [<i>bmi</i>]</code></p>

  <p>Note that the same format is used both to provide the input mapping for
  imported modules/headers as well as the output mapping for writing a
  module/header BMI.</p>

  <p>A line prefix may be specified in an implementation-defined manner (for
  example, as part of the command line option that specifies the mapper file).
  If specified, then only lines that begin with such a prefix are considered
  (the prefix itself is ignored). Leading (after the line prefix, if any) and
  trailing whitespaces as well as blank lines are ignored.</p>

  <div class="note">
  <p>Specifying the line prefix is supported by GCC but this functionality is
  not described in <a href="https://wg21.link/p1184">P1184</a>.</p>
  </div>

  <div class="note">
  <p>The line prefix allows reusing existing files, such as the venerable
  <code>.d</code> file, for storing the module mapping information.</p>
  </div>

  <p>The last form (with the leading <code><b>!</b></code>) is used to signal
  that including this header should be translated to an import. In this form
  specifying the BMI is optional.</p>

  <div class="note">
  <p>It may be desirable to allow separating the specification of header to
  BMI mapping and include translation, for example, in different mapper files.
  At the same time we expect it to be common for these specifications to be
  combined.</p>
  </div>

  <h1 id="qna">4 Questions and Answers</h1>

  <h2 id="qna-impl">4.1 Is there implementation experience?</h2>

  <p>Yes, an implementation is available in the <a
  href="https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/boris/c%2B%2B-modules-ex"><code>boris/c++-modules-ex</code></a>
  GCC branch.</p>

  <h2 id="qna-usage">4.2 Is there usage experience?</h2>

  <p>Yes, the <a href="https://build2.org"><code>build2</code> build
  system</a> implements support for modules and header units (including
  include translation) in GCC using this generalized mapper.</p>

  <h1 id="ack">5 Acknowledgments</h1>

  <p>This work is based on Nathan Sidwell's <a
  href="https://wg21.link/p1184">P1184</a> and module mapper implementation in
  GCC. The module mapper idea was originally conceived (according to <a
  href="https://wg21.link/p1184">P1184</a>) in a discussion between Nathan
  Sidwell, Richard Smith, and David Blaikie.</p>

</div>

</body>
</html>
