The problem
A C++ project is usually described in a second language, and a target sees whatever happens to be installed on the machine that builds it.
One package.cpp per project
Describe a project in a package.cpp. cxpm builds, tests, packs and installs it, and fetches what it depends on from git repositories or from a package index.
Experimental and at an early stage · it already builds, tests, packs and installs itself.
$ cxpm cxpm — index https://01.dev.soft-forge.dev/cxpm/index # help lists the commands, Tab completes, Ctrl-D leaves. cxpm demo> search cx cxpm 0.2.0 A package manager and build tool for C and C++ cxpm demo> dependency add zlib@>=1.2 Added zlib >= 1.2 to package.cpp cxpm demo> build cxpm demo> publish
Why cxpm
For people who write C and C++ and want one tool between the source and an installed package: no separate build language, no generator step, and dependencies that are declared instead of found by accident.
A C++ project is usually described in a second language, and a target sees whatever happens to be installed on the machine that builds it.
A project is described in a package.cpp, as Swift does with Package.swift. A package.json with the same fields works where no C++ is wanted.
A target gets include paths and libraries from the dependencies it declares, and from nowhere else. Builds run against a sysroot.
Another project of the same workspace, a git repository, a package the index publishes, or a package of the sysroot.
fetch, configure, build, test, pack, install and uninstall. Each runs the stages before it that it needs. Packages are archives, or pacman, rpm and deb packages.
The index maps a name and a version to a commit of a repository. Nothing but that entry is uploaded; the code stays in the repository.
Walkthrough
Four steps, each one a command you can run today.
cxpm project create writes a package.cpp and a first source. The manifest is ordinary C++: one target, with its name, version, type, sources and dependencies.
$ cxpm project create demo $ cd demo // package.cpp auto target = Target() .name_set("demo") .version_set("0.1.0") .type_set("executable") .sources_append({"src/*.cpp"}) .create(); auto project = Project().target_set(target).create();
Everything a project produces is under .cxpm/. cxpm test builds the project and then builds and runs its tests projects. cxpm install packs it and installs the package with the toolchain's package manager.
$ cxpm build $ cxpm test $ cxpm pack --package-manager rpm $ cxpm install --prefix ~/.local
cxpm dependency add writes the dependency into the manifest and fetches it. A name is looked up in the index; dependency remove, list and sync do the rest.
$ cxpm dependency add fmt $ cxpm dependency add "zlib@>=1.2" $ cxpm dependency add https://example.org/team/json.git#v3 $ cxpm dependency list fmt >= 10.2.0 zlib >= 1.2 json https://example.org/team/json.git#v3
Log in to the index once, by confirming a code on Soft Forge Payments, then publish from the top of the repository. cxpm sends the name, the version, the repository's address and the commit.
$ cxpm login $ cxpm whoami $ cxpm publish $ cxpm search greeter
Reference
cxpm help <command> shows a command's options.
| fetch | Downloads the dependencies, resolves the ones the index publishes and pins them in .cxpm/lock.json. |
|---|---|
| configure | Resolves the toolchain and the dependencies again. |
| build, test | Builds a project; builds and runs its tests projects. |
| pack, install, uninstall | Packs a project for a package manager, installs the package, removes it. |
| dependency add | remove | list | sync | Edits the dependencies in the manifest and fetches them. |
| search | Lists the packages of the index, or the ones matching a text. |
| login, logout, whoami | Stores, forgets and shows the account used with an index. |
| publish | Publishes the project's version as a commit of its repository. |
| project create, generate | Creates a project; writes a starter manifest. |
| repl | Opens a session over these commands. |
| serve | Serves a package index over HTTP. |
Install
Needs a C++23 compiler (GCC 14 or newer), pkg-config and git. bwrap is optional: with it, manifests and build steps run confined.
$ git clone --recurse-submodules https://github.com/arthurafarias/cxpm $ cd cxpm $ ./cxpm-build.sh --install --prefix ~/.local # or as a package of your distribution $ ./cxpm-build.sh --prefix /usr --package-manager rpm $ sudo rpm -i .cxpm/packages/*.rpm
One manifest per project, dependencies that are declared, and a package index that points at commits.