<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 9.1.0">
<title>Format for describing dependencies of source files</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */

/* Default font. */
body {
  font-family: Georgia,serif;
}

/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
  font-family: Arial,Helvetica,sans-serif;
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}
h5 {
  font-size: 1.0em;
}

div.sectionbody {
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}
ul > li     { color: #aaa; }
ul > li > * { color: black; }

.monospaced, code, pre {
  font-family: "Courier New", Courier, monospace;
  font-size: inherit;
  color: navy;
  padding: 0;
  margin: 0;
}
pre {
  white-space: pre-wrap;
}

#author {
  color: #527bbd;
  font-weight: bold;
  font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}

#footer {
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid #dddddd;
  border-left: 4px solid #f0f0f0;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid #dddddd;
  border-left: 5px solid #f0f0f0;
  background: #f8f8f8;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #f0f0f0;
  color: #888;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > pre.content {
  font-family: inherit;
  font-size: inherit;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}

div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}

div.colist td {
  padding-right: 0.5em;
  padding-bottom: 0.3em;
  vertical-align: top;
}
div.colist td img {
  margin-top: 0.3em;
}

@media print {
  #footer-badges { display: none; }
}

#toc {
  margin-bottom: 2.5em;
}

#toctitle {
  color: #527bbd;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}

span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }

span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }

span.big { font-size: 2em; }
span.small { font-size: 0.6em; }

span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }

div.unbreakable { page-break-inside: avoid; }


/*
 * xhtml11 specific
 *
 * */

div.tableblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-weight: bold;
  color: #527bbd;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overridden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


/*
 * html5 specific
 *
 * */

table.tableblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
thead, p.tableblock.header {
  font-weight: bold;
  color: #527bbd;
}
p.tableblock {
  margin-top: 0;
}
table.tableblock {
  border-width: 3px;
  border-spacing: 0px;
  border-style: solid;
  border-color: #527bbd;
  border-collapse: collapse;
}
th.tableblock, td.tableblock {
  border-width: 1px;
  padding: 4px;
  border-style: solid;
  border-color: #527bbd;
}

table.tableblock.frame-topbot {
  border-left-style: hidden;
  border-right-style: hidden;
}
table.tableblock.frame-sides {
  border-top-style: hidden;
  border-bottom-style: hidden;
}
table.tableblock.frame-none {
  border-style: hidden;
}

th.tableblock.halign-left, td.tableblock.halign-left {
  text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
  text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
  text-align: right;
}

th.tableblock.valign-top, td.tableblock.valign-top {
  vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
  vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
  vertical-align: bottom;
}


/*
 * manpage specific
 *
 * */

body.manpage h1 {
  padding-top: 0.5em;
  padding-bottom: 0.5em;
  border-top: 2px solid silver;
  border-bottom: 2px solid silver;
}
body.manpage h2 {
  border-style: none;
}
body.manpage div.sectionbody {
  margin-left: 3em;
}

@media print {
  body.manpage div#toc { display: none; }
}


</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  if (!toc) {
    return;
  }

  // Delete existing TOC entries in case we're reloading the TOC.
  var tocEntriesToRemove = [];
  var i;
  for (i = 0; i < toc.childNodes.length; i++) {
    var entry = toc.childNodes[i];
    if (entry.nodeName.toLowerCase() == 'div'
     && entry.getAttribute("class")
     && entry.getAttribute("class").match(/^toclevel/))
      tocEntriesToRemove.push(entry);
  }
  for (i = 0; i < tocEntriesToRemove.length; i++) {
    toc.removeChild(tocEntriesToRemove[i]);
  }

  // Rebuild TOC entries.
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  // Delete existing footnote entries in case we're reloading the footnodes.
  var i;
  var noteholder = document.getElementById("footnotes");
  if (!noteholder) {
    return;
  }
  var entriesToRemove = [];
  for (i = 0; i < noteholder.childNodes.length; i++) {
    var entry = noteholder.childNodes[i];
    if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
      entriesToRemove.push(entry);
  }
  for (i = 0; i < entriesToRemove.length; i++) {
    noteholder.removeChild(entriesToRemove[i]);
  }

  // Rebuild footnote entries.
  var cont = document.getElementById("content");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      var note = spans[i].getAttribute("data-note");
      if (!note) {
        // Use [\s\S] in place of . so multi-line matches work.
        // Because JavaScript has no s (dotall) regex flag.
        note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
        spans[i].innerHTML =
          "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
        spans[i].setAttribute("data-note", note);
      }
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
},

