Skip to content
Bret Brown edited this page Mar 3, 2024 · 13 revisions

Welcome to the CPS wiki!

Hi! Thanks for your interest into the Common Package Specification (CPS). These documents are intended to supplement the specification itself with community-editable tutorials, guides, and other explanations.

How-To Guides

Specific steps to solve specific problems!

Cookbook

How do I write a CPS file for a given type of project?

Single Static Library

In a file called fmt.cps:

{
  "name": "fmt",
  "description": "An open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams.",
  "license": "MIT",
  "version": "10.2.1",
  "default_components": [ "fmt" ],
  "components": {
    "fmt": {
      "type": "archive",
      "definitions": ["FMT_HEADER_ONLY=0"],
      "requires": [],
      "includes": "@prefix@/include",
      "location": "@prefix@/lib64/libfmt.a"
    }
  }
}

Note:

  • The library would be of the archive type.
  • The location is the location of the library binary file.
  • The "header-only" preprocessor definition is explicitly disabled.

Single Shared Library

In a file called fmt.cps:

{
  "name": "fmt",
  "description": "An open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams.",
  "license": "MIT",
  "version": "10.2.1",
  "default_components": [ "fmt" ],
  "components": {
    "fmt": {
      "type": "dylib",
      "definitions": ["FMT_HEADER_ONLY=0"],
      "requires": [],
      "includes": "@prefix@/include",
      "location": "@prefix@/lib64/libfmt.so"
    }
  }
}

Note:

  • The library would be of the dylib type.
  • The location is the location of the library to be linked in downstream projects.
  • The "header-only" preprocessor definition is explicitly disabled.
  • TODO: What about RUNPATH?

Single Header-Only Library

In a file called fmt.cps:

{
  "name": "fmt",
  "description": "An open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams.",
  "license": "MIT",
  "version": "10.2.1",
  "default_components": [ "fmt" ],
  "components": {
    "fmt": {
      "type": "interface",
      "definitions": ["FMT_HEADER_ONLY=1"],
      "requires": [],
      "includes": "@prefix@/include",
    }
  }
}

Note:

  • The library would be of the interface type.
  • For this library, a different preprocessor definition for FMT_HEADER_ONLY is needed.
  • There is no location field provided.

Library Providing Both Shared and Static Options

In a file called fmt.cps:

{
  "name": "fmt",
  "description": "An open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams.",
  "license": "MIT",
  "version": "10.2.1",
  "default_components": [ ":shared" ],
  "components": {
    "shared": {
      "type": "dylib",
      "definitions": ["FMT_HEADER_ONLY=0"],
      "requires": [],
      "includes": "@prefix@/include",
      "location": "@prefix@/lib64/libfmt.so"
    },
    "static": {
      "type": "archive",
      "definitions": ["FMT_HEADER_ONLY=0"],
      "requires": [],
      "includes": "@prefix@/include",
      "location": "@prefix@/lib64/libfmt.a"
    }
  }
}

Note:

  • There are two "components", one for the static version of the library and one for the shared version.
  • The shared version of the library is the default version in this arrangement, but it's possible to specify otherwise.
  • See the simple static and shared examples for notes on specific fields.
  • TODO: What about RUNPATH?
  • TODO: Do the static and shared versions conflict?

Explanations

Concepts, context, and other ways to grow understanding.

Motivation

See the CppCon 2023 talk called Libraries: A First Step Toward Standard C++ Dependency Management by Bill Hoffman and Bret Brown to understand the motivation and goals for CPS.

In short, CPS attempts to be a metadata file format to allow better interoperability across the build systems of different projects. It's important to have specific interfaces and protocols for how projects cooperate because natively compiled languages do have nuanced requirements regarding how they are linked together. Certain decisions, as detailed as specific flags used to compile specific files, need to be communicated and followed consistently for correct and productive software development in natively compiled languages. Implications of these difficulties have been far-reaching and have held back innovation and progress in tooling, dependency management, and even a development of a robust library ecosystem.

Historically, dependency management for natively compiled languages has been painstaking and bug-prone, but CPS hopes to provide a path forward.

How to Write a CPS File

Most CPS files will be simple. The first examples in the CPS Cookbook should be the most common examples, especially as the CPS ecosystem develops.

The primary purpose of a CPS file is to provide a defined schema for describing intention of the original authors and packagers of a library. The files should objectively describe the library as deployed. This will primarily consist of describing built files on disk, how they were built, what headers they provide, and what dependencies that library exposes to consumers.

While there are worse and better ways to build and package libraries, CPS exists partly to describe even mistakes accurately. For instance, it is possible to construct a cyclic dependency graph with CPS. It is wise to avoid cyclic library dependencies, but the CPS project values adaptability of its metadata over perfection. It is expected that tools will develop to help clearly identify problems such as cycles in dependency graphs because CPS data will exist to make that activity possible.


Reference Documentation

Facts, specifics, and other information

Reference documentation for CPS is maintained in the CPS specification. Since precision and review are important to maintaining a specification, those documents are maintained using a more structured pull request workflow. Please use PRs and issues on the CPS repo itself to contribute to the CPS specification.


Contributors' Guide

It can be challenging to write documentation that serves all purposes for all readers. The documentation for CPS is instead structured into the documentation system described by Divio. It's expected that approach will be more approachable both for readers and for contributors to the documentation. If you have ideas, questions, or concerns, please open an issue on this repo describing what you expected and what happened instead.

Clone this wiki locally