<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 9.0.2">
<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 P1689R3,</span>
<span id="revdate">2020-12-09</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/P1689R3
</p>
</td>
</tr>
<tr>
<td class="hdlist1">
Date
<br>
</td>
<td class="hdlist2">
<p style="margin-top: 0;">
2020-12-09
</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="_r3_dec_2020_mailing">2.1. 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.2. 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.3. 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.4. 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 dependencies of running the dependency scanning tool itself;
</p>
</li>
<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>
</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>
      "required": <span style="color: #990000">[</span>
        "inputs"<span style="color: #990000">,</span>
        "work-directory"
      <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>
        "inputs": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#inputs</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Files that were read by this execution</span>"<span style="color: #990000">,</span>
          "uniqueItems": <span style="font-weight: bold"><span style="color: #0000FF">true</span></span><span style="color: #990000">,</span>
          "minLength": <span style="color: #993399">1</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>
        "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">Files that will be output by this execution</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>
        "depends": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#depends</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Paths read during this execution</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>
        "future-compile": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/future-depinfo</span>"
        <span style="color: #990000">}</span>
      <span style="color: #990000">}</span>
    <span style="color: #990000">},</span>
    "future-depinfo": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#future-depinfo</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
      "properties": <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">Files output by a future 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>
          "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>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/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>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/module-desc</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">}</span>
      <span style="color: #990000">}</span>
    <span style="color: #990000">},</span>
    "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>
        "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>
    <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 either be relative or absolute. To this end, the dependency
scanning tool must output its working directory in the <span class="monospaced">work-directory</span>
property for each rule. The build tool may then construct the absolute paths as
necessary.</p></div>
<div class="paragraph"><p>For concrete examples where absolute paths may not be suitable:</p></div>
<div class="ulist"><ul>
<li>
<p>
A distributed build may perform the compilation in a different directory on
    another machine than the host machine is using.
</p>
</li>
<li>
<p>
A build tool uses a chroot for each command it
    invokes.<span class="footnote"><br>[Concretely, the Tup build tool can execute
    compile rules inside of individual FUSE chroots where absolute paths are
    meaningless outside of that context. In this case, Tup would know how to
    translate between the producer&#8217;s and consumer&#8217;s different chroot paths.]<br></span>
</p>
</li>
</ul></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">outputs</span> in each object and <span class="monospaced">future-compile</span> object
must be unique (after translation into the appropriate environment). 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="_dependency_information">6.5. Dependency information</h3>
<div class="paragraph"><p>Each rule represented in the <span class="monospaced">rules</span> array is a JSON object which has a single
required property, <span class="monospaced">inputs</span>. The value of this property is an array of
<span class="monospaced">datablock</span> entries representing a set of filepaths that are read directly by
the execution of this rule. A rule must have at least one input because
otherwise the rule is idempotent and never needs dependency information to be
discovered. Two optional properties exist to indicate the dependencies of the
execution of the dependency scanning tool itself: the <span class="monospaced">outputs</span> array and the
<span class="monospaced">depends</span> array. The <span class="monospaced">depends</span> value is an array in which each element is a
filepath for files that affect the results of the run. For C++, this will
generally be paths due to <span class="monospaced">#include</span>, but other mechanisms may be in effect
(e.g., the proposed <span class="monospaced">#embed</span> directive discussed in <a href="#P1040R6">[P1040R6]</a> and
<a href="#P1967R2">[P1967R2]</a>).</p></div>
</div>
<div class="sect2">
<h3 id="_future_dependency_information">6.6. Future dependency information</h3>
<div class="paragraph"><p>The core of this specification is the <span class="monospaced">future-compile</span> property on a <span class="monospaced">rules</span>
object. <span class="monospaced">future-compile</span> objects have three optional properties, <span class="monospaced">outputs</span>,
<span class="monospaced">provides</span>, and <span class="monospaced">requires</span>.</p></div>
<div class="paragraph"><p>The <span class="monospaced">outputs</span> array contains filepaths which will be written to when the source
is compiled (e.g., object files or debugging sidecar files). The <span class="monospaced">provides</span> and
<span class="monospaced">requires</span> arrays contain names of modules. The <span class="monospaced">provides</span> array is for modules
that the inputs will produce and the <span class="monospaced">requires</span> array is for modules that the
inputs require. Each item of these arrays is a JSON object with one required
property, <span class="monospaced">logical-name</span>, and two optional properties: <span class="monospaced">compiled-module-path</span>
and <span class="monospaced">source-path</span>. All of these property&#8217;s values are filepaths. The
<span class="monospaced">logical-name</span> value is what build tools must use to discover the ordering
among translation unit compilations. In C++, this will generally be the name
of the module (including its partition, if any) as included in the source. The
<span class="monospaced">compiled-module-path</span> should be provided only if the location of the module&#8217;s
artifact is known when the dependency information is discovered. The
<span class="monospaced">source-path</span> is the path to the main source of the module. This is intended to
be used to communicate the location of a header for a header-unit import or a
module interface unit for a C++20 module when it is known.</p></div>
<div class="listingblock">
<div class="title">Example source entry with <span class="monospaced">future-compile</span> 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>
  "inputs": <span style="color: #990000">[</span>
    "path/to/input.cxx"
  <span style="color: #990000">],</span>
  "future-compile": <span style="color: #990000">[</span>
    "outputs": <span style="color: #990000">[</span>
      "path/to/output.o"
    <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>
<span style="color: #990000">}</span></tt></pre></div></div>
</div>
<div class="sect2">
<h3 id="_extensions">6.7. 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>
  "input": "<span style="color: #FF0000">path/to/input</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 this reduced source file <span class="monospaced">module.cpp</span>:</p></div>
<div class="listingblock">
<div class="title">Reduced example C++ module source</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> my<span style="color: #990000">.</span>module<span style="color: #990000">;</span>

<span style="color: #008080">import</span> other<span style="color: #990000">.</span>module<span style="color: #990000">;</span>
import <span style="color: #990000">&lt;</span>header<span style="color: #990000">&gt;;</span>

<span style="font-weight: bold"><span style="color: #000080">#include</span></span> <span style="color: #FF0000">"config.h"</span></tt></pre></div></div>
<div class="paragraph"><p>a full output for scanning this source could be:</p></div>
<div class="listingblock">
<div class="title">Example dependency 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>
    "work-directory": "<span style="color: #FF0000">/scanner/working/dir</span>"<span style="color: #990000">,</span>
    "inputs": <span style="color: #990000">[</span>
      "my.module.cpp"
    <span style="color: #990000">],</span>
    "outputs": <span style="color: #990000">[</span>
      "depinfo.json"
    <span style="color: #990000">],</span>
    "depends": <span style="color: #990000">[</span>
      "/system/include/path/header"<span style="color: #990000">,</span>
      "include/path/config.h"
    <span style="color: #990000">],</span>
    "future-compile": <span style="color: #990000">{</span>
      "outputs": <span style="color: #990000">[</span>
        "my.module.cpp.o"<span style="color: #990000">,</span>
        "my_module.bmi"
      <span style="color: #990000">],</span>
      "provides": <span style="color: #990000">[</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">my.module</span>"<span style="color: #990000">,</span>
          "source-path": "<span style="color: #FF0000">my.module.cpp</span>"<span style="color: #990000">,</span>
          "compiled-module-path": "<span style="color: #FF0000">my_module.bmi</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">other.module</span>"
        <span style="color: #990000">}</span>
        <span style="color: #990000">{</span>
          "logical-name": "<span style="color: #FF0000">&lt;header&gt;</span>"<span style="color: #990000">,</span>
          "source-path": "<span style="color: #FF0000">/system/include/path/header</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>
</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="P1040R6"></a>[P1040R6] JeanHeyd Meneide. std::embed and #depend.
  <a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1040r6.html">http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1040r6.html</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="P1967R2"></a>[P1967R2] JeanHeyd Meneide. #embed - a simple, scannable
  preprocessor-based resource acquisition method.
  <a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1967r2.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1967r2.pdf</a>.
</p>
</li>
<li>
<p>
<a id="RFC3629"></a>[RFC3629] Francois Yergeau. UTF-8, a transformation format of ISO 10646.
  <a href="https://tools.ietf.org/html/rfc3629">https://tools.ietf.org/html/rfc3629</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 P1689R3<br>
Last updated
 2020-12-09 16:38:21 EST
</div>
</div>
</body>
</html>