install: function(toclevels) {
  var timerId;

  function reinstall() {
    asciidoc.footnotes();
    if (toclevels) {
      asciidoc.toc(toclevels);
    }
  }

  function reinstallAndRemoveTimer() {
    clearInterval(timerId);
    reinstall();
  }

  timerId = setInterval(reinstall, 500);
  if (document.addEventListener)
    document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
  else
    window.onload = reinstallAndRemoveTimer;
}

}
asciidoc.install(5);
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>Format for describing dependencies of source files</h1>
<span id="author">Ben Boeckel, Brad King</span><br>
<span id="email" class="monospaced">&lt;<a href="mailto:ben.boeckel@kitware.com, brad.king@kitware.com">ben.boeckel@kitware.com, brad.king@kitware.com</a>&gt;</span><br>
<span id="revnumber">version P1689R4,</span>
<span id="revdate">2021-06-14</span>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="hdlist"><table>
<tr>
<td class="hdlist1">
Document number
<br>
</td>
<td class="hdlist2">
<p style="margin-top: 0;">
ISO/IEC/JTC1/SC22/WG21/P1689R4
</p>
</td>
</tr>
<tr>
<td class="hdlist1">
Date
<br>
</td>
<td class="hdlist2">
<p style="margin-top: 0;">
2021-06-14
</p>
</td>
</tr>
<tr>
<td class="hdlist1">
Reply-to
<br>
</td>
<td class="hdlist2">
<p style="margin-top: 0;">
Ben Boeckel, Brad King, <a href="mailto:ben.boeckel@kitware.com">ben.boeckel@kitware.com</a>, <a href="mailto:brad.king@kitware.com">brad.king@kitware.com</a>
</p>
</td>
</tr>
<tr>
<td class="hdlist1">
Audience
<br>
</td>
<td class="hdlist2">
<p style="margin-top: 0;">
EWG (Evolution), SG15 (Tooling)
</p>
</td>
</tr>
</table></div>
</div>
</div>
<div class="sect1">
<h2 id="_abstract">1. Abstract</h2>
<div class="sectionbody">
<div class="paragraph"><p>When building C++ source code, build tools need to discover dependencies of
source files based on their contents. This occurs during the build so that file
contents can change without build tools having to reinitialize and so the
dependencies of source file generated during the build are correct. With the
advent of modules in <a href="#P1103R3">[P1103R3]</a>, there are now ordering requirements among
compilation rules. These also need to be discovered during the build. This
paper specifies a format for communicating this information to build tools.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_changes">2. Changes</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_r4_june_2021_mailing">2.1. R4 (June 2021 mailing)</h3>
<div class="paragraph"><p>Changed:</p></div>
<div class="ulist"><ul>
<li>
<p>
Removed <span class="monospaced">work-directory</span> from the list of required keys. It is not strictly
    necessary because the build system should be controlling working
    directories in a way it understands anyways.
</p>
</li>
<li>
<p>
Removed <span class="monospaced">inputs</span>, <span class="monospaced">outputs</span>, <span class="monospaced">depends</span> from rules. These were intended to
    replace depfiles (i.e., <span class="monospaced">-M</span> flags in <span class="monospaced">gcc</span>), but for module dependencies,
    implementation experience showed that parsing this information was
    extraneous work for tools that just needed the module dependency
    information. Future proposals can tackle this problem and, in order to keep
    the information outside of this file, may be referenced by a new key to be
    added in a future version (ideally in a backwards-compatible way).
</p>
</li>
<li>
<p>
<span class="monospaced">future-compile</span> is now folded into its parent object as it is the only one
    left.
</p>
</li>
<li>
<p>
The <span class="monospaced">primary-output</span> key is added to rules in order to know which rule it
    is associated with. Without it, there was an ambiguity of which <span class="monospaced">outputs</span>
    item was the primary output. This is analogous to the <span class="monospaced">-MT</span> flag in <span class="monospaced">gcc</span>
    to control the output name of the <span class="monospaced">make</span> snippet in the depfile.
</p>
</li>
<li>
<p>
Introduce <span class="monospaced">unique-on-source-path</span> in order to disambiguate header units for
    C++.
</p>
</li>
<li>
<p>
Required module descriptions now contain a <span class="monospaced">lookup-method</span> property which
    describes how the module was requested by the source. It defaults to
    <span class="monospaced">by-name</span>.
</p>
</li>
<li>
<p>
Specify defaults for <span class="monospaced">provides</span> and <span class="monospaced">requires</span> as empty arrays.
</p>
</li>
<li>
<p>
Improve examples.
</p>
</li>
</ul></div>
</div>
<div class="sect2">
<h3 id="_r3_dec_2020_mailing">2.2. R3 (Dec 2020 mailing)</h3>
<div class="paragraph"><p>Changed:</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">work-directory</span> is now represented per-rule rather than as a top-level
    entry.
</p>
</li>
<li>
<p>
arbitrary binary data format storage has been removed. This was deemed as
    too complicated for the benefits gained at this time. If experience shows
    that the generalizations are needed, the binary representation can be
    revisited in the future.
</p>
</li>
<li>
<p>
the example filenames are now consistent with each other.
</p>
</li>
</ul></div>
</div>
<div class="sect2">
<h3 id="_r2_pre_prague">2.3. R2 (pre-Prague)</h3>
<div class="paragraph"><p>Added:</p></div>
<div class="ulist"><ul>
<li>
<p>
more background information (motivation and assumptions)
</p>
</li>
<li>
<p>
validity of source entries depends on uniqueness in the outputs, not the
    inputs.
</p>
</li>
<li>
<p>
<span class="monospaced">input</span> is now an array, <span class="monospaced">inputs</span>. This is to support representation of
    unity builds where multiple input sources are compiled at once into a
    single set of outputs.
</p>
</li>
<li>
<p>
<span class="monospaced">sources</span> is renamed to <span class="monospaced">rules</span>. There is not necessarily a 1-to-1
    correlation with source files with compilation rules.
