<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <meta name="title" content="C++ Dependency Management: Package Consumption vs Development"/>

  <title>C++ Dependency Management: Package Consumption vs Development</title>

  <style type="text/css">

html
{
  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
  font-weight: normal;
  font-size: 18px;
  line-height: 1.4em;
  letter-spacing: 0.01em;

  color: #292929;
}

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

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

/*
 * Header (optional).
 */

#header-bar
{
  width: 100%;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/*
 * Content.
 */

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

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

/*
 * Footer (optional).
 */

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

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

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

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

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

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

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

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

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

/*
 * Common elements.
 */

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

/* Notes. */

.note
{
  color: #606060;
}

div.note
{
  margin: 1em 0 1em 0;

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

  page-break-inside: avoid;
}

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

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

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

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

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

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

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

pre {white-space: pre-wrap;}

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

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


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


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

/*
code::before
{
  letter-spacing: -0.2em;
  content: "\00a0";
}

code::after
{
  letter-spacing: -0.2em;
  content: "\00a0";
}
*/


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

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

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

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

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

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

/* Title page */

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

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

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

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

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

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

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

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

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

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

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


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

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

  table-layout: fixed;

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

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

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

  width: 7em;
}
.proplist th:after {content: ":";}
  </style>

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

  <div id="titlepage">
    <div class="title">C++ Dependency Management:<br/>Package Consumption vs Development</div>

    <table class="proplist">
      <tbody>
	<tr><th>Document</th><td><a href="https://wg21.link/P1067R0">P1067R0</a></td></tr>
	<tr><th>Audience</th><td>SG15</td></tr>
	<tr><th>Authors</th><td>Boris Kolpackov</td></tr>
	<tr><th>Reply-To</th><td>boris@codesynthesis.com</td></tr>
	<tr><th>Date</th><td>2018-05-04</td></tr>
      </tbody>
    </table>
  </div>
  <h2 id="abstract">Abstract</h2>

  <p><i>Today's C++ package managers focus on package consumption leaving the
  question of what happens during the package development largely unanswered.
  In this presentation I would like to demonstrate the dependency management
  workflow focused on development (as opposed to consumption) that we have
  implemented in the <a href="https://build2.org"><code>build2</code></a>
  toolchain.</i></p>

  <h2 id="background">Background</h2>

  <p>Current C++ package dependency managers provide roughly the same
  functionality: there is a repository of <i>released</i> packages that may
  depend on each other and which the user can retrieve and install with the
  package manager making sure all the dependencies are satisfied. In other
  words, these package managers are <i>consumption</i> tools with the
  <i>dependency management</i> functionality boiling down to satisfying
  dependencies of the packages being consumed.</p>

  <p>The question is then what happens between the releases of these packages?
  Or, in other words, how are they developed, tested, and delivered?
  Currently, the answer is <i>painfully</i> (and rarely by mere mortals).</p>

  <p>At the same time, languages competing with C++ show that the state of the
  art has moved on (see Rust's <a
  href="https://doc.rust-lang.org/cargo/guide/dependencies.html"><code>cargo</code></a>,
  Go's <a
  href="https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527"><code>dep</code>
  design paper</a> and, more recently, <a
  href="https://research.swtch.com/vgo"><code>vgo</code></a>). As their
  experience demonstrate, a package manager alone is not sufficient: we also
  need support for managing dependencies of a project during development
  &#8211; a tool often referred to as the <i>project dependency
  manager</i>.</p>

  <p>And the <i>dependency management</i> functionality in this context is
  quite a bit different: we are talking about adding and removing dependencies
  (to/from the project's <code>manifest</code> and propagating the result to
  its build configurations) as well as managing their upgrades and downgrades
  all while making sure the precise set of dependencies can be reproduced by
  everyone else (by storing their exact versions in the project's
  <code>lockfile</code>).</p>

  <p>It is not hard to see that a project dependency manager can be naturally
  built on top of the package dependency manager. In fact, the languages
  mentioned above do not separate the two (and also combine the dependency
  manager with the build system, which has its drawbacks). There are, however,
  a number of additional requirements and challenges that will be hard to
  address without a well-integrated (note: <i>integrated</i>, not
  <i>combined</i>) C++ build toolchain:</p>

  <ul>
  <li>Support for automated, continuous versioning between releases.</li>

  <li>Dependence on unpackaged/unreleased revisions in version control
  repositories.</li>

  <li>Dependency auto-synchronization on build system invocations.</li>
  </ul>

</div>

</body>
</html>
