<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 10.2.0">
<title>Build database 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>Build database files</h1>
<span id="author">Ben Boeckel, Daniel Ruoso</span><br>
<span id="email" class="monospaced">&lt;<a href="mailto:ben.boeckel@kitware.com, druoso@bloomberg.net">ben.boeckel@kitware.com, druoso@bloomberg.net</a>&gt;</span><br>
<span id="revnumber">version P2977R2,</span>
<span id="revdate">2024-10-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/P2977R2
</p>
</td>
</tr>
<tr>
<td class="hdlist1">
Date
<br>
</td>
<td class="hdlist2">
<p style="margin-top: 0;">
2024-10-14
</p>
</td>
</tr>
<tr>
<td class="hdlist1">
Reply-to
<br>
</td>
<td class="hdlist2">
<p style="margin-top: 0;">
Ben Boeckel, Daniel Ruoso, <a href="mailto:ben.boeckel@kitware.com">ben.boeckel@kitware.com</a>, <a href="mailto:druoso@bloomberg.net">druoso@bloomberg.net</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>Build tools need to be able to manage modules for projects that do not use the
same compiler as the tool. However, compiled module formats are generally not
compatible between compilers (or even compiler versions) or tools which may
need to analyze modules for their own purposes (e.g., static analyzers). These
tools need to be able to compile module interfaces in their own format with an
understanding that corresponds to the actual build and therefore need to know
what flags are relevant in order to make analogous compiled modules as the main
build.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_changes">2. Changes</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_r2_wroclaw">2.1. R2 (Wroclaw)</h3>
<div class="paragraph"><p>This revision incorporates updates based on experience in implementing the
information described in R1. This includes:</p></div>
<div class="ulist"><ul>
<li>
<p>
adding a language indicator to support specifying more than just C++
</p>
</li>
<li>
<p>
set names may now be <span class="monospaced">null</span>; these sets may not be visible from any other set
</p>
</li>
<li>
<p>
move baseline arguments to the set rather than each translation unit
</p>
</li>
</ul></div>
</div>
<div class="sect2">
<h3 id="_r1_tokyo">2.2. R1 (Tokyo)</h3>
<div class="paragraph"><p>This revision incorporates updates based on experience in implementing the
information described in R0. This includes:</p></div>
<div class="ulist"><ul>
<li>
<p>
including the baseline arguments for a module set;
</p>
</li>
<li>
<p>
adding a "family name" to help draw associations between related sets;
</p>
</li>
<li>
<p>
including BMI paths for provided modules;
</p>
</li>
<li>
<p>
including information beyond just module-providing sources.
</p>
</li>
</ul></div>
<div class="paragraph"><p>This revision also selects the "Standalone" representation from the first
revision as its proposed format. Given the expanded scope, referring to a
compile commands database turns out to be significant duplication and not
worthwhile.</p></div>
</div>
<div class="sect2">
<h3 id="_r0_initial">2.3. R0 (Initial)</h3>
<div class="paragraph"><p>Initial paper.</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_contents">3. Contents</h2>
<div class="sectionbody">
<div class="paragraph"><p>In order to analyze a build with modules in it, a tool needs to know:</p></div>
<div class="ulist"><ul>
<li>
<p>
the module interface source;
</p>
</li>
<li>
<p>
the language the source uses;
</p>
</li>
<li>
<p>
the names of modules that it requires;
</p>
</li>
<li>
<p>
the set of sources which may provide modules which are required;
</p>
</li>
<li>
<p>
the visibility of the module within the set of sources;
</p>
</li>
<li>
<p>
the "baseline arguments" for a set to apply to modules from visible sets;
</p>
</li>
<li>
<p>
the set of "local preprocessor arguments" used during the build when
  processing the source; and