</p>
</li>
<li>
<p>
full example output for a C++ source
</p>
</li>
<li>
<p>
uniformly use "property" instead of "key" for JSON fields.
</p>
</li>
</ul></div>
</div>
<div class="sect2">
<h3 id="_r1_post_cologne">2.4. R1 (post-Cologne)</h3>
<div class="paragraph"><p>The following changes have been made in response to feedback in SG15:</p></div>
<div class="ulist"><ul>
<li>
<p>
rename keys to be more "noun-like" or for clarity including:
</p>
</li>
<li>
<p>
<span class="monospaced">readable</span> → <span class="monospaced">readable-name</span>
</p>
</li>
<li>
<p>
<span class="monospaced">logical</span> → <span class="monospaced">logical-name</span>
</p>
</li>
<li>
<p>
<span class="monospaced">filepath</span> → <span class="monospaced">compiled-module-path</span>
</p>
</li>
<li>
<p>
remove <span class="monospaced">future-link</span> (no known use case)
</p>
</li>
<li>
<p>
remove <span class="monospaced">%</span>-encoding for filepaths
</p>
</li>
<li>
<p>
remove top-level <span class="monospaced">extensions</span> key (still possible, just use <span class="monospaced">_</span> keys)
</p>
</li>
<li>
<p>
require vendor prefixes for extensions
</p>
</li>
<li>
<p>
add an optional <span class="monospaced">source-path</span> key to <span class="monospaced">depinfo</span> objects
</p>
</li>
</ul></div>
<div class="paragraph"><p>The following changes have been made in response to feedback in SG16:</p></div>
<div class="ulist"><ul>
<li>
<p>
change the name of the "data" key to "code-units"
</p>
</li>
<li>
<p>
mention normalization for JSON encoders and decoders
</p>
</li>
</ul></div>
</div>
<div class="sect2">
<h3 id="_r0_initial">2.5. R0 (Initial)</h3>
<div class="paragraph"><p>Description of the format and its semantics.</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_introduction">3. Introduction</h2>
<div class="sectionbody">
<div class="paragraph"><p>This paper describes a format designed primarily to communicate dependencies of
source files during the building of C++ source code. While other uses may
exist, the primary goal is correct compilation of C++ sources. The tool which
generates this format is referred to as a "dependency scanning tool" in this
paper.</p></div>
<div class="paragraph"><p>The contents of this format includes:</p></div>
<div class="ulist"><ul>
<li>
<p>
the resources that will be required to exist when the scanned translation
    unit is compiled; and
</p>
</li>
<li>
<p>
the resources that will be provided when the scanned translation unit is
    compiled.
</p>
</li>
</ul></div>
<div class="paragraph"><p>This information is sufficient to allow a build tool to order compilation rules
to get a valid build in the presence of C++ modules.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_motivation">4. Motivation</h2>
<div class="sectionbody">
<div class="paragraph"><p>Before C++ modules, the only kinds of dependencies on files that a build
system would care about could be determined during the execution of that rule.
This is because each compilation was independent of other compilation rules.
However, with modules, compilation rules can now depend on each other and they
must be executed in order. Build tools need to be able to extract this
information from source files before compiling them due to this new ordering
requirement.</p></div>
<div class="paragraph"><p>Incidentally, this is exactly analogous to the problem that Fortran build
systems has with Fortran modules. To that end, this format is explicitly not
specific to C++ and is intended for use within the Fortran ecosystem in the
future. Terminology specific to C++ is avoided in this format to avoid any
indications that it is C++-specific.</p></div>
<div class="sect2">
<h3 id="_why_makefile_snippets_don_8217_t_work">4.1. Why Makefile snippets don&#8217;t work</h3>
<div class="paragraph"><p>Historically, dependency information of a build rule has been handled by
Makefile snippets. An example of this is:</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #990000">output:</span> input_a input_b input_c</tt></pre></div></div>
<div class="paragraph"><p>This states that the artifact of the build rule is <span class="monospaced">output</span> and files
<span class="monospaced">input_a</span>, <span class="monospaced">input_b</span>, and <span class="monospaced">input_c</span> were read during its creation. This allows
the build system to know that if any of the listed <span class="monospaced">input_*</span> files changes, the
rule for <span class="monospaced">output</span> needs to be brought up-to-date as well.</p></div>
<div class="paragraph"><p>This works decently well for the kinds of dependencies that have occurred in C++
to date, namely header includes. This is because these dependencies can be
discovered while executing the rule associated with <span class="monospaced">output</span>.</p></div>
<div class="paragraph"><p>The issue that arises with the Makefile design is that modules are a new kind
of dependency that cannot be represented in declarative Makefile syntax. For
example, GCC outputs variable modifications (<span class="monospaced">CXX_MODULES+=…</span>) into these
snippets which is commonly not supported by the consuming tools. In addition,
because these dependencies must be discovered <strong>before</strong> the compilation rule is
executed, there would need to be one rule that writes dependency information
for another.</p></div>
<div class="paragraph"><p>As an example of the restrictions placed on these Makefile snippets, the
<span class="monospaced">ninja</span> <a href="#ninja">[ninja]</a> build tool requires that <span class="monospaced">output</span> be the same for the rule
which wrote out the dependency snippet and that no other outputs are mentioned.
No other Makefile syntax is supported (variables, adding rules, special
variables, macro expansions, etc.). This is because <span class="monospaced">ninja</span> is reading these
for just the dependency information.</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_assumptions">5. Assumptions</h2>
<div class="sectionbody">
<div class="paragraph"><p>This format assumes the following things about the environment in which it is
used: uniformity of the environment between creation and usage; only used
within one build of a project; it does not apply to different configurations of
a build (since dependencies may vary with the target platform or build settings
such as whether it is debug or not).</p></div>
<div class="paragraph"><p>It is generally assumed that the environment in which a file of this format is
created is the same as the environments in which it will be read and ultimately
used during the actual compilation. However, build systems may have different
strategies for executing rules and when this is the case, it is assumed that
the build system itself knows how to translate between the environments it sets
up for each rule. For example, a build system which distributes the builds
across multiple machines (whether over a network or using containerization)
should know how to translate between the environment set up for one execution
and another execution.</p></div>
<div class="paragraph"><p>Environments can have many knobs which change fundamental behaviors of the
system. A non-exhaustive list includes:</p></div>
<div class="ulist"><ul>
<li>
<p>
mount layout (particularly of the input and output absolute paths)
</p>
</li>
<li>
<p>
encoding (active code page, locale)
</p>
</li>
<li>
<p>
effective permissions (process user and group, security modules,
    anti-virus)
</p>
</li>
</ul></div>
<div class="paragraph"><p>The first two can be translated between different rules in a straightforward
way. For example, if one rule is executed in a <span class="monospaced">/chroot/exec1</span> prefix while
another is under <span class="monospaced">/chroot/exec2</span>, it is assumed that the build system
constructed those environments and knows that paths underneath those prefixes
should be rerooted for another execution rule to get its paths correct.
Encoding differences can be converted between using either system APIs or
libraries which handle encodings. If there are permission differences between
the scanner and the compiler, it is hard to imagine how a build tool would be
able to translate the file effectively.</p></div>
<div class="paragraph"><p>Given that there are various things that can interfere with interpretation of
the files, it is recommended that the producers will provide mechanisms to add
extra context in order for build systems to be able to link up various bits
together. For example, <span class="monospaced">work-directory</span> may be obtained via a call such
<span class="monospaced">getcwd()</span>, but if the build tool knows that is not going to be correct (e.g.,
due to chroot mechanisms), tools should provide ways of specifying what this
path is.</p></div>
<div class="paragraph"><p>Also note that, due to the way environments can be set up, it is assumed that
<span class="monospaced">..</span> is interpreted as the operating system does. Namely, symlinks may alter
behavior from what is expected based solely on the manipulation of the path as
a string.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_format">6. Format</h2>
<div class="sectionbody">
<div class="paragraph"><p>The format uses JSON <a href="#ECMA-404">[ECMA-404]</a> as a base for encoding its information. This
is suitable because it is structured (versus a plain-text format), parsers for
JSON are readily available (versus candidates with a custom structural format),
and the format is simple to implement (versus candidates such as YAML or TOML)
which will allow for easy adoption.</p></div>
<div class="paragraph"><p>JSON specifies that documents are Unicode.  However, due to the way filepaths
are represented in this format, it is further constrained to be a valid UTF-8
sequence.</p></div>
<div class="sect2">
<h3 id="_schema">6.1. Schema</h3>
<div class="paragraph"><p>For the information provided by the format, the following JSON Schema
<a href="#JSON-Schema">[JSON-Schema]</a> may be used.</p></div>
<div class="paragraph"><p> <details><summary> 
JSON Schema for the format
 </summary><div> </p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #990000">{</span>
  "$schema": ""<span style="color: #990000">,</span>
  "$id": "<span style="color: #FF0000">http://example.com/root.json</span>"<span style="color: #990000">,</span>
  "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
  "title": "<span style="color: #FF0000">SG15 TR depformat</span>"<span style="color: #990000">,</span>
  "definitions": <span style="color: #990000">{</span>
    "datablock": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#datablock</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">A filepath</span>"<span style="color: #990000">,</span>
      "minLength": <span style="color: #993399">1</span>
    <span style="color: #990000">},</span>
    "depinfo": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#depinfo</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">Dependency information for a compilation rule</span>"<span style="color: #990000">,</span>
      "properties": <span style="color: #990000">{</span>
        "work-directory": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">},</span>
        "primary-output": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#primary-output</span>"<span style="color: #990000">,</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
          "description": "<span style="color: #FF0000">The primary output for the compilation</span>"
        <span style="color: #990000">},</span>
        "outputs": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#outputs</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Other files output by a compiling this source using the same flags</span>"<span style="color: #990000">,</span>
          "uniqueItems": <span style="font-weight: bold"><span style="color: #0000FF">true</span></span><span style="color: #990000">,</span>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">},</span>
        "provides": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#provides</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Modules provided by a future compile rule for this source using the same flags</span>"<span style="color: #990000">,</span>
          "uniqueItems": <span style="font-weight: bold"><span style="color: #0000FF">true</span></span><span style="color: #990000">,</span>
          "default": <span style="color: #990000">[],</span>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/provided-module-desc</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">},</span>
        "requires": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#requires</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Modules required by a future compile rule for this source using the same flags</span>"<span style="color: #990000">,</span>
          "uniqueItems": <span style="font-weight: bold"><span style="color: #0000FF">true</span></span><span style="color: #990000">,</span>
          "default": <span style="color: #990000">[],</span>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/requires-module-desc</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">}</span>
      <span style="color: #990000">}</span>
    <span style="color: #990000">},</span>
    "provided-module-desc": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#module-desc</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
      "required": <span style="color: #990000">[</span>
        "logical-name"
      <span style="color: #990000">],</span>
      "properties": <span style="color: #990000">{</span>
        "source-path": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">},</span>
        "compiled-module-path": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">},</span>
        "unique-on-source-path": <span style="color: #990000">{</span>
          "type": "<span style="color: #FF0000">boolean</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Whether the module name is unique on `logical-name` or `source-path`</span>"<span style="color: #990000">,</span>
          "default": <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
        <span style="color: #990000">},</span>
        "logical-name": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">}</span>
      <span style="color: #990000">}</span>
    "required-module-desc": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#module-desc</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
      "required": <span style="color: #990000">[</span>
        "logical-name"
      <span style="color: #990000">],</span>
      "properties": <span style="color: #990000">{</span>
        "source-path": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">},</span>
        "compiled-module-path": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">},</span>
        "unique-on-source-path": <span style="color: #990000">{</span>
          "type": "<span style="color: #FF0000">boolean</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Whether the module name is unique on `logical-name` or `source-path`</span>"<span style="color: #990000">,</span>
          "default": <span style="font-weight: bold"><span style="color: #0000FF">false</span></span>
        <span style="color: #990000">},</span>
        "logical-name": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">},</span>
        "lookup-method": <span style="color: #990000">{</span>
          "type": "<span style="color: #FF0000">string</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">The method by which the module was requested</span>"<span style="color: #990000">,</span>
          "default": "<span style="color: #FF0000">by-name</span>"<span style="color: #990000">,</span>
          "enum": <span style="color: #990000">[</span>
            "by-name"<span style="color: #990000">,</span>
            "include-angle"<span style="color: #990000">,</span>
            "include-quote"
          <span style="color: #990000">]</span>
        <span style="color: #990000">}</span>
      <span style="color: #990000">}</span>
    <span style="color: #990000">}</span>
  <span style="color: #990000">},</span>
  "required": <span style="color: #990000">[</span>
    "version"<span style="color: #990000">,</span>
    "rules"
  <span style="color: #990000">],</span>
  "properties": <span style="color: #990000">{</span>
    "version": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#version</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">integer</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">The version of the output specification</span>"
    <span style="color: #990000">},</span>
    "revision": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#revision</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">integer</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">The revision of the output specification</span>"<span style="color: #990000">,</span>
      "default": <span style="color: #993399">0</span>
    <span style="color: #990000">},</span>
    "rules": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#rules</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
      "title": "<span style="color: #FF0000">rules</span>"<span style="color: #990000">,</span>
      "minItems": <span style="color: #993399">1</span><span style="color: #990000">,</span>
      "items": <span style="color: #990000">{</span>
        "$ref": "<span style="color: #FF0000">#/definitions/depinfo</span>"
      <span style="color: #990000">}</span>
    <span style="color: #990000">}</span>
  <span style="color: #990000">}</span>
<span style="color: #990000">}</span></tt></pre></div></div>
<div class="paragraph"><p> </div></details> </p></div>
</div>
<div class="sect2">
<h3 id="_storing_binary_data">6.2. Storing binary data</h3>
<div class="paragraph"><p>This format uses UTF-8 as a communication channel between a dependency scanning
tool and a build tool, but filepath encodings are specific to the platform
which means considerations for paths containing non-UTF-8 sequences must be
made. However, the most common uses of paths and filenames are either valid
UTF-8 sequences or may be unambiguously represented using UTF-8 (e.g., a
platform using UTF-16 for its path APIs has a valid UTF-8 encoding), so
requiring excessive obfuscation in all cases is unnecessary.</p></div>
<div class="paragraph"><p>After discussion with stakeholders, complicating the format for corner cases of
filepaths which do not have unambiguous UTF-8 representations is an unnecessary
complication at the moment. Future versions of the format may have a way to
unambiguously transmit filepaths that are not Unicode-unambiguous or not valid
Unicode if the need arises..</p></div>
<div class="paragraph"><p>There are some use cases (though rare) which cannot be handled without a way to
represent arbitrary paths. These include (but are not limited to):</p></div>
<div class="ulist"><ul>
<li>
<p>
Windows paths with unpaired surrogate half codepoints (for which there is
    no valid UTF-8 representation).
</p>
</li>
<li>
<p>
Encodings historically used for East Asian languages including Big-5,
    SHIFT-JIS, and others. There are characters in these encodings which share
    a Unicode representation, so there is no lossless way to use UTF-8 strings
    as a transport for these paths.
</p>
</li>
</ul></div>
<div class="paragraph"><p>These restrictions have been deemed to not be important enough to support at
this time in the general format. Note that many build tools already have
restrictions in characters due to implementation details. For example,
Makefiles have trouble representing paths ending with a <span class="monospaced">\\</span> character and
CMake has issues with paths containing its list separator, the semicolon.</p></div>
</div>
<div class="sect2">
<h3 id="_filepaths">6.3. Filepaths</h3>
<div class="paragraph"><p>Filepaths may be either relative or absolute. Build tools generally already
know the working directory because it chooses where to execute the tool in the
first place. If other tools require this information, it should be indicated to
the program writing the format which then shall write the provided directory to
the format in the <span class="monospaced">work-directory</span> property.</p></div>
</div>
<div class="sect2">
<h3 id="_rule_items">6.4. Rule items</h3>
<div class="paragraph"><p>The <span class="monospaced">rules</span> array allows for the dependency information of multiple rules to
be specified in a single file.</p></div>
<div class="paragraph"><p>The only restriction on the contents of the collective set of <span class="monospaced">rules</span> objects
is that the set of all <span class="monospaced">primary-output</span> and <span class="monospaced">outputs</span> of each object must be
unique. This is because if they are not unique, there are outputs which have
multiple rules that write to them, which is, in general, undefined behavior in
build tools.</p></div>
</div>
<div class="sect2">
<h3 id="_module_dependency_information">6.5. Module dependency information</h3>
<div class="paragraph"><p>Each rule represented in the <span class="monospaced">rules</span> array is a JSON object which has four
optional properties, <span class="monospaced">primary-output</span>, <span class="monospaced">outputs</span>, <span class="monospaced">provides</span>, and <span class="monospaced">requires</span>.
They are described as follows:</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">primary-output</span> (optional): The primary output of the rule being scanned.
    The build system generally dictates this value since it has to know what
    each rule outputs in order to make a build graph. To support this, tools
    writing this format should provide a way to fill in this value and it shall
    be written to this property.
