-
Notifications
You must be signed in to change notification settings - Fork 1
Welcome
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.
Specific steps to solve specific problems!
How do I write a CPS file for a given type of project?
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.
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?
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.
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?
Concepts, context, and other ways to grow understanding.
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.
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.
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.
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.