<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P1767R0: Packaging C++ Modules</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in §N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .assertion  for assertions                    (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/******************************************************************************/
/*                                   Body                                     */
/******************************************************************************/

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;               /* limit line length to 50em for readability   */
		margin: 0 auto;                /* center text within page                     */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag     */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		/* Colors */
		color: black;
		background: white top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		color: white;
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		border-color: #c00;
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 2;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
			color: black;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			background: white;
			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;
			background: white;
		}
		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		#toc-nav > a:hover,
		#toc-nav > a:focus {
			background: #f8f8f8;
		}
		#toc-nav > a:not(:hover):not(:focus) {
			color: #707070;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}

		#toc-toggle-inline {
			vertical-align: 0.05em;
			font-size: 80%;
			color: gray;
			color: hsla(203,20%,40%,.7);
			border-style: none;
			background: transparent;
			position: relative;
		}
		#toc-toggle-inline:hover:not(:active),
		#toc-toggle-inline:focus:not(:active) {
			text-shadow: 1px 1px silver;
			top: -1px;
			left: -1px;
		}

		#toc-nav :active {
			color: #C00;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;    /* Inherit the font family. */
		line-height: 1.2;        /* Keep wrapped headings compact */
		hyphens: manual;         /* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		background: transparent;
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#subtitle {
		/* #subtitle is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	 border-left: 0.5em solid #DEF;
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd; border-radius: .5em;
	  margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	  margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	  margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	 margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	 margin-left: -2em;
	}
	dl.switch {
	 padding-left: 2em;
	}
	dl.switch > dt {
	 text-indent: -1.5em;
	 margin-top: 1em;
	}
	dl.switch > dt + dt {
	 margin-top: 0;
	}
	dl.switch > dt::before {
	 content: '\21AA';
	 padding: 0 0.5em 0 0;
	 display: inline-block;
	 width: 1em;
	 text-align: right;
	 line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: medium;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del { color: red;  text-decoration: line-through; }
	ins { color: #080; text-decoration: underline;    }

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

  /* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		text-decoration: none;
		border-bottom: 1px solid #707070;
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		border-bottom-color: #BBB;
	}

	/* Use distinguishing colors when user is interacting with the link */
	a[href]:focus,
	a[href]:hover {
		background: #f8f8f8;
		background: rgba(75%, 75%, 75%, .25);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	a[href]:active {
		color: #C00;
		border-color: #C00;
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	/* For autogen numbers, add
	   .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,    .sidefigure img,    figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote {
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	.issue,
	.note,
	.example,
	.advisement,
	.assertion,
	blockquote {
		margin: 1em auto;
	}
	.note  > p:first-child,
	.issue > p:first-child,
	blockquote > :first-child {
		margin-top: 0;
	}
	blockquote > :last-child {
		margin-bottom: 0;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	   or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #E0CB52;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	   or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52E052;
		background: #E9FBE9;
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary::before,
	details.note > summary > .marker {
		text-transform: uppercase;
		display: block;
		color: hsl(120, 70%, 30%);
	}
	/* Add .note::before { content: "Note"; } for autogen label,
	   or use class="marker" to mark up the label in source. */

	details.note > summary {
		display: block;
		color: hsl(120, 70%, 30%);
	}
	details.note[open] > summary {
		border-bottom: 1px silver solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		background: #EEE;
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-style: none solid;
		background: #FFEECC;
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement > .marker {
		color: #B35F00;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 1em;
		right: 1em;
		bottom: 1em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #DEF;
		margin: 1.2em 0;
		border-left: 0.5em solid #8CCBF2;
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def           td.footnote {
		padding-top: 0.6em;
	}
	table.def           td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		 <table class="data"> highlights structural relationships in a table
		 when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		 Use class="complex data" for particularly complicated tables --
		 (This will draw more lines: busier, but clearer.)

		 Use class="long" on table cells with paragraph-like contents
		 (This will adjust text alignment accordingly.)
		 Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
	 vertical-align: baseline;
	 text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
		line-height: 1.1rem; /* consistent spacing */
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li             { font-weight: bold;   }
	.toc > li li          { font-weight: normal; }
	.toc > li li li       { font-size:   95%;    }
	.toc > li li li li    { font-size:   90%;    }
	.toc > li li li li .secno { font-size: 85%; }
	.toc > li li li li li { font-size:   85%;    }
	.toc > li li li li li .secno { font-size: 100%; }

	/* @supports not (display:grid) { */
		.toc > li             { margin: 1.5rem 0;    }
		.toc > li li          { margin: 0.3rem 0;    }
		.toc > li li li       { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}

		.toc li {
			clear: both;
		}

		:not(li) > .toc              { margin-left:  5rem; }
		.toc .secno                  { margin-left: -5rem; }
		.toc > li li li .secno       { margin-left: -7rem; }
		.toc > li li li li .secno    { margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc              { margin-left:  4rem; }
			.toc .secno                  { margin-left: -4rem; }
			.toc > li li li              { margin-left:  1rem; }
			.toc > li li li .secno       { margin-left: -5rem; }
			.toc > li li li li .secno    { margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
	/* } */

	@supports (display:grid) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			   comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
		}
		#toc .content:hover {
			background: rgba(75%, 75%, 75%, .25);
			border-bottom: 3px solid #054572;
			margin-bottom: -3px;
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index       { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li    { margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em }
	ul.index dl    { margin-top: 0; }
	ul.index dt    { margin: .2em 0 .2em 20px;}
	ul.index dd    { margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		background: #f7f8f9;
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

	/* This rule is inherited from past style sheets. No idea what it's for. */
	.hide { display: none }



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-left: calc(13px + 26.5rem - 50vw);
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-left: calc(40em - 50vw) !important;
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-left: 0 !important;
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			 * http://lea.verou.me/2012/04/background-attachment-local/
			 *
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
			            top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
			            top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style type="text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }
  </style>
  <meta content="Bikeshed version 872cce6d3026423d677f3bd5837f1a1a46299a04" name="generator">
  <link href="http://wg21.link/p1767r0" rel="canonical">
  <link href="https://isocpp.org/favicon.ico" rel="icon">
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-syntax-highlighting */

.highlight:not(.idl) { background: hsl(24, 20%, 95%); }
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */
</style>
<style>/* style-selflinks */

.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: gray;
    color: white;
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: black;
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: #005a9c;
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P1767R0<br>Packaging C++ Modules</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2019-06-16">2019-06-16</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="http://wg21.link/p1767r0">http://wg21.link/p1767r0</a>
     <dt>Author:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:richard@metafoo.co.uk">Richard Smith</a> (<span class="p-org org">Google</span>)
     <dt>Audience:
     <dd>SG15
     <dt>Project:
     <dd>ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>This paper describes one concrete possibility for a packaging mechanism for C++ code.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#problem"><span class="secno">1</span> <span class="content">Problem</span></a>
    <li><a href="#scope"><span class="secno">2</span> <span class="content">Scope</span></a>
    <li>
     <a href="#approach"><span class="secno">3</span> <span class="content">Approach</span></a>
     <ol class="toc">
      <li><a href="#package"><span class="secno">3.1</span> <span class="content">Packages</span></a>
      <li><a href="#manifest"><span class="secno">3.2</span> <span class="content">Manifests</span></a>
      <li><a href="#uniqueness"><span class="secno">3.3</span> <span class="content">Package names and uniqueness</span></a>
      <li><a href="#linkage"><span class="secno">3.4</span> <span class="content">Package names and linkage</span></a>
      <li><a href="#convention"><span class="secno">3.5</span> <span class="content">Package name conventions</span></a>
     </ol>
    <li>
     <a href="#consequences"><span class="secno">4</span> <span class="content">Consequences</span></a>
     <ol class="toc">
      <li><a href="#authors"><span class="secno">4.1</span> <span class="content">For C++ library authors</span></a>
      <li><a href="#packagers"><span class="secno">4.2</span> <span class="content">For C++ library packagers</span></a>
      <li><a href="#build-system"><span class="secno">4.3</span> <span class="content">For C++ build system vendors</span></a>
      <li><a href="#compilers"><span class="secno">4.4</span> <span class="content">For C++ compiler vendors</span></a>
      <li><a href="#tools"><span class="secno">4.5</span> <span class="content">For C++ tool vendors</span></a>
     </ol>
    <li>
     <a href="#index"><span class="secno"></span> <span class="content">Index</span></a>
     <ol class="toc">
      <li><a href="#index-defined-here"><span class="secno"></span> <span class="content">Terms defined by this specification</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="problem"><span class="secno">1. </span><span class="content">Problem</span><a class="self-link" href="#problem"></a></h2>
   <p>A C++ project (a program or library) typically has dependencies on libraries
provided by third parties. When using those libraries, the build system of the
project needs to be aware of how to make the dependencies visible to the build
of the project.</p>
   <p>In C++17 and before, there are a number of necessary pieces for using such a
dependency, typically including:</p>
   <ul>
    <li data-md>
     <p>A set of include paths</p>
    <li data-md>
     <p>A set of predefined compiler macros</p>
    <li data-md>
     <p>A set of libraries to link against</p>
   </ul>
   <p>... and possibly other things too.</p>
   <p>In C++20, this becomes more complicated, because in general we additionally
need to build module interfaces and header units as part of the build of the
project. Some build-system-independent mechanism for providing this information
would be highly valuable.</p>
   <h2 class="heading settled" data-level="2" id="scope"><span class="secno">2. </span><span class="content">Scope</span><a class="self-link" href="#scope"></a></h2>
   <p>There are (at least) three different levels at which C++ code is distributed:</p>
   <ol>
    <li data-md>
     <p>Source distribution (eg, I download your library from github, or I check out
 a project that I intend to hack on)</p>
    <li data-md>
     <p>Precompiled library distribution to developers (eg, I install a package with
 a package manager, or I build a library that I downloaded and install its
 built components somewhere for later use by other code)</p>
    <li data-md>
     <p>Binary-only distribution to end-users (eg, the product made available for
 download on some company’s website)</p>
   </ol>
   <p>This paper is concerned primarily with the second level. While its approach has
implications for the first and third level, the intent is to not constrain the
build systems and development techniques used for package maintainers nor the
ways in which C++ projects are distributed and installed on end-user systems.</p>
   <p>This paper doesn’t intend to provide or describe a complete, finished solution
for any of the problems it touches upon. Instead, the hope is that this
provides a venue for discussion of this approach that might lead to a more
concrete finalized solution.</p>
   <h2 class="heading settled" data-level="3" id="approach"><span class="secno">3. </span><span class="content">Approach</span><a class="self-link" href="#approach"></a></h2>
   <h3 class="heading settled" data-level="3.1" id="package"><span class="secno">3.1. </span><span class="content">Packages</span><a class="self-link" href="#package"></a></h3>
   <p>A <dfn data-dfn-type="dfn" data-noexport id="package①">package<a class="self-link" href="#package①"></a></dfn> is a collection of C++ file system artifacts
that are built and installed together
in a specific build configuration. A package typically contains:</p>
   <ul>
    <li data-md>
     <p>A package <a href="#manifest">manifest</a></p>
    <li data-md>
     <p>Some translated translation units, in the form of
prebuilt libraries (<code class="highlight"><c- p>.</c-><c- n>lib</c-></code> / <code class="highlight"><c- p>.</c-><c- n>a</c-></code> / <code class="highlight"><c- p>.</c-><c- n>dll</c-></code> / <code class="highlight"><c- p>.</c-><c- n>so</c-></code> / <code class="highlight"><c- p>.</c-><c- n>dylib</c-></code> / ...),</p>
    <li data-md>
     <p>Some module interface units</p>
    <li data-md>
     <p>Some header units</p>
    <li data-md>
     <p>Some textual header files</p>
   </ul>
   <p>(It would be possible to ship some compiler-specific module representation
("CMI") files for a specific compiler along with a package, and this is not
precluded by the model of a package. However, such files should be thought of
as strictly an optional extra that does not replace the necessity to provide
sources for module interfaces and header units.)</p>
   <p>Modules and packages are different levels of a hierarchy of components:</p>
   <ul>
    <li data-md>
     <p>A package contains zero or more complete libraries. (A single library cannot
be split across packages.)</p>
    <li data-md>
     <p>A library (<code class="highlight"><c- p>.</c-><c- n>lib</c-></code> / <code class="highlight"><c- p>.</c-><c- n>a</c-></code> / <code class="highlight"><c- p>.</c-><c- n>dll</c-></code> / <code class="highlight"><c- p>.</c-><c- n>so</c-></code> / <code class="highlight"><c- p>.</c-><c- n>dylib</c-></code> / ...) contains
zero or more complete modules, and zero or more complete non-module
translation units.</p>
    <li data-md>
     <p>A module contains zero or more module units.</p>
   </ul>
   <p>A module is a coherent unit of encapsulation and isolation and provides
an encapsulation boundary, whereas a package is a coherent bundle of
artifacts that should be distributed together, and so instead provides a
distribution boundary.</p>
   <p>A package is intended to be independent of the build system that produced it
and independent of the build systems that will consume it.</p>
   <div class="example" id="example-65675278"><a class="self-link" href="#example-65675278"></a> On Linux distributions, package management systems are used
to install packages.
On my development Debian machine,
boost is divided into 30 different <code class="highlight"><c- o>-</c-><c- n>dev</c-></code> packages,
each of which is a package in the sense defined in this document. </div>
   <h3 class="heading settled" data-level="3.2" id="manifest"><span class="secno">3.2. </span><span class="content">Manifests</span><a class="self-link" href="#manifest"></a></h3>
   <p>A <dfn data-dfn-type="dfn" data-noexport id="package-manifest">package manifest<a class="self-link" href="#package-manifest"></a></dfn> is a file
(in a specific new file format),
distinct from the C++ source code,
that describes how a collection of source code
is assembled to form a package.
For example, a package manifest identifies
where the interface files necessary to use the package
can be found (both header units and module interface units),
what configuration settings are necessary
to correctly build BMIs from those interface files,
the include paths and other flags that must be used in code
that directly depends on the package,
and the dependencies of the package on other packages.</p>
   <p>The manifest describes the specific instance of the package
as installed on the system.
Dependencies would typically be described by a file system path
to the package manifest files corresponding to those dependency packages.
To this end, package manifest files may need to be distributed as
"skeleton" files that are configured to contain the correct paths
at installation time.</p>
   <p>Generation of a package manifest file will in general need information from
multiple sources.</p>
   <div class="example" id="example-e18c2421">
    <a class="self-link" href="#example-e18c2421"></a> A package manifest file for a <code class="highlight"><c- p>.</c-><c- n>deb</c-></code> package on a Debian system might be
generated as follows: 
    <ul>
     <li data-md>
      <p>The author of the source package writes a skeleton package manifest
file describing properties of the package that do not depend on how
it is configured or installed.</p>
     <li data-md>
      <p>The configure script of the package extends the skeleton manifest file
to describe the concrete configured dependencies and some of the
build flags.</p>
     <li data-md>
      <p>The <code class="highlight"><c- n>install</c-></code> stage of the package installs a package manifest file
alongside the contents of the package, with the paths in the manifest
file describing the installed locations of the package’s contents.</p>
     <li data-md>
      <p>The <code class="highlight"><c- p>.</c-><c- n>deb</c-></code> build script tweaks the paths to describe the location of the
package on the target system instead of the locations on the build machine
and sets the package name to the right name for the installed package.</p>
    </ul>
   </div>
   <p>The intent is that SG15 will specify a concrete package manifest file format,
describing exactly how the requisite information will be encoded. However,
this document does not propose any concrete file format for package manifests.
The author believes that a plain-text -- possibly YAML -- format, with a
suitable schema to encode all currently-known necessary information, and room
for extensibility, would likely be a reasonable choice.</p>
   <h3 class="heading settled" data-level="3.3" id="uniqueness"><span class="secno">3.3. </span><span class="content">Package names and uniqueness</span><a class="self-link" href="#uniqueness"></a></h3>
   <p>One important problem to solve is that of module name uniqueness.
Broadly-speaking, if we wish to avoid module name collisions, we need to ensure
that thre is some collision-free namespace in which module names live. Other
languages deal with this in various ways, such as:</p>
   <ul>
    <li data-md>
     <p>An external unique name assignment system can be used to generate names.
(For example, Java uses DNS as its source of uniqueness.)</p>
    <li data-md>
     <p>A language can choose One True Package System and use its package names
as the source of uniqueness. (For example, the Hackage package archive
serves this role for Haskell.)</p>
    <li data-md>
     <p>Allow customization of the search path to resolve name ambiguities. (Python
permits this.)</p>
   </ul>
   <p>This document proposes the following approach:</p>
   <ul>
    <li data-md>
     <p>Packages have <dfn data-dfn-type="dfn" data-noexport id="package-name">package name<a class="self-link" href="#package-name"></a></dfn>s that are unique on the system on
which the package resides, but not necessarily globally unique.</p>
    <li data-md>
     <p>The name of a package is determined by the process that builds and installs
the package, and <em>not</em> by the author of the package.</p>
    <li data-md>
     <p>Two same-named modules provided by different packages are nonetheless
different modules (and hence there are no linker-level collisions between
modules with the same name in different packages).</p>
    <li data-md>
     <p>A package manifest can optionally specify a <dfn data-dfn-type="dfn" data-noexport id="module-name-prefix">module name prefix<a class="self-link" href="#module-name-prefix"></a></dfn> for each of its dependencies. This prefix specifies how the dependency’s
modules will be named within the depending module. This allows two
same-named modules from different packages to be imported into the same
source file.</p>
   </ul>
   <div class="example" id="example-3546a93f">
    <a class="self-link" href="#example-3546a93f"></a> Suppose that a project depends on two packages, YouEye and Fizix. Configuration
of the project resolves those dependencies as follows: 
    <ul>
     <li data-md>
      <p>YouEye’s package manifest is <code class="highlight"><c- o>/</c-><c- n>usr</c-><c- o>/</c-><c- n>share</c-><c- o>/</c-><c- n>youeye</c-><c- o>/</c-><c- n>youeye</c-><c- p>.</c-><c- n>cpkg</c-></code>, which says the
package name is <code class="highlight"><c- nl>sys</c-><c- p>:</c-><c- n>youeye</c-><c- o>-</c-><c- mf>3.4</c-></code>. (This package was installed by the system’s
package manager, so the system’s package manager is responsible for picking
a unique name for the package, and it picked a name based on the package
manager’s name for the package.)</p>
     <li data-md>
      <p>Fizix’s package manifest is <code class="highlight"><c- o>/</c-><c- n>home</c-><c- o>/</c-><c- n>myuser</c-><c- o>/</c-><c- n>fizix</c-><c- o>/</c-><c- n>fizix</c-><c- p>.</c-><c- n>cpkg</c-></code>, which says the
package name is <code class="highlight"><c- nl>user</c-><c- p>:</c-><c- n>fixiz</c-></code>. (This package was installed by the user, so
the user is responsible for picking a unique name for the package. They
accepted the default package name suggested by Fizix’s <code class="highlight"><c- n>configure</c-></code>A) script.</p>
    </ul>
    <p>The project specifies a module name prefix for its YouEye dependency of <code class="highlight"><c- n>deps</c-><c- p>.</c-><c- n>youeye</c-></code> and a module name prefix for its Fizix dependency of <code class="highlight"><c- n>deps</c-><c- p>.</c-><c- n>fizix</c-></code>. Code in the project can then import modules from both
dependencies as:</p>
<pre class="highlight"><c- k>export</c-> <c- n>module</c-> <c- n>mylib</c-><c- p>;</c->
<c- n>import</c-> <c- n>deps</c-><c- p>.</c-><c- n>youeye</c-><c- p>.</c-><c- n>widgets</c-><c- p>.</c-><c- n>box</c-><c- p>;</c-> <c- c1>// import widgets.box from sys:youeye-3.4</c->
<c- n>import</c-> <c- n>deps</c-><c- p>.</c-><c- n>fizix</c-><c- p>.</c-><c- n>widgets</c-><c- p>.</c-><c- n>box</c-><c- p>;</c->  <c- c1>// import widgets.box from user:fizix-4.0</c->
</pre>
    <p>The package manifest for this project would describe the dependency on the
package manifests for YouEye and Fizix, along with the module import prefixes,
so that a consumer of this project can compile a BMI from its module interface.</p>
   </div>
   <h3 class="heading settled" data-level="3.4" id="linkage"><span class="secno">3.4. </span><span class="content">Package names and linkage</span><a class="self-link" href="#linkage"></a></h3>
   <p>Because we require that modules in different packages are different modules
even if they have the same module name, we need a mechanism for the linker
to tell symbols from the two modules apart. This can be accomplished using
the same techniques that are used to ensure that entities from different
modules that have the same name are distinguished (eg, by name mangling),
or by using another technique, such as:</p>
   <ul>
    <li data-md>
     <p>On ELF targets, use of symbol versioning information</p>
    <li data-md>
     <p>On MachO targets, use of two-level namespacing</p>
    <li data-md>
     <p>On PE/COFF targets, symbols from distinct <code class="highlight"><c- p>.</c-><c- n>dll</c-></code>s can have the same name
without collision</p>
   </ul>
   <p>Note that the allowance of module name collisions between distinct packages
permits multiple versions of a library to be used within a program (as part
of multiple distinct packages). This may be inadvisable in some cases (for
example, a "global" registry from package <code class="highlight"><c- n>foo</c-><c- o>-</c-><c- mf>1.4</c-></code> would not list entities
registered with package <code class="highlight"><c- n>foo</c-><c- o>-</c-><c- mf>1.5</c-></code>) and some way to disallow that as optional
"conflict" information in the package manifest may be useful.</p>
   <h3 class="heading settled" data-level="3.5" id="convention"><span class="secno">3.5. </span><span class="content">Package name conventions</span><a class="self-link" href="#convention"></a></h3>
   <p>We propose the following strawman package naming convention:</p>
   <ul>
    <li data-md>
     <p>A package name is a <code class="highlight"><c- o>:</c-></code>-separated sequence of name pieces, where each level
before the last describes a system that guarantees the uniqueness of the
name.</p>
    <li data-md>
     <p>Names of the form <code class="highlight"><c- nl>sys</c-><c- p>:</c-><c- o>&lt;</c-><c- n>name</c-><c- o>></c-></code> are reserved for the system’s package
manager. The package name will generally correspond with the name assigned
by that package manager.</p>
    <li data-md>
     <p>Names of the form <code class="highlight"><c- nl>user</c-><c- p>:</c-><c- o>&lt;</c-><c- n>name</c-><c- o>></c-></code> are reserved for the case where the end-user
is responsible for ensuring uniqueness; this should be the default for
packages built from source repositories.</p>
    <li data-md>
     <p>Otherwise, responsibility for uniqueness of names in the top-level namespace
lies with the administrator of the system in question. For example, if the
system administrator installs Homebrew in <code class="highlight"><c- o>/</c-><c- n>usr</c-><c- o>/</c-><c- n>local</c-></code>, they might assign it <code class="highlight"><c- nl>brew</c-><c- p>:</c-></code> as a prefix for packages that Homebrew installs, but if a user
installs Homebrew into their home directory, it could use <code class="highlight"><c- nl>user</c-><c- p>:</c-><c- n>brew</c-><c- o>-</c-><c- mf>2.1.5</c-><c- o>:</c-></code> as its package name prefix.</p>
   </ul>
   <h2 class="heading settled" data-level="4" id="consequences"><span class="secno">4. </span><span class="content">Consequences</span><a class="self-link" href="#consequences"></a></h2>
   <h3 class="heading settled" data-level="4.1" id="authors"><span class="secno">4.1. </span><span class="content">For C++ library authors</span><a class="self-link" href="#authors"></a></h3>
   <p>Your build system will need to be extended to produce a package manifest file
describing your package and its dependencies. Your build configuration system
(<code class="highlight"><c- n>configure</c-></code> script, or meta-build system, or...) will need to know how to find
the package manifest files for your direct dependencies (or how to ask the user
to say where they are).</p>
   <p>You can continue to build your code however you like, so long as you use the
compilation flags required by your dependencies (much like the status quo).</p>
   <h3 class="heading settled" data-level="4.2" id="packagers"><span class="secno">4.2. </span><span class="content">For C++ library packagers</span><a class="self-link" href="#packagers"></a></h3>
   <p>You will need to ensure that package manifest files exist (and may need to
author such files for, say, C libraries that provide header files that should
be consumed as header units) and that the package names used by them are unique.</p>
   <h3 class="heading settled" data-level="4.3" id="build-system"><span class="secno">4.3. </span><span class="content">For C++ build system vendors</span><a class="self-link" href="#build-system"></a></h3>
   <p>You will need to parse package manifest files, and figure out suitable build
rules and compiler flags for a package’s transitive dependencies. You will need
to cause the necessary .BMI files to be built as inputs to their consumers.</p>
   <p>You will need to produce package manifest files for libraries that you build
and install, so that those libraries can be consumed by downstream builds.</p>
   <h3 class="heading settled" data-level="4.4" id="compilers"><span class="secno">4.4. </span><span class="content">For C++ compiler vendors</span><a class="self-link" href="#compilers"></a></h3>
   <p>You have options:</p>
   <ul>
    <li data-md>
     <p>You could do nothing and expect the build system to take care of everything
for you and provide you with all the BMIs you need</p>
    <li data-md>
     <p>You could provide a module-mapper-style interface that can talk to a build
system component that uses package manifest files to determine how to build
BMI files on demand</p>
    <li data-md>
     <p>You could accept and parse package manifest files yourself, and implicitly
build BMI files on demand</p>
   </ul>
   <p>All of these options might make sense in different scenarios.</p>
   <h3 class="heading settled" data-level="4.5" id="tools"><span class="secno">4.5. </span><span class="content">For C++ tool vendors</span><a class="self-link" href="#tools"></a></h3>
   <p>You will probably want to be given the package manifest files of dependencies
of any particular compilation. With those and the compilation command, you
have sufficient information to parse and process the module interface units
of dependencies of the current compilation without needing to understand
the formats of BMI files or how they are built.</p>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don’t scroll to compensate for the ToC if we’re above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don’t know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn’t exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn’t standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don’t have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we’re at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can’t find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="index"><span class="content">Index</span><a class="self-link" href="#index"></a></h2>
  <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="content">Terms defined by this specification</span><a class="self-link" href="#index-defined-here"></a></h3>
  <ul class="index">
   <li><a href="#module-name-prefix">module name prefix</a><span>, in §3.3</span>
   <li><a href="#package①">package</a><span>, in §3.1</span>
   <li><a href="#package-manifest">package manifest</a><span>, in §3.2</span>
   <li><a href="#package-name">package name</a><span>, in §3.3</span>
  </ul>