</p>
</li>
<li>
<p>
<span class="monospaced">outputs</span> (optional): An array of additional outputs created by the rule
    being scanned.
</p>
</li>
<li>
<p>
<span class="monospaced">provides</span> (optional; defaults to <span class="monospaced">[]</span>): An array of module description
    objects which are provided by the rule being scanned.
</p>
</li>
<li>
<p>
<span class="monospaced">requires</span> (optional; defaults to <span class="monospaced">[]</span>): An array of module description
    objects which are required in order to perform the rule being scanned.
</p>
</li>
</ul></div>
<div class="paragraph"><p>Module descriptions for the <span class="monospaced">provides</span> and <span class="monospaced">requires</span> arrays include the
following properties:</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">logical-name</span> (required): The name of the module. This is the name to use
    to correlate between providing and requiring modules in order to determine
    the order compilation rules need to be performed.
</p>
</li>
<li>
<p>
<span class="monospaced">compiled-module-path</span> (optional): The path to the compiled module (if
    known).
</p>
</li>
<li>
<p>
<span class="monospaced">source-path</span> (optional if <span class="monospaced">unique-on-source-path</span> is <span class="monospaced">false</span>): The path to
    the source file for this module (if known).
</p>
</li>
<li>
<p>
<span class="monospaced">unique-on-source-path</span> (optional; defaults to <span class="monospaced">false</span>): Whether the module
    is unique based on its <span class="monospaced">logical-name</span> (if <span class="monospaced">false</span>) or <span class="monospaced">source-path</span> (if
    <span class="monospaced">true</span>).
</p>
</li>
</ul></div>
<div class="paragraph"><p>Additionally, those in the <span class="monospaced">requires</span> array may also include a property
indicating how the module was found:</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">lookup-method</span> (optional; defaults to <span class="monospaced">by-name</span>): Must be one of
    <span class="monospaced">by-name</span>, <span class="monospaced">include-angle</span>, or <span class="monospaced">include-quote</span>.
</p>
</li>
</ul></div>
<div class="sect3">
<h4 id="_language_specific_notes">6.5.1. Language-specific notes</h4>
<div class="sect4">
<h5 id="_fortran">Fortran</h5>
<div class="paragraph"><p>Fortran only supports named modules, so it will generally never have use the
<span class="monospaced">include-</span> <span class="monospaced">lookup-method</span> values. Additionally, the <span class="monospaced">source-path</span> will
generally not be known either as Fortran compilers only support finding
compiled modules. Fortran also supports providing multiple modules from a
single source file which is the reason <span class="monospaced">provides</span> is an array rather than a
single object.</p></div>
</div>
<div class="sect4">
<h5 id="_c">C++</h5>
<div class="paragraph"><p>In C++20, source files may only provide a single module or module partition,
so only one will be provided for each rule. Some compiler may choose to
implement the <span class="monospaced">:private</span> module partition as a separate module for lookup
purposes, and if so, it should be indicated as a separate <span class="monospaced">provides</span> entry.</p></div>
<div class="paragraph"><p>For header units, the logical name will likely be the full, normalized path to
the header itself in order to correlate its usage no matter how it is included
in the literal source. This is because a header imported via
<span class="monospaced">import "header.h";</span> or <span class="monospaced">import &lt;parent/header.h&gt;;</span> should both resolve to the
same module. In such cases, <span class="monospaced">unique-on-source-path</span> should be set to <span class="monospaced">true</span>.
This will allow the build system to know that the <span class="monospaced">"header.h"</span> and
<span class="monospaced">&lt;parent/header.h&gt;</span> modules are both the same.</p></div>
<div class="paragraph"><p>In some cases, it may be important to know whether the module was imported via
angle brackets or quotes. For this case, the <span class="monospaced">logical-name</span> can drop the
decoration and instead specify <span class="monospaced">lookup-method</span> to the appropriate indicator.</p></div>
<div class="listingblock">
<div class="title">Example source entry</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #990000">{</span>
  "primary-output": "<span style="color: #FF0000">path/to/output.o</span>"<span style="color: #990000">,</span>
  "provides": <span style="color: #990000">[</span>
    <span style="color: #990000">{</span>
      "compiled-module-path": "<span style="color: #FF0000">exported.bmi</span>"<span style="color: #990000">,</span>
      "logical-name": "<span style="color: #FF0000">exported</span>"
    <span style="color: #990000">}</span>
  <span style="color: #990000">],</span>
  "requires": <span style="color: #990000">[</span>
    <span style="color: #990000">{</span>
      "logical-name": "<span style="color: #FF0000">imported</span>"
    <span style="color: #990000">}</span>
  <span style="color: #990000">]</span>
<span style="color: #990000">}</span></tt></pre></div></div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_extensions">6.6. Extensions</h3>
<div class="paragraph"><p>Vendor extensions may be added to the format using properties prefixed with an
underscore (<span class="monospaced">_</span>) followed by a vendor-specific string followed by another
underscore. None of these may be used to store semantically relevant
information required to execute a correct build. Consumers must be able to
ignore all <span class="monospaced">_</span>-prefixed properties and not suffer any loss of essential
functionality.</p></div>
<div class="listingblock">
<div class="title">Example source entry with extended information</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #990000">{</span>
  "primary-output": "<span style="color: #FF0000">path/to/output</span>"<span style="color: #990000">,</span>
  "_VENDOR_extension": <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