</p>
</li>
<li>
<p>
the working directory of the compilation.
</p>
</li>
</ul></div>
<div class="paragraph"><p>Given this, a tool may traverse the dependency graph through the set of sources
information for a given source in order to generate the appropriate module
artifacts for whatever analysis is being performed.</p></div>
<div class="sect2">
<h3 id="_interface_source">3.1. Interface source</h3>
<div class="paragraph"><p>The interface source path is required so that the tool understands what
consitutes the module itself.</p></div>
</div>
<div class="sect2">
<h3 id="_language">3.2. Language</h3>
<div class="paragraph"><p>The source may be in another source language. Not all of the world is C++ and
other languages (e.g., Objective-C++) may support consuming C++ modules.
Additionally, build databases may contain entries for compilation of C,
Fortran, etc. Standardized values are:</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">c</span>
</p>
</li>
<li>
<p>
<span class="monospaced">c++</span>
</p>
</li>
<li>
<p>
<span class="monospaced">fortran</span>
</p>
</li>
<li>
<p>
<span class="monospaced">objective-c</span>
</p>
</li>
<li>
<p>
<span class="monospaced">objective-c++</span>
</p>
</li>
</ul></div>
<div class="paragraph"><p>Languages not listed here may be specified with an <span class="monospaced">ext:</span> prefix and
standardized as a new <span class="monospaced">minor</span> version.</p></div>
</div>
<div class="sect2">
<h3 id="_provided_modules">3.3. Provided modules</h3>
<div class="paragraph"><p>The set of provided modules and their BMIs are required so that imports of the
module may know which source provides each module to satisfy an import.</p></div>
</div>
<div class="sect2">
<h3 id="_required_modules">3.4. Required modules</h3>
<div class="paragraph"><p>Modules imported by the module also need to be know in order to prepare
satisfaction of the contained <span class="monospaced">import</span> statements.</p></div>
</div>
<div class="sect2">
<h3 id="_visible_sets">3.5. Visible sets</h3>
<div class="paragraph"><p>Translation units are described in terms of "sets". Only modules that are
provided by members of sets which are visible of the translation unit&#8217;s owning
set may be used to satisfy <span class="monospaced">import</span> requests within the current module.</p></div>
<div class="paragraph"><p>A set is implicitly visible to itself with the additional power to also use
modules provided by <span class="monospaced">private</span> translation units.</p></div>
</div>
<div class="sect2">
<h3 id="_visibility">3.6. Visibility</h3>
<div class="paragraph"><p>Translation units that are part of a set may be marked as "private" to indicate
that they are not eligible for use by other sets. For example, the contained
symbols might not be accessible at runtime (using <span class="monospaced">-fvisibility=hidden</span> or a
lack of <span class="monospaced">__declspec</span> decorations). They are specified in order to given more
useful diagnostics if they are mentioned from other sets and to indicate usage
within the set itself.</p></div>
</div>
<div class="sect2">
<h3 id="_baseline_arguments">3.7. Baseline arguments</h3>
<div class="paragraph"><p>These arguments are used for a set when applied to any imported modules in
order to create compatible BMI files. Tooling may need to "translate" flags for
the compiler in use (where the flags come from) for itself.</p></div>
</div>
<div class="sect2">
<h3 id="_local_arguments">3.8. Local arguments</h3>
<div class="paragraph"><p>These arguments are required to be used to create the module in a corresponding
way. Tooling may need to "translate" flags for the compiler in use (where the
flags come from) for itself.</p></div>
</div>
<div class="sect2">
<h3 id="_working_directory">3.9. Working directory</h3>
<div class="paragraph"><p>Tooling interprets relative paths differently based on the current working
directory. This field is specified so that tooling may agree with the compiler
as needed.</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_sets_of_translation_units">4. Sets of translation units</h2>
<div class="sectionbody">
<div class="paragraph"><p>Each set contains a collection of translation units that "belong" together.
They should have some connection with each other (e.g., part of the same
library artifact), but there are no defined semantics of the format itself.
Sets are unique by their <span class="monospaced">name</span> field but may indicate a "family name" as well.
Sets which share a family name are related (e.g., by having the same source
files). Each set then represents a single "view" on the sources that create
separate, but incompatible, BMIs for consumers to use. They may differ based on
local arguments or baseline arguments depending on whether the BMIs are needed
for different configurations (e.g., "release" versus "debug") or consumers
(e.g., incompatible flags).</p></div>
<div class="paragraph"><p>A set may only list a single member of a family in its list of visible sets. If
multiple family members of a family could be visible, it would be ambiguous
which family member provides modules from the common sources.</p></div>
<div class="sect2">
<h3 id="_tooling">4.1. Tooling</h3>
<div class="paragraph"><p>Tools which consume build databases may have different views on what
constitutes an incompatible BMI. Tools may need to create their own new family
members to support combinations of local arguments and baseline arguments used
during the actual build.</p></div>
</div>
<div class="sect2">
<h3 id="_unnamed_sets">4.2. Unnamed sets</h3>
<div class="paragraph"><p>Sets may also be unnamed (i.e., <span class="monospaced">null</span>). Such sets are not eligible to be
visible from any other set for the purposes of modules and are considered
separate from any other unnamed set.</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_representation">5. Representation</h2>
<div class="sectionbody">
<div class="paragraph"><p>There are a few potential ways in which this information may be represented
within a build tree. Here, a few possible representations are presented.</p></div>
<div class="sect2">
<h3 id="_standalone">5.1. Standalone</h3>
<div class="paragraph"><p>The first option is for a standalone database which contains all of the
relevant information. It might be in separate files (see below) and later
combined into a single database for convenience.</p></div>
<div class="paragraph"><p>A benefit of this is that the content could be reused for the installation
rather than just the build tree (as a compilation database doesn&#8217;t make sense
for installations).</p></div>
</div>
<div class="sect2">
<h3 id="_cross_reference_with_compile_commands_database">5.2. Cross-reference with Compile Commands Database</h3>
<div class="paragraph"><p>Another way would be for the module database to be used in conjunction with a
compilation database <a href="#json-cdb">[json-cdb]</a>. This would help to reduce duplication, but
would require tooling to manually perform joins on the two databases to get all
of the required information.</p></div>
<div class="paragraph"><p>The main issue with this approach is that the most reliable way of correlating
the module database with the compilation database relies on an optional value
(<span class="monospaced">output</span>) as a single source might participate in a build graph more than once
with different flags (e.g., building release and debug or static and shared
variants at the same time).</p></div>
<div class="paragraph"><p>It would also likely involve adopting the compilation database from the Clang
team and into ISO with the additional enhancements specified for modules.</p></div>
</div>
<div class="sect2">
<h3 id="_share_with_compile_commands_database">5.3. Share with Compile Commands Database</h3>
<div class="paragraph"><p>Another alternative would be to split the information into parts that could be
shared with the compilation database (such as the local preprocessor flags) and
the module-specific information (such as module sets and their dependencies)
refer to this shared information as well.</p></div>
<div class="paragraph"><p>This approach would not require that the compilation database be adopted into
ISO as it would just also have pointers to the shared portion (though the
rationale for the split may be awkward).</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_json_schema">6. JSON Schema</h2>
<div class="sectionbody">
<div class="paragraph"><p>This paper selects the "Standalone" solution in order to keep it simpler as the
compilation database would be largely duplicated with the additional
information.</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">C++ build database</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">string</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>
    "argument": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#argument</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">string</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">An command line argument</span>"<span style="color: #990000">,</span>
    <span style="color: #990000">},</span>
    "module_name": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#module_name</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">string</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">The logical name of a module</span>"<span style="color: #990000">,</span>
      "minLength": <span style="color: #993399">1</span>
    <span style="color: #990000">},</span>
    "set_name": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#set_name</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">string</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">The name of a set</span>"<span style="color: #990000">,</span>
      "minLength": <span style="color: #993399">1</span>
    <span style="color: #990000">},</span>
    "set": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#set</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">A collection of translation units</span>"<span style="color: #990000">,</span>
      "required": <span style="color: #990000">[</span>
        "baseline-arguments"<span style="color: #990000">,</span>
        "family-name"<span style="color: #990000">,</span>
        "name"<span style="color: #990000">,</span>
        "translation-units"
      <span style="color: #990000">],</span>
      "properties": <span style="color: #990000">{</span>
        "baseline-arguments": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#baseline_arguments</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Baseline arguments for the set that apply to imported translation units</span>"<span style="color: #990000">,</span>
          "default": <span style="color: #990000">[],</span>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/argument</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">},</span>
        "family-name": <span style="color: #990000">{</span>
          "type": "<span style="color: #FF0000">string</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">The family name of the module set</span>"
        <span style="color: #990000">},</span>
        "name": <span style="color: #990000">{</span>
          "type": <span style="color: #990000">[</span>"string"<span style="color: #990000">,</span> "null"<span style="color: #990000">],</span>
          "description": "<span style="color: #FF0000">The name of the module set</span>"
        <span style="color: #990000">},</span>
        "visible-sets": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#visible_sets</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": ""<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/set_name</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">},</span>
        "translation-units": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#translation_units</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">The translation units of the set</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/translation_unit</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">}</span>
      <span style="color: #990000">}</span>
    <span style="color: #990000">},</span>
    "translation_unit": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#translation_unit</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
      "description": "<span style="color: #FF0000">A translation unit</span>"<span style="color: #990000">,</span>
      "required": <span style="color: #990000">[</span>
        "source"<span style="color: #990000">,</span>
        "language"<span style="color: #990000">,</span>
        "arguments"
      <span style="color: #990000">],</span>
      "properties": <span style="color: #990000">{</span>
        "arguments": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#arguments</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">The arguments to compile this translation unit</span>"<span style="color: #990000">,</span>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/argument</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">},</span>
        "language": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#local_arguments</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">string</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">The language of the source file</span>"<span style="color: #990000">,</span>
        <span style="color: #990000">},</span>
        "local-arguments": <span style="color: #990000">{</span>
          "$id": "<span style="color: #FF0000">#local_arguments</span>"<span style="color: #990000">,</span>
          "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Local arguments to the translation unit</span>"<span style="color: #990000">,</span>
          "default": <span style="color: #990000">[],</span>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/argument</span>"
          <span style="color: #990000">}</span>
        <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>
        "private": <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 is available to other module sets</span>"<span style="color: #990000">,</span>
          "default": <span style="font-weight: bold"><span style="color: #0000FF">false</span></span><span style="color: #990000">,</span>
        <span style="color: #990000">},</span>
        "source": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">},</span>
        "object": <span style="color: #990000">{</span>
          "$ref": "<span style="color: #FF0000">#/definitions/datablock</span>"
        <span style="color: #990000">},</span>
        "provides": <span style="color: #990000">{</span>
          "type": "<span style="color: #FF0000">object</span>"<span style="color: #990000">,</span>
          "description": "<span style="color: #FF0000">Modules provided by the translation unit</span>"<span style="color: #990000">,</span>
          "default": <span style="color: #990000">{},</span>
          "items": <span style="color: #990000">{</span>
            "$ref": "<span style="color: #FF0000">#/definitions/module_name</span>"
          <span style="color: #990000">}</span>
        <span style="color: #990000">},</span>
        "requires": <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 the translation unit</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/module_name</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>
  "required": <span style="color: #990000">[</span>
    "version"<span style="color: #990000">,</span>
    "sets"
  <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>
    "sets": <span style="color: #990000">{</span>
      "$id": "<span style="color: #FF0000">#sets</span>"<span style="color: #990000">,</span>
      "type": "<span style="color: #FF0000">array</span>"<span style="color: #990000">,</span>
      "title": "<span style="color: #FF0000">sets</span>"<span style="color: #990000">,</span>
      "minItems": <span style="color: #993399">0</span><span style="color: #990000">,</span>
      "items": <span style="color: #990000">{</span>
        "$ref": "<span style="color: #FF0000">#/definitions/set</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>
<div class="sect1">
<h2 id="_availability">7. Availability</h2>
<div class="sectionbody">
<div class="paragraph"><p>Generally, these module compilation databases must be created during the build
itself. This is because the set of module names in a build are not necessarily
known until the build is underway.</p></div>
<div class="paragraph"><p>However, this is not a new problem as the compilation database can refer to the
compilation of generated sources which do not exist until the build has
completed some of its work.</p></div>
<div class="paragraph"><p>Build systems should offer mechanisms to combine module compilation databases
together into combined files in well-known locations so that consuming tools do
not need to search for relevant files and have a reliable way to make sure that
the information is consistent across the entire file. This would be provided by
relying on standard features of build systems to update outputs when inputs
change and the appropriate dependency information provided.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_combining">8. Combining</h2>
<div class="sectionbody">
<div class="paragraph"><p>Combining two module compilation databases is as trivial as ensuring the
version information is consistent and appending each file&#8217;s <span class="monospaced">sets</span> arrays into
a single array and writing out the combined information.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_versioning">9. 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.</p></div>
<div class="paragraph"><p>The <span class="monospaced">version</span> integer is incremented when semantic information required for a
correct interpretation 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 graph. 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="_references">10. References</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
<a id="json-cdb"></a>[json-cdb] JSON Compilation Database Format Specification.
  <a href="https://clang.llvm.org/docs/JSONCompilationDatabase.html">https://clang.llvm.org/docs/JSONCompilationDatabase.html</a>.
</p>
</li>
</ul></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
Version P2977R2<br>
Last updated
 2024-10-15 10:20:19 EDT
</div>
</div>
</body>
</html>
