Reference
c3pm metadata
Source, toolchain, link, and native package fields under vendor.c3pm.
All c3pm-specific metadata lives under vendor.c3pm. The same field has the same meaning wherever it is valid:
| Field | Purpose | Used by |
|---|---|---|
c3.dependencies |
Maps C3 dependency names to their source locations | Projects and library manifests |
nix |
Declares native tools, libraries, propagated inputs, and local package definitions | Projects and library manifests |
registry |
Records the registry, package ID, and selected version of a registry dependency | Projects |
toolchain |
Pins the C3 compiler and nixpkgs reference | Projects |
links |
Connects project targets to native packages or other C3 project targets | Projects |
C3 dependency sources
Each entry under vendor.c3pm.c3.dependencies is a flat source object:
source |
Location fields | Other required fields |
|---|---|---|
github |
owner, repository |
rev |
git+https |
url beginning with https:// |
rev |
git+ssh |
url beginning with ssh:// |
rev |
archive+https |
url beginning with https:// |
sha256 in SRI form |
path |
path |
none |
subdir is optional for every source type. These are the only supported source-object forms.
Registry references
When c3pm dep add installs a registry package, the project’s project.json records the selected release under vendor.c3pm.registry. The entry key is the library manifest’s provides name:
{
"vendor": {
"c3pm": {
"registry": {
"raylib55": {
"registry": "default",
"package": "vendor/raylib",
"version": "5.5"
}
}
}
}
}
registry is the configured registry name, package is its namespace/name ID, and version is the exact published label. c3pm also keeps the resolved source under vendor.c3pm.c3.dependencies, so existing builds remain pinned until c3pm dep update changes them. Removing the dependency removes this reference when no target still uses it. The library’s own .c3l/manifest.json continues to describe what that library provides.
Toolchain metadata
vendor.c3pm.toolchain.c3c stores the project compiler version. vendor.c3pm.toolchain.nixpkgs stores the nixpkgs source reference. These fields belong to project.json; use the toolchain commands to inspect or change them.
Link metadata
A link connects a C3 target to an input that it must compile or link against. The input may be a native nixpkgs package, a custom Nix package, or a static or dynamic library target from another C3 project. A C3 dependency supplies source modules imported by name; a link supplies build or linker inputs.
See Linking libraries and projects for the commands that create, inspect, and remove links.
linked-libraries gives c3c the library names to pass to the linker. It is the project-file equivalent of c3c’s -l option. linker-search-paths gives the linker its search directories and corresponds to -L:
{
"linked-libraries": ["sqlite3"],
"linker-search-paths": ["/path/to/lib"]
}
This is roughly equivalent to:
c3c ... -L /path/to/lib -l sqlite3
The name sqlite3 is neither a nixpkgs package name nor a file path. The linker searches its configured directories for the platform’s matching file, such as libsqlite3.so or libsqlite3.a on Linux.
c3pm adds the link name to linked-libraries at either the project or target level. Separately, it places the selected Nix package in the generated buildInputs. Inside c3pm shell and the bundle build, Nix exposes the package’s library directories to the compiler and linker. Projects therefore do not normally need Nix-store paths in linker-search-paths.
Links live beside c3, nix, and toolchain. In this example, the server target links against protocol. c3pm fetches the remote project, builds protocol-static, imports the local Nix package definition, and propagates the result only to server:
{
"targets": {
"server": {
"type": "executable",
"linked-libraries": ["protocol"]
}
},
"vendor": {
"c3pm": {
"links": {
"protocol": {
"source": "git+ssh",
"url": "ssh://git@example.com/acme/protocol.git",
"rev": "v1.0.0",
"subdir": "project",
"c3cTarget": "protocol-static",
"nixPackage": "path:./package.nix",
"mode": "passthrough",
"forTarget": "server"
}
}
}
}
}
Nix inputs
C3 and Nix metadata answer different questions.
C3 metadata describes what the compiler needs
{
"dependencies": ["sqlite3"],
"linked-libraries": ["sqlite3"]
}
This tells C3 which source libraries and linker names the project uses.
Nix metadata describes what the build environment needs
{
"vendor": {
"c3pm": {
"nix": {
"nativeBuildInputs": ["pkg-config", "cmake"],
"buildInputs": ["sqlite", "openssl"],
"propagatedNativeBuildInputs": [],
"propagatedBuildInputs": []
}
}
}
}
The package classes are:
| Field | Purpose |
|---|---|
nativeBuildInputs |
Tools executed during the build, such as pkg-config, CMake, or code generators |
buildInputs |
Libraries and headers compiled or linked into the target, such as SQLite, OpenSSL, zlib, or SDL |
propagatedNativeBuildInputs |
Build tools that consumers of a packaged library must also receive |
propagatedBuildInputs |
Libraries that consumers inherit when using a packaged library |
Each entry is a nixpkgs attribute path rather than an arbitrary Nix expression. Both simple and nested attributes are valid:
{
"buildInputs": [
"openssl",
"xorg.libX11",
"llvmPackages.clang"
]
}
c3pm validates each attribute against the locked nixpkgs revision and emits references such as pkgs.openssl and pkgs.xorg.libX11.
c3pm gathers all four input classes from the root project and every reachable C3 dependency. It removes duplicates and provides the result to the development shell and project builder.
Linker names are not nixpkgs package names
c3pm does not guess a nixpkgs package from a C3 linker name.
For example:
"linked-libraries": ["sqlite3"]
means “pass sqlite3 to the C3 linker,” while:
"buildInputs": ["sqlite"]
means “make the nixpkgs sqlite package available to the build.”
Declare both fields when the library needs both.
Native packages outside nixpkgs
Projects and library manifests can load trusted package definitions with vendor.c3pm.nix.imports. Use an array of paths, or a single path string when there is only one definition:
{
"vendor": {
"c3pm": {
"nix": {
"imports": ["./microui.nix"]
}
}
}
}
Each import:
- must be a relative
.nixpath; - is resolved from the declaring project or
.c3ldirectory; - is evaluated with
pkgs.callPackage; - is added to
buildInputs.
Absolute paths and paths containing .. are rejected.
Unlike generated dependency nodes, each declared import is trusted executable Nix code.