<span style="color: #990000">}</span></tt></pre></div></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_versioning">7. Versioning</h2>
<div class="sectionbody">
<div class="paragraph"><p>There are two properties with integer values in the top-level JSON object of
the format: <span class="monospaced">version</span> and <span class="monospaced">revision</span>. The <span class="monospaced">version</span> property is required and if
<span class="monospaced">revision</span> is not provided, it can be assumed to be <span class="monospaced">0</span>. These indicate the
version of the information available in the format itself and what features may
be used. Tools creating this format should have a way to create older versions
of the format to support consumers that do not support newer format versions.</p></div>
<div class="paragraph"><p>The <span class="monospaced">version</span> integer is incremented when semantic information required for a
correct build is different than the previous version. When the <span class="monospaced">version</span> is
incremented, the <span class="monospaced">revision</span> integer is reset to <span class="monospaced">0</span>.</p></div>
<div class="paragraph"><p>The <span class="monospaced">revision</span> integer is incremented when the semantic information of the
format is the same as the previous revision of the same version, but it may
include additionally specified information or use an additionally specified
format for the same information. For example, adding a <span class="monospaced">modification_time</span> or
<span class="monospaced">input_hash</span> field may be helpful in some cases, but is not required to
understand the dependency information. Such an addition would cause an
increment of the <span class="monospaced">revision</span> value.</p></div>
<div class="paragraph"><p>The version specified in this document is:</p></div>
<div class="listingblock">
<div class="title">Version fields for this specification</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #990000">{</span>
  "version": <span style="color: #993399">1</span><span style="color: #990000">,</span>
  "revision": <span style="color: #993399">0</span>
<span style="color: #990000">}</span></tt></pre></div></div>
</div>
</div>
<div class="sect1">
<h2 id="_full_example">8. Full example</h2>
<div class="sectionbody">
<div class="paragraph"><p>Given the following three translation units in C++.</p></div>
<div class="listingblock">
<div class="title">Provide module TU (<span class="monospaced">duplicate.mpp</span>)</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">export</span></span> <span style="color: #008080">module</span> duplicate<span style="color: #990000">;</span>

<span style="font-weight: bold"><span style="color: #0000FF">export</span></span> <span style="color: #009900">int</span> <span style="font-weight: bold"><span style="color: #000000">m</span></span><span style="color: #990000">()</span> <span style="color: #FF0000">{</span>
    <span style="font-weight: bold"><span style="color: #0000FF">return</span></span> <span style="color: #993399">0</span><span style="color: #990000">;</span>
<span style="color: #FF0000">}</span></tt></pre></div></div>
<div class="listingblock">
<div class="title">Provide and require modules TU (<span class="monospaced">another.mpp</span>)</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">export</span></span> <span style="color: #008080">module</span> another<span style="color: #990000">;</span>
<span style="color: #008080">impot</span> duplicate<span style="color: #990000">;</span>

<span style="font-weight: bold"><span style="color: #0000FF">export</span></span> <span style="color: #009900">int</span> <span style="font-weight: bold"><span style="color: #000000">i</span></span><span style="color: #990000">()</span> <span style="color: #FF0000">{</span>
    <span style="font-weight: bold"><span style="color: #0000FF">return</span></span> <span style="font-weight: bold"><span style="color: #000000">m</span></span><span style="color: #990000">();</span>
<span style="color: #FF0000">}</span></tt></pre></div></div>
<div class="listingblock">
<div class="title">Require modules TU (<span class="monospaced">use.mpp</span>)</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #008080">import</span> duplicate<span style="color: #990000">;</span>
<span style="color: #008080">import</span> another<span style="color: #990000">;</span>

<span style="color: #009900">int</span> <span style="font-weight: bold"><span style="color: #000000">lib</span></span><span style="color: #990000">()</span> <span style="color: #FF0000">{</span>
    <span style="font-weight: bold"><span style="color: #0000FF">return</span></span> <span style="font-weight: bold"><span style="color: #000000">m</span></span><span style="color: #990000">()</span> <span style="color: #990000">+</span> <span style="font-weight: bold"><span style="color: #000000">i</span></span><span style="color: #990000">();</span>
<span style="color: #FF0000">}</span></tt></pre></div></div>
<div class="paragraph"><p>The scanning results of each TU can be represented by:</p></div>
<div class="listingblock">
<div class="title">Example scanning output</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #990000">{</span>
  "version": <span style="color: #993399">1</span><span style="color: #990000">,</span>
  "revision": <span style="color: #993399">0</span><span style="color: #990000">,</span>
  "rules": <span style="color: #990000">[</span>
    <span style="color: #990000">{</span>
      "primary-output": "<span style="color: #FF0000">duplicate.mpp.o</span>"<span style="color: #990000">,</span>
      "provides": <span style="color: #990000">[</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">duplicate</span>"
        <span style="color: #990000">}</span>
      <span style="color: #990000">]</span>
    <span style="color: #990000">},</span>
    <span style="color: #990000">{</span>
      "primary-output": "<span style="color: #FF0000">another.mpp.o</span>"<span style="color: #990000">,</span>
      "provides": <span style="color: #990000">[</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">another</span>"
        <span style="color: #990000">}</span>
      <span style="color: #990000">],</span>
      "requires": <span style="color: #990000">[</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">duplicate</span>"
        <span style="color: #990000">}</span>
      <span style="color: #990000">]</span>
    <span style="color: #990000">},</span>
    <span style="color: #990000">{</span>
      "primary-output": "<span style="color: #FF0000">use.mpp.o</span>"<span style="color: #990000">,</span>
      "requires": <span style="color: #990000">[</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">duplicate</span>"
        <span style="color: #990000">},</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">another</span>"
        <span style="color: #990000">}</span>
      <span style="color: #990000">]</span>
    <span style="color: #990000">}</span>
  <span style="color: #990000">]</span>
<span style="color: #990000">}</span></tt></pre></div></div>
<div class="paragraph"><p>Note that the scanner, in this case, has been told the <span class="monospaced">primary-output</span> for
each translation unit so that the build system can correlate which rule mapping
corresponds to each source file. The scanner, in this case, also does not
indicate where the module files might be generated, so it does not provide
<span class="monospaced">compiled-module-path</span> properties and it is up to the build system to generate
a suitable filename for each.</p></div>
<div class="paragraph"><p>An example with a header unit involved is:</p></div>
<div class="listingblock">
<div class="title">Provide header unit (<span class="monospaced">header.hpp</span>)</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="font-weight: bold"><span style="color: #000080">#define</span></span> header_unit_macro</tt></pre></div></div>
<div class="listingblock">
<div class="title">Require header unit TU (<span class="monospaced">use-header.mpp</span>)</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt>import <span style="color: #990000">&lt;</span>header<span style="color: #990000">.</span>hpp<span style="color: #990000">&gt;;</span>

<span style="font-weight: bold"><span style="color: #000080">#ifdef</span></span> header_unit_macro
<span style="font-weight: bold"><span style="color: #000080">#endif</span></span></tt></pre></div></div>
<div class="paragraph"><p>The scanning results of these files can be represented by:</p></div>
<div class="listingblock">
<div class="title">Example scanning output</div>
<div class="content"><!-- Generator: GNU source-highlight
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span style="color: #990000">{</span>
  "version": <span style="color: #993399">1</span><span style="color: #990000">,</span>
  "revision": <span style="color: #993399">0</span><span style="color: #990000">,</span>
  "rules": <span style="color: #990000">[</span>
    <span style="color: #990000">{</span>
      "primary-output": "<span style="color: #FF0000">use-header.mpp.o</span>"<span style="color: #990000">,</span>
      "requires": <span style="color: #990000">[</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">&lt;header.hpp&gt;</span>"<span style="color: #990000">,</span>
          "source-path": "<span style="color: #FF0000">/path/to/found/header.hpp</span>"<span style="color: #990000">,</span>
          "unique-on-source-path": <span style="font-weight: bold"><span style="color: #0000FF">true</span></span><span style="color: #990000">,</span>
          "lookup-method": "<span style="color: #FF0000">include-angle</span>"
        <span style="color: #990000">}</span>
      <span style="color: #990000">]</span>
    <span style="color: #990000">},</span>
    <span style="color: #990000">{</span>
      "primary-output": "<span style="color: #FF0000">header.hpp.bmi</span>"<span style="color: #990000">,</span>
      "provides": <span style="color: #990000">[</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">header.hpp</span>"<span style="color: #990000">,</span>
          "source-path": "<span style="color: #FF0000">/path/to/found/header.hpp</span>"<span style="color: #990000">,</span>
          "unique-on-source-path": <span style="font-weight: bold"><span style="color: #0000FF">true</span></span><span style="color: #990000">,</span>
        <span style="color: #990000">}</span>
      <span style="color: #990000">]</span>
    <span style="color: #990000">}</span>
  <span style="color: #990000">]</span>
<span style="color: #990000">}</span></tt></pre></div></div>
<div class="paragraph"><p>Note that the <span class="monospaced">logical-name</span> does not match because the scanner of <span class="monospaced">header.hpp</span>
does not know how it will be imported. This is the reason that <span class="monospaced">source-path</span> is
used and <span class="monospaced">unique-on-source-path</span> is set to <span class="monospaced">true</span>. The build system, in this
case, will need to use this to inform the compilation of <span class="monospaced">use-header.mpp</span> to
use the generated file for the header scanning under the name it will be
requested during the compilation (given as <span class="monospaced">logical-name</span>).</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_references">9. References</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
<a id="ECMA-404"></a>[ECMA-404] The JSON Data Interchange Syntax.
  <a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf">http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf</a>.
</p>
</li>
<li>
<p>
<a id="JSON-Schema"></a>[JSON-Schema] Austin Wright and Henry Andrews. JSON Schema: A Media Type
  for Describing JSON Documents.
  <a href="https://tools.ietf.org/html/draft-handrews-json-schema-01">https://tools.ietf.org/html/draft-handrews-json-schema-01</a>.
</p>
</li>
<li>
<p>
<a id="ninja"></a>[ninja] Ninja, a small build system with a focus on speed.
  <a href="https://ninja-build.org/">https://ninja-build.org/</a>.
</p>
</li>
<li>
<p>
<a id="P1103R3"></a>[P1103R3] Richard Smith. Merging Modules.
  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1103r3.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1103r3.pdf</a>.
</p>
</li>
<li>
<p>
<a id="Unicode-12"></a>[Unicode-12] Unicode Consortium. Unicode 12.0.0.
  <a href="https://www.unicode.org/versions/Unicode12.0.0/">https://www.unicode.org/versions/Unicode12.0.0/</a>.
</p>
</li>
</ul></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
Version P1689R4<br>
Last updated
 2021-06-14 15:17:12 EDT
</div>
</div>
</body>
</html>
