wyvrnpm 2.11.0 → 2.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1914 -1905
- package/bin/{wyvrn.js → wyvrnpm.js} +31 -0
- package/cmake/cpp.cmake +7 -9
- package/cmake/functions.cmake +224 -224
- package/cmake/macros.cmake +284 -284
- package/package.json +3 -2
- package/src/auth.js +66 -66
- package/src/binary-dir.js +95 -0
- package/src/bootstrap/cookbook.js +196 -196
- package/src/bootstrap/detect.js +150 -150
- package/src/bootstrap/index.js +220 -220
- package/src/bootstrap/version.js +72 -72
- package/src/build/cache.js +344 -344
- package/src/build/clone.js +170 -170
- package/src/build/cmake.js +342 -342
- package/src/build/index.js +299 -297
- package/src/build/msvc-env.js +260 -260
- package/src/build/recipe.js +188 -188
- package/src/commands/add.js +141 -141
- package/src/commands/bootstrap.js +96 -96
- package/src/commands/build.js +482 -452
- package/src/commands/cache.js +189 -189
- package/src/commands/clean.js +80 -80
- package/src/commands/configure.js +92 -92
- package/src/commands/init.js +70 -70
- package/src/commands/install-skill.js +115 -115
- package/src/commands/install.js +730 -674
- package/src/commands/link.js +320 -320
- package/src/commands/profile.js +237 -237
- package/src/commands/publish.js +584 -555
- package/src/commands/show.js +252 -252
- package/src/commands/version.js +187 -187
- package/src/compat.js +273 -273
- package/src/conf/index.js +415 -391
- package/src/conf/namespaces.js +94 -94
- package/src/context.js +230 -230
- package/src/http-fetch.js +53 -53
- package/src/ignore.js +118 -118
- package/src/logger.js +122 -122
- package/src/options.js +303 -303
- package/src/settings-overrides.js +152 -152
- package/src/toolchain/deps.js +164 -164
- package/src/toolchain/index.js +212 -212
- package/src/toolchain/presets.js +356 -340
- package/src/toolchain/template.cmake +79 -77
- package/src/upload-built.js +265 -265
- package/src/version-range.js +301 -301
- package/src/zip-safe.js +52 -52
- package/src/zip-stream.js +126 -0
package/README.md
CHANGED
|
@@ -1,1905 +1,1914 @@
|
|
|
1
|
-
# wyvrnpm
|
|
2
|
-
|
|
3
|
-
A simple, private C++ package manager that works with any static file hosting provider — Amazon S3, a plain HTTP/HTTPS server, a local directory, or an SMB/UNC network share.
|
|
4
|
-
|
|
5
|
-
There is no central registry. You control where packages are hosted.
|
|
6
|
-
|
|
7
|
-
> **README version: 2.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Install
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install -g wyvrnpm
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Requires Node.js >= 18.
|
|
18
|
-
|
|
19
|
-
For S3 publishing, also install the AWS SDK:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm install -g @aws-sdk/client-s3 @aws-sdk/credential-providers
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## Quick Start
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
# 1. Initialise a manifest in your project
|
|
31
|
-
wyvrnpm init
|
|
32
|
-
|
|
33
|
-
# 2. Configure your package sources once
|
|
34
|
-
wyvrnpm configure add-source --kind install --name corp-s3 --url s3://my-bucket/packages --profile my-sso
|
|
35
|
-
wyvrnpm configure add-source --kind publish --name default --url s3://my-bucket/packages --profile my-sso
|
|
36
|
-
|
|
37
|
-
# 3. Detect and save your build environment as the default profile
|
|
38
|
-
wyvrnpm configure profile detect
|
|
39
|
-
|
|
40
|
-
# 4. Add dependencies (resolves latest from your configured sources)
|
|
41
|
-
wyvrnpm add zlib fmt@^10.0.0
|
|
42
|
-
|
|
43
|
-
# 5. Install dependencies (resolved against your build profile)
|
|
44
|
-
wyvrnpm install
|
|
45
|
-
|
|
46
|
-
# 6. Configure and build via the generated CMake preset
|
|
47
|
-
wyvrnpm build
|
|
48
|
-
|
|
49
|
-
# 7. Publish your package (uses the active profile automatically)
|
|
50
|
-
wyvrnpm publish
|
|
51
|
-
|
|
52
|
-
# 8. (Optional) Link local packages for development
|
|
53
|
-
cd ../my-local-lib && wyvrnpm link
|
|
54
|
-
cd ../my-app && wyvrnpm link my-local-lib
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Build Profiles
|
|
60
|
-
|
|
61
|
-
v2 introduces **build profiles** — named snapshots of your build environment (OS, architecture, compiler, C++ standard, runtime linkage). Each published binary is tagged with a profile hash so installs can resolve the correct prebuilt binary automatically.
|
|
62
|
-
|
|
63
|
-
Profile fields mirror Conan 2.0 settings:
|
|
64
|
-
|
|
65
|
-
| Field | Example values |
|
|
66
|
-
|---|---|
|
|
67
|
-
| `os` | `Windows` `Linux` `Macos` |
|
|
68
|
-
| `arch` | `x86_64` `x86` `armv8` |
|
|
69
|
-
| `compiler` | `msvc` `gcc` `clang` `apple-clang` |
|
|
70
|
-
| `compiler.version` | `193` `13` `17` |
|
|
71
|
-
| `compiler.cppstd` | `14` `17` `20` `23` |
|
|
72
|
-
| `compiler.runtime` | `dynamic` `static` *(MSVC only)* |
|
|
73
|
-
|
|
74
|
-
Profiles are stored in the platform config directory:
|
|
75
|
-
|
|
76
|
-
| Platform | Path |
|
|
77
|
-
|---|---|
|
|
78
|
-
| Windows | `%LOCALAPPDATA%\wyvrnpm\profiles\` |
|
|
79
|
-
| Linux / macOS | `~/.config/wyvrnpm/profiles/` |
|
|
80
|
-
|
|
81
|
-
### Typical profile workflow
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
# Auto-detect your current environment and save it as "default"
|
|
85
|
-
wyvrnpm configure profile detect
|
|
86
|
-
|
|
87
|
-
# Or save under a specific name (e.g. for a release build with static runtime)
|
|
88
|
-
wyvrnpm configure profile detect --name release
|
|
89
|
-
wyvrnpm configure profile set --name release --runtime static
|
|
90
|
-
|
|
91
|
-
# List all saved profiles (* marks the default)
|
|
92
|
-
wyvrnpm configure profile list
|
|
93
|
-
|
|
94
|
-
# Switch the default profile
|
|
95
|
-
wyvrnpm configure profile set-default release
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Once a default profile is saved, `install` and `publish` use it automatically — no flags required.
|
|
99
|
-
|
|
100
|
-
### Profile inheritance — `extends` (2.8.0+)
|
|
101
|
-
|
|
102
|
-
Teams often end up with a small fleet of near-duplicate profiles (`windows-msvc-debug`, `windows-msvc-release`, `windows-msvc-x86`, …) that drift over time. A profile can inherit from another via `extends`:
|
|
103
|
-
|
|
104
|
-
```json
|
|
105
|
-
{
|
|
106
|
-
"extends": "windows-msvc-base",
|
|
107
|
-
"compiler.cppstd": "23"
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Or from multiple parents (later entries override earlier):
|
|
112
|
-
|
|
113
|
-
```json
|
|
114
|
-
{
|
|
115
|
-
"extends": ["windows-base", "team-defaults"],
|
|
116
|
-
"compiler.runtime": "static"
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Rules:
|
|
121
|
-
|
|
122
|
-
- `[settings]` fields merge per-key — child wins.
|
|
123
|
-
- The `conf` block (if present) merges per-leaf — child overrides single keys without dropping siblings.
|
|
124
|
-
- Overlay value `null` explicitly unsets a parent field (Conan's `None` semantics).
|
|
125
|
-
- Inheritance cycles are detected and fail with the full trail (`alpha → beta → alpha`).
|
|
126
|
-
- Missing parent names fail fast — no silent drop.
|
|
127
|
-
- `extends` itself is stripped from the resolved profile and is **not** folded into `profileHash`, so `{ "extends": "base" }` with no overrides hashes byte-identically to `base`.
|
|
128
|
-
|
|
129
|
-
`wyvrnpm configure profile show <name>` prints the raw `extends:` chain alongside the resolved `[settings]` so you can inspect inheritance without grepping JSON.
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Commands
|
|
134
|
-
|
|
135
|
-
### `wyvrnpm init`
|
|
136
|
-
|
|
137
|
-
Creates a `wyvrn.json` manifest in the current directory.
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
wyvrnpm init
|
|
141
|
-
wyvrnpm init --root ./my-project
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
### `wyvrnpm bootstrap`
|
|
147
|
-
|
|
148
|
-
Scaffolds a first-draft `wyvrn.json` for an open-source C++ library so it can be packaged into your wyvrnpm registry with a single review pass instead of hand-writing a manifest from scratch. Clones the upstream git repo, detects `name` / `version` / `kind` from the checkout, applies known-library CMake flag hints (skip tests, skip examples, flip install gates), and prints a TODO report for everything a machine can't decide for you.
|
|
149
|
-
|
|
150
|
-
Designed for batch-converting a list of forked upstreams (fmt, spdlog, zlib, Catch2, etc.) into your private registry.
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
# Typical single-repo conversion
|
|
154
|
-
wyvrnpm bootstrap https://github.com/fmtlib/fmt.git --dest ./pkgs/fmt
|
|
155
|
-
cd ./pkgs/fmt # review wyvrn.json, settle TODOs
|
|
156
|
-
wyvrnpm install
|
|
157
|
-
wyvrnpm build --install --all-configs
|
|
158
|
-
wyvrnpm publish --source team-s3
|
|
159
|
-
|
|
160
|
-
# Override the derived name / version / kind
|
|
161
|
-
wyvrnpm bootstrap https://github.com/nlohmann/json.git \
|
|
162
|
-
--dest ./pkgs/nlohmann-json \
|
|
163
|
-
--name nlohmann-json \
|
|
164
|
-
--kind HeaderOnlyLib
|
|
165
|
-
|
|
166
|
-
# Work on a directory you already cloned
|
|
167
|
-
wyvrnpm bootstrap --no-clone --dest ./pkgs/fmt --force
|
|
168
|
-
|
|
169
|
-
# Preview without writing — TODO report only
|
|
170
|
-
wyvrnpm bootstrap https://github.com/google/re2.git --dest /tmp/re2 --dry-run
|
|
171
|
-
|
|
172
|
-
# Batch driver — one shell loop, no wyvrnpm subcommand needed
|
|
173
|
-
while read url; do
|
|
174
|
-
wyvrnpm bootstrap "$url" --dest "./pkgs/$(basename "$url" .git)" --force
|
|
175
|
-
done < urls.txt
|
|
176
|
-
# then review, build, and publish each in a loop of your own
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
**Options**
|
|
180
|
-
|
|
181
|
-
| Option | Default | Description |
|
|
182
|
-
|---|---|---|
|
|
183
|
-
| `<url>` positional | *(required)* | Upstream git URL. Accepts HTTPS or SSH form. |
|
|
184
|
-
| `--dest <dir>` | `basename(url)` | Destination directory for the clone. |
|
|
185
|
-
| `--ref <ref>` | *(remote HEAD)* | Clone at a specific branch / tag / SHA. |
|
|
186
|
-
| `--name` | *(from URL)* | Override the derived package name. |
|
|
187
|
-
| `--pkg-version` | *(nearest git tag)* | Override the version. Named oddly so yargs doesn't confuse it with the built-in `--version`. |
|
|
188
|
-
| `--kind` | *(auto-detect)* | Force `ConsoleApp` / `StaticLib` / `DynamicLib` / `HeaderOnlyLib` / etc. |
|
|
189
|
-
| `--description` | *(TODO placeholder)* | One-line description written into `wyvrn.json`. |
|
|
190
|
-
| `--no-clone` | `false` | Skip the clone step; operate on an already-populated `--dest`. |
|
|
191
|
-
| `--shallow` | `false` | `--depth 1` clone. Faster, but git tag detection degrades — pair with `--pkg-version` when using this. |
|
|
192
|
-
| `--dry-run` | `false` | Print the proposed manifest + TODOs; don't write `wyvrn.json`. |
|
|
193
|
-
| `--force` | `false` | Overwrite an existing destination and/or `wyvrn.json`. |
|
|
194
|
-
| `--format` | `text` | Output format: `text` (human) or `json` (CI — one object on stdout). |
|
|
195
|
-
|
|
196
|
-
The cookbook of per-library hints lives in [src/bootstrap/cookbook.js](src/bootstrap/cookbook.js). Current coverage is ~30 popular libraries (fmt, spdlog, nlohmann/json, yaml-cpp, zlib, Catch2, lz4, brotli, hiredis, redis-plus-plus, GLM, SQLiteCpp, re2, …). Adding a new entry is a two-line change — submit a PR.
|
|
197
|
-
|
|
198
|
-
The patterns bootstrap detects (header-only with INTERFACE target, standard CMake static lib, CMake with wyvrnpm dep, ABI-option'd lib, non-CMake upstream) are catalogued in the bundled Agent Skill at [claude/skills/wyvrnpm/references/oss-conversion-patterns.md](claude/skills/wyvrnpm/references/oss-conversion-patterns.md) — Claude reads it when you ask "how do I convert X to a wyvrnpm package?".
|
|
199
|
-
|
|
200
|
-
---
|
|
201
|
-
|
|
202
|
-
### `wyvrnpm add`
|
|
203
|
-
|
|
204
|
-
Adds one or more dependencies to `wyvrn.json` without downloading them. Useful when you know the package name but not the latest version.
|
|
205
|
-
|
|
206
|
-
- **Bare name** — resolves `latest.json` from your configured install sources and writes `"^<latest>"` (caret range, major-pinned).
|
|
207
|
-
- **`name@<version>`** — writes the given string verbatim. Accepts exact pins (`1.2.3.4`), caret/tilde ranges (`^1.2.3.4`, `~1.2.3.4`), and explicit comparators (`>=1.80.0 <2.0.0`).
|
|
208
|
-
|
|
209
|
-
If the dependency is already listed, it is replaced. When the prior entry was an object (`{ version, settings, options }`), the `settings` and `options` are preserved — only the version field is updated.
|
|
210
|
-
|
|
211
|
-
`add` does **not** run install. Chain `wyvrnpm install` afterwards to download.
|
|
212
|
-
|
|
213
|
-
```bash
|
|
214
|
-
# Resolve latest, write "^<latest>"
|
|
215
|
-
wyvrnpm add zlib
|
|
216
|
-
|
|
217
|
-
# Pin exactly
|
|
218
|
-
wyvrnpm add zlib@1.3.0.0
|
|
219
|
-
|
|
220
|
-
# Use a caret / tilde / comparator range
|
|
221
|
-
wyvrnpm add fmt@^10.0.0
|
|
222
|
-
wyvrnpm add boost@">=1.80.0 <2.0.0"
|
|
223
|
-
|
|
224
|
-
# Multiple in one call
|
|
225
|
-
wyvrnpm add zlib fmt@10.2.0.0 spdlog
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Options**
|
|
229
|
-
|
|
230
|
-
| Option | Default | Description |
|
|
231
|
-
|---|---|---|
|
|
232
|
-
| `--source` / `-s` | *(config)* | Base URL used for the `latest` lookup. Repeat for multiple. |
|
|
233
|
-
| `--platform` | `win_x64` | v1 legacy platform sub-path (used as a fallback during `latest` lookup). |
|
|
234
|
-
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
### `wyvrnpm version`
|
|
239
|
-
|
|
240
|
-
Read, set, or partially update the top-level `version` field in `wyvrn.json`. Designed for CI/CD — bumps the build component from a pipeline variable, prints the result for capture, and never touches git (CI pipelines own tagging and commits).
|
|
241
|
-
|
|
242
|
-
- **Bare** — prints the current version on stdout, naked (no `[wyvrn]` prefix), so `VER=$(wyvrnpm version)` works straight away.
|
|
243
|
-
- **Full set** — `wyvrnpm version 1.2.3.4` writes the value verbatim. Strict 4-part `x.y.z.b` validation; leading zeros and 3-part semver are rejected.
|
|
244
|
-
- **Component flags** — `--major / --minor / --patch / --build N` replace one component while leaving the others alone. Combine flags freely (`--minor 3 --build 0`).
|
|
245
|
-
- Positional and component flags are mutually exclusive — pick a mode.
|
|
246
|
-
|
|
247
|
-
```bash
|
|
248
|
-
# Read the current version (CI capture)
|
|
249
|
-
VER=$(wyvrnpm version)
|
|
250
|
-
|
|
251
|
-
# Inject the build number from a pipeline variable
|
|
252
|
-
wyvrnpm version --build "$BUILD_ID"
|
|
253
|
-
|
|
254
|
-
# Cut a minor release — reset the build component to 0
|
|
255
|
-
wyvrnpm version --minor 3 --build 0
|
|
256
|
-
|
|
257
|
-
# Set a full version verbatim
|
|
258
|
-
wyvrnpm version 2.0.0.0
|
|
259
|
-
|
|
260
|
-
# CI-friendly capture
|
|
261
|
-
wyvrnpm version --build "$BUILD_ID" --format json
|
|
262
|
-
# {"command":"version","previous":"1.2.3.4","version":"1.2.3.99","written":true,...}
|
|
263
|
-
|
|
264
|
-
# Preview without writing
|
|
265
|
-
wyvrnpm version --build 99 --dry-run
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
**Options**
|
|
269
|
-
|
|
270
|
-
| Option | Default | Description |
|
|
271
|
-
|---|---|---|
|
|
272
|
-
| `<newVersion>` positional | — | Full 4-part version (e.g. `1.2.3.4`). Mutex with `--major/--minor/--patch/--build`. |
|
|
273
|
-
| `--major` | — | Replace the 1st component. |
|
|
274
|
-
| `--minor` | — | Replace the 2nd component. |
|
|
275
|
-
| `--patch` | — | Replace the 3rd component. |
|
|
276
|
-
| `--build` | — | Replace the 4th component (typical CI use). |
|
|
277
|
-
| `--dry-run` | `false` | Compute and print the proposed version without writing. |
|
|
278
|
-
| `--format` | `text` | Output format: `text` (human) or `json` (CI — single object on stdout). |
|
|
279
|
-
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
280
|
-
|
|
281
|
-
---
|
|
282
|
-
|
|
283
|
-
### `wyvrnpm install`
|
|
284
|
-
|
|
285
|
-
Resolves the full dependency graph and downloads all packages.
|
|
286
|
-
|
|
287
|
-
**Source priority:** CLI `--source` values are used if provided. If omitted, sources are loaded from the [configuration file](#configuration-file).
|
|
288
|
-
|
|
289
|
-
**Profile resolution:** `--profile` selects the named build profile. If omitted, `config.defaultProfile` is used, falling back to `"default"`. v2 binaries are resolved in this order:
|
|
290
|
-
|
|
291
|
-
1. **Exact profile-hash match** — the preferred path.
|
|
292
|
-
2. **Declarative compatibility** — each published build may advertise a `compatibility` block (e.g. "compatible with any `msvc.version ≥ 193` on `Windows/x86_64`"). The best compatible candidate is picked deterministically.
|
|
293
|
-
3. **Source build** (with `--build=missing`) — clones the package's source at the published `gitSha`, resolves its own dependencies, invokes CMake through the shared toolchain generator, and caches the result under `%LOCALAPPDATA%\wyvrnpm\bc\`. On Windows/MSVC with a Ninja or Make generator, `vcvarsall.bat` is auto-activated.
|
|
294
|
-
4. **v1 legacy path** — only when no v2 entry exists for the package at all.
|
|
295
|
-
|
|
296
|
-
The pre-2.1 "same OS + arch, any compiler" loose fallback is no longer available. Publish a build for your profile, add a declarative `compatibility` block to the recipe, or rerun with `--build=missing` to source-build.
|
|
297
|
-
|
|
298
|
-
```bash
|
|
299
|
-
# Use configured sources and the default build profile
|
|
300
|
-
wyvrnpm install
|
|
301
|
-
|
|
302
|
-
# Use a specific named profile
|
|
303
|
-
wyvrnpm install --profile release
|
|
304
|
-
|
|
305
|
-
# Override with explicit sources
|
|
306
|
-
wyvrnpm install --source https://pkg.example.com/cpp
|
|
307
|
-
|
|
308
|
-
# Multiple sources — tried in order, first to respond wins
|
|
309
|
-
wyvrnpm install \
|
|
310
|
-
--source https://primary.example.com/cpp \
|
|
311
|
-
--source https://mirror.example.com/cpp
|
|
312
|
-
|
|
313
|
-
# Build any missing binary from source
|
|
314
|
-
wyvrnpm install --build=missing
|
|
315
|
-
|
|
316
|
-
# Force every dep to be rebuilt from source (debugging / reproducibility check)
|
|
317
|
-
wyvrnpm install --build=always
|
|
318
|
-
|
|
319
|
-
# Print the resolved install plan WITHOUT downloading (CI-friendly with --format=json)
|
|
320
|
-
wyvrnpm install --dry-run
|
|
321
|
-
wyvrnpm install --dry-run --format=json
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
**Options**
|
|
325
|
-
|
|
326
|
-
| Option | Default | Description |
|
|
327
|
-
|---|---|---|
|
|
328
|
-
| `--source` / `-s` | *(config)* | Base URL of a package source. Repeat for multiple. Overrides config when provided. |
|
|
329
|
-
| `--profile` / `-p` | *(config / "default")* | Named build profile to use for v2 binary resolution. |
|
|
330
|
-
| `--build` | `never` | Resolution mode when no exact or compatible profile match exists: `never` fails; `missing` clones and builds the package from its published `gitRepo@gitSha`; `always` rebuilds even when a binary exists. |
|
|
331
|
-
| `--platform` | `win_x64` | v1 legacy platform sub-path (used as a fallback when no v2 binary is found). |
|
|
332
|
-
| `--timeout` | `300` | HTTP request timeout in seconds. |
|
|
333
|
-
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
334
|
-
| `--root` | `./` | Project root (packages extracted to `{root}/wyvrn_internal/`). |
|
|
335
|
-
| `--dry-run` | `false` | Run the resolver + profile/options math, print the install plan, and exit. No download, no `wyvrn.lock`, no `wyvrn_internal/`, no toolchain. Combine with `--format=json` for CI ingestion (payload carries `command: "install-dry-run"`). |
|
|
336
|
-
| `--conf` | — | Non-ABI build-time override. Repeatable. Format: `<namespace.leaf>=<value>` — e.g. `--conf cmake.cache.CHROMA_ENABLE_TEST=ON`. Layered: CLI > `wyvrn.local.json` > named-profile `conf` > recipe. Does **not** fold into `profileHash`. See [Build-time configuration (`conf`)](#build-time-configuration-conf). |
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
- `wyvrn_internal/
|
|
344
|
-
- `wyvrn_internal/
|
|
345
|
-
- `
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
| `
|
|
353
|
-
| `
|
|
354
|
-
| `
|
|
355
|
-
| `
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
| `
|
|
365
|
-
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
WYVRN_APPLY_ARCH_SUFFIX(String
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
#
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
wyvrnpm build --clean
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
wyvrnpm build --install
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
| `--
|
|
429
|
-
| `--
|
|
430
|
-
| `--
|
|
431
|
-
| `--
|
|
432
|
-
| `--
|
|
433
|
-
| `--
|
|
434
|
-
| `--
|
|
435
|
-
| `--
|
|
436
|
-
| `--install
|
|
437
|
-
| `--
|
|
438
|
-
| `--
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
**
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
#
|
|
468
|
-
wyvrnpm publish --source https://pkg.corp.com --token
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
|
490
|
-
|
|
491
|
-
| `--
|
|
492
|
-
| `--
|
|
493
|
-
| `--
|
|
494
|
-
| `--
|
|
495
|
-
| `--
|
|
496
|
-
| `--
|
|
497
|
-
| `--
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
/
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
|
585
|
-
|
|
586
|
-
| `--
|
|
587
|
-
| `--
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
- **
|
|
620
|
-
- **
|
|
621
|
-
- **
|
|
622
|
-
- **
|
|
623
|
-
- **
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
|
632
|
-
|
|
633
|
-
|
|
|
634
|
-
| `--
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
|
660
|
-
|
|
661
|
-
| `--
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
Link a
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
#
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
-
|
|
724
|
-
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
|
750
|
-
|
|
751
|
-
| `--
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
--
|
|
784
|
-
--
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
--
|
|
791
|
-
--
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
--
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
--
|
|
804
|
-
--
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
|
812
|
-
|
|
813
|
-
| `--
|
|
814
|
-
| `--
|
|
815
|
-
| `--
|
|
816
|
-
| `--
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
|
865
|
-
|
|
866
|
-
| `--
|
|
867
|
-
| `--
|
|
868
|
-
| `--
|
|
869
|
-
| `--
|
|
870
|
-
| `--
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
wyvrnpm
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
"
|
|
891
|
-
"
|
|
892
|
-
"
|
|
893
|
-
"
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
"
|
|
898
|
-
"
|
|
899
|
-
"
|
|
900
|
-
"
|
|
901
|
-
"
|
|
902
|
-
"
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
- `
|
|
913
|
-
- `
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
"
|
|
922
|
-
"
|
|
923
|
-
"
|
|
924
|
-
"
|
|
925
|
-
"
|
|
926
|
-
"
|
|
927
|
-
"
|
|
928
|
-
"
|
|
929
|
-
"
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
"
|
|
940
|
-
"
|
|
941
|
-
"
|
|
942
|
-
"
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
"
|
|
950
|
-
"
|
|
951
|
-
"
|
|
952
|
-
"
|
|
953
|
-
"
|
|
954
|
-
"
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
"
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
"
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
"
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
The `
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
|
1024
|
-
|
|
1025
|
-
| **
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
https://s3.amazonaws.com/
|
|
1036
|
-
https://s3.us-east-1.amazonaws.com/
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
//
|
|
1077
|
-
//
|
|
1078
|
-
// options.
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
const
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
{source}/v2/{name}/
|
|
1115
|
-
{source}/v2/{name}/
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
"
|
|
1152
|
-
"
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
"
|
|
1169
|
-
"
|
|
1170
|
-
"
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
**`
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
|
1193
|
-
|
|
1194
|
-
| `"
|
|
1195
|
-
| `"
|
|
1196
|
-
| `"
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
**
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
- **
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
"
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
"boost-
|
|
1250
|
-
"
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
-
|
|
1264
|
-
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
"
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
"
|
|
1282
|
-
},
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
"-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
-
|
|
1298
|
-
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
**
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
"
|
|
1335
|
-
"
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
"
|
|
1339
|
-
"
|
|
1340
|
-
"
|
|
1341
|
-
"
|
|
1342
|
-
"
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
|
1350
|
-
|
|
1351
|
-
| `
|
|
1352
|
-
| `
|
|
1353
|
-
| `
|
|
1354
|
-
| `
|
|
1355
|
-
| `
|
|
1356
|
-
| `
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
|
1369
|
-
|
|
1370
|
-
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
│ ─────
|
|
1381
|
-
│
|
|
1382
|
-
│ ─────
|
|
1383
|
-
│
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
"
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
"
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
wyvrnpm
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
```
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
###
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
wyvrnpm
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
"
|
|
1770
|
-
"
|
|
1771
|
-
"
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
}
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
**
|
|
1811
|
-
|
|
1812
|
-
|
|
|
1813
|
-
|---|---|
|
|
1814
|
-
| `
|
|
1815
|
-
| `
|
|
1816
|
-
| `
|
|
1817
|
-
| `
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
wyvrnpm build --install --install
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
#
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
#
|
|
1859
|
-
wyvrnpm build --install --
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
### `--install
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1
|
+
# wyvrnpm
|
|
2
|
+
|
|
3
|
+
A simple, private C++ package manager that works with any static file hosting provider — Amazon S3, a plain HTTP/HTTPS server, a local directory, or an SMB/UNC network share.
|
|
4
|
+
|
|
5
|
+
There is no central registry. You control where packages are hosted.
|
|
6
|
+
|
|
7
|
+
> **README version: 2.12.3** — Highlights since 2.8.3: profile's `compiler.cppstd` is now authoritative for the toolchain — `CMAKE_CXX_STANDARD` is set unconditionally before `project()` and `cpp.cmake` no longer touches it post-`project()`, so a `-DCMAKE_CXX_STANDARD=23` on the cmake CLI cannot defeat a `cppstd=20` profile; `wyvrnpm install` exits non-zero on partial failure (sha256-mismatch, extract-failed, no-exact-match, source-build-failed, not-found) and prints a per-dep failure summary instead of misreporting "Done — N installed"; streaming publish via `archiver` (handles >2 GiB artefacts that `adm-zip` choked on — e.g. gRPC's `RelWithDebInfo` static libs); `--build-dir <path>` + `wyvrn.local.json:binaryDirRoot` to sidestep `build/` case-insensitive-FS collisions on repos with a Bazel/Buck `BUILD` file at the root (gRPC, …); `wyvrnpm version` to read / set / partially update the top-level `version` field from CI pipelines (`wyvrnpm version --build "$BUILD_ID"`); `wyvrnpm bootstrap <git-url>` to scaffold a first-draft `wyvrn.json` for OSS C++ libraries (fmt, spdlog, zlib, …) with cookbook-driven defaults; `wyvrnpm publish --dry-run` (npm-style preview of the upload plan, plus `wouldOverwrite` flag in `--format json`); `wyvrnpm build --config Debug,Release` / `--all-configs` to build multiple configurations from a single configure; resolver hardened against the CloudFront brotli-vs-identity cache split (resolved a class of bugs where `show` listed a freshly-published version that `install` claimed didn't exist). Full list in `claude/EVALUATION.md`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g wyvrnpm
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Requires Node.js >= 18.
|
|
18
|
+
|
|
19
|
+
For S3 publishing, also install the AWS SDK:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g @aws-sdk/client-s3 @aws-sdk/credential-providers
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# 1. Initialise a manifest in your project
|
|
31
|
+
wyvrnpm init
|
|
32
|
+
|
|
33
|
+
# 2. Configure your package sources once
|
|
34
|
+
wyvrnpm configure add-source --kind install --name corp-s3 --url s3://my-bucket/packages --profile my-sso
|
|
35
|
+
wyvrnpm configure add-source --kind publish --name default --url s3://my-bucket/packages --profile my-sso
|
|
36
|
+
|
|
37
|
+
# 3. Detect and save your build environment as the default profile
|
|
38
|
+
wyvrnpm configure profile detect
|
|
39
|
+
|
|
40
|
+
# 4. Add dependencies (resolves latest from your configured sources)
|
|
41
|
+
wyvrnpm add zlib fmt@^10.0.0
|
|
42
|
+
|
|
43
|
+
# 5. Install dependencies (resolved against your build profile)
|
|
44
|
+
wyvrnpm install
|
|
45
|
+
|
|
46
|
+
# 6. Configure and build via the generated CMake preset
|
|
47
|
+
wyvrnpm build
|
|
48
|
+
|
|
49
|
+
# 7. Publish your package (uses the active profile automatically)
|
|
50
|
+
wyvrnpm publish
|
|
51
|
+
|
|
52
|
+
# 8. (Optional) Link local packages for development
|
|
53
|
+
cd ../my-local-lib && wyvrnpm link
|
|
54
|
+
cd ../my-app && wyvrnpm link my-local-lib
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Build Profiles
|
|
60
|
+
|
|
61
|
+
v2 introduces **build profiles** — named snapshots of your build environment (OS, architecture, compiler, C++ standard, runtime linkage). Each published binary is tagged with a profile hash so installs can resolve the correct prebuilt binary automatically.
|
|
62
|
+
|
|
63
|
+
Profile fields mirror Conan 2.0 settings:
|
|
64
|
+
|
|
65
|
+
| Field | Example values |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `os` | `Windows` `Linux` `Macos` |
|
|
68
|
+
| `arch` | `x86_64` `x86` `armv8` |
|
|
69
|
+
| `compiler` | `msvc` `gcc` `clang` `apple-clang` |
|
|
70
|
+
| `compiler.version` | `193` `13` `17` |
|
|
71
|
+
| `compiler.cppstd` | `14` `17` `20` `23` |
|
|
72
|
+
| `compiler.runtime` | `dynamic` `static` *(MSVC only)* |
|
|
73
|
+
|
|
74
|
+
Profiles are stored in the platform config directory:
|
|
75
|
+
|
|
76
|
+
| Platform | Path |
|
|
77
|
+
|---|---|
|
|
78
|
+
| Windows | `%LOCALAPPDATA%\wyvrnpm\profiles\` |
|
|
79
|
+
| Linux / macOS | `~/.config/wyvrnpm/profiles/` |
|
|
80
|
+
|
|
81
|
+
### Typical profile workflow
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Auto-detect your current environment and save it as "default"
|
|
85
|
+
wyvrnpm configure profile detect
|
|
86
|
+
|
|
87
|
+
# Or save under a specific name (e.g. for a release build with static runtime)
|
|
88
|
+
wyvrnpm configure profile detect --name release
|
|
89
|
+
wyvrnpm configure profile set --name release --runtime static
|
|
90
|
+
|
|
91
|
+
# List all saved profiles (* marks the default)
|
|
92
|
+
wyvrnpm configure profile list
|
|
93
|
+
|
|
94
|
+
# Switch the default profile
|
|
95
|
+
wyvrnpm configure profile set-default release
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Once a default profile is saved, `install` and `publish` use it automatically — no flags required.
|
|
99
|
+
|
|
100
|
+
### Profile inheritance — `extends` (2.8.0+)
|
|
101
|
+
|
|
102
|
+
Teams often end up with a small fleet of near-duplicate profiles (`windows-msvc-debug`, `windows-msvc-release`, `windows-msvc-x86`, …) that drift over time. A profile can inherit from another via `extends`:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"extends": "windows-msvc-base",
|
|
107
|
+
"compiler.cppstd": "23"
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Or from multiple parents (later entries override earlier):
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"extends": ["windows-base", "team-defaults"],
|
|
116
|
+
"compiler.runtime": "static"
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Rules:
|
|
121
|
+
|
|
122
|
+
- `[settings]` fields merge per-key — child wins.
|
|
123
|
+
- The `conf` block (if present) merges per-leaf — child overrides single keys without dropping siblings.
|
|
124
|
+
- Overlay value `null` explicitly unsets a parent field (Conan's `None` semantics).
|
|
125
|
+
- Inheritance cycles are detected and fail with the full trail (`alpha → beta → alpha`).
|
|
126
|
+
- Missing parent names fail fast — no silent drop.
|
|
127
|
+
- `extends` itself is stripped from the resolved profile and is **not** folded into `profileHash`, so `{ "extends": "base" }` with no overrides hashes byte-identically to `base`.
|
|
128
|
+
|
|
129
|
+
`wyvrnpm configure profile show <name>` prints the raw `extends:` chain alongside the resolved `[settings]` so you can inspect inheritance without grepping JSON.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Commands
|
|
134
|
+
|
|
135
|
+
### `wyvrnpm init`
|
|
136
|
+
|
|
137
|
+
Creates a `wyvrn.json` manifest in the current directory.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
wyvrnpm init
|
|
141
|
+
wyvrnpm init --root ./my-project
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### `wyvrnpm bootstrap`
|
|
147
|
+
|
|
148
|
+
Scaffolds a first-draft `wyvrn.json` for an open-source C++ library so it can be packaged into your wyvrnpm registry with a single review pass instead of hand-writing a manifest from scratch. Clones the upstream git repo, detects `name` / `version` / `kind` from the checkout, applies known-library CMake flag hints (skip tests, skip examples, flip install gates), and prints a TODO report for everything a machine can't decide for you.
|
|
149
|
+
|
|
150
|
+
Designed for batch-converting a list of forked upstreams (fmt, spdlog, zlib, Catch2, etc.) into your private registry.
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Typical single-repo conversion
|
|
154
|
+
wyvrnpm bootstrap https://github.com/fmtlib/fmt.git --dest ./pkgs/fmt
|
|
155
|
+
cd ./pkgs/fmt # review wyvrn.json, settle TODOs
|
|
156
|
+
wyvrnpm install
|
|
157
|
+
wyvrnpm build --install --all-configs
|
|
158
|
+
wyvrnpm publish --source team-s3
|
|
159
|
+
|
|
160
|
+
# Override the derived name / version / kind
|
|
161
|
+
wyvrnpm bootstrap https://github.com/nlohmann/json.git \
|
|
162
|
+
--dest ./pkgs/nlohmann-json \
|
|
163
|
+
--name nlohmann-json \
|
|
164
|
+
--kind HeaderOnlyLib
|
|
165
|
+
|
|
166
|
+
# Work on a directory you already cloned
|
|
167
|
+
wyvrnpm bootstrap --no-clone --dest ./pkgs/fmt --force
|
|
168
|
+
|
|
169
|
+
# Preview without writing — TODO report only
|
|
170
|
+
wyvrnpm bootstrap https://github.com/google/re2.git --dest /tmp/re2 --dry-run
|
|
171
|
+
|
|
172
|
+
# Batch driver — one shell loop, no wyvrnpm subcommand needed
|
|
173
|
+
while read url; do
|
|
174
|
+
wyvrnpm bootstrap "$url" --dest "./pkgs/$(basename "$url" .git)" --force
|
|
175
|
+
done < urls.txt
|
|
176
|
+
# then review, build, and publish each in a loop of your own
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Options**
|
|
180
|
+
|
|
181
|
+
| Option | Default | Description |
|
|
182
|
+
|---|---|---|
|
|
183
|
+
| `<url>` positional | *(required)* | Upstream git URL. Accepts HTTPS or SSH form. |
|
|
184
|
+
| `--dest <dir>` | `basename(url)` | Destination directory for the clone. |
|
|
185
|
+
| `--ref <ref>` | *(remote HEAD)* | Clone at a specific branch / tag / SHA. |
|
|
186
|
+
| `--name` | *(from URL)* | Override the derived package name. |
|
|
187
|
+
| `--pkg-version` | *(nearest git tag)* | Override the version. Named oddly so yargs doesn't confuse it with the built-in `--version`. |
|
|
188
|
+
| `--kind` | *(auto-detect)* | Force `ConsoleApp` / `StaticLib` / `DynamicLib` / `HeaderOnlyLib` / etc. |
|
|
189
|
+
| `--description` | *(TODO placeholder)* | One-line description written into `wyvrn.json`. |
|
|
190
|
+
| `--no-clone` | `false` | Skip the clone step; operate on an already-populated `--dest`. |
|
|
191
|
+
| `--shallow` | `false` | `--depth 1` clone. Faster, but git tag detection degrades — pair with `--pkg-version` when using this. |
|
|
192
|
+
| `--dry-run` | `false` | Print the proposed manifest + TODOs; don't write `wyvrn.json`. |
|
|
193
|
+
| `--force` | `false` | Overwrite an existing destination and/or `wyvrn.json`. |
|
|
194
|
+
| `--format` | `text` | Output format: `text` (human) or `json` (CI — one object on stdout). |
|
|
195
|
+
|
|
196
|
+
The cookbook of per-library hints lives in [src/bootstrap/cookbook.js](src/bootstrap/cookbook.js). Current coverage is ~30 popular libraries (fmt, spdlog, nlohmann/json, yaml-cpp, zlib, Catch2, lz4, brotli, hiredis, redis-plus-plus, GLM, SQLiteCpp, re2, …). Adding a new entry is a two-line change — submit a PR.
|
|
197
|
+
|
|
198
|
+
The patterns bootstrap detects (header-only with INTERFACE target, standard CMake static lib, CMake with wyvrnpm dep, ABI-option'd lib, non-CMake upstream) are catalogued in the bundled Agent Skill at [claude/skills/wyvrnpm/references/oss-conversion-patterns.md](claude/skills/wyvrnpm/references/oss-conversion-patterns.md) — Claude reads it when you ask "how do I convert X to a wyvrnpm package?".
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### `wyvrnpm add`
|
|
203
|
+
|
|
204
|
+
Adds one or more dependencies to `wyvrn.json` without downloading them. Useful when you know the package name but not the latest version.
|
|
205
|
+
|
|
206
|
+
- **Bare name** — resolves `latest.json` from your configured install sources and writes `"^<latest>"` (caret range, major-pinned).
|
|
207
|
+
- **`name@<version>`** — writes the given string verbatim. Accepts exact pins (`1.2.3.4`), caret/tilde ranges (`^1.2.3.4`, `~1.2.3.4`), and explicit comparators (`>=1.80.0 <2.0.0`).
|
|
208
|
+
|
|
209
|
+
If the dependency is already listed, it is replaced. When the prior entry was an object (`{ version, settings, options }`), the `settings` and `options` are preserved — only the version field is updated.
|
|
210
|
+
|
|
211
|
+
`add` does **not** run install. Chain `wyvrnpm install` afterwards to download.
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Resolve latest, write "^<latest>"
|
|
215
|
+
wyvrnpm add zlib
|
|
216
|
+
|
|
217
|
+
# Pin exactly
|
|
218
|
+
wyvrnpm add zlib@1.3.0.0
|
|
219
|
+
|
|
220
|
+
# Use a caret / tilde / comparator range
|
|
221
|
+
wyvrnpm add fmt@^10.0.0
|
|
222
|
+
wyvrnpm add boost@">=1.80.0 <2.0.0"
|
|
223
|
+
|
|
224
|
+
# Multiple in one call
|
|
225
|
+
wyvrnpm add zlib fmt@10.2.0.0 spdlog
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Options**
|
|
229
|
+
|
|
230
|
+
| Option | Default | Description |
|
|
231
|
+
|---|---|---|
|
|
232
|
+
| `--source` / `-s` | *(config)* | Base URL used for the `latest` lookup. Repeat for multiple. |
|
|
233
|
+
| `--platform` | `win_x64` | v1 legacy platform sub-path (used as a fallback during `latest` lookup). |
|
|
234
|
+
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
### `wyvrnpm version`
|
|
239
|
+
|
|
240
|
+
Read, set, or partially update the top-level `version` field in `wyvrn.json`. Designed for CI/CD — bumps the build component from a pipeline variable, prints the result for capture, and never touches git (CI pipelines own tagging and commits).
|
|
241
|
+
|
|
242
|
+
- **Bare** — prints the current version on stdout, naked (no `[wyvrn]` prefix), so `VER=$(wyvrnpm version)` works straight away.
|
|
243
|
+
- **Full set** — `wyvrnpm version 1.2.3.4` writes the value verbatim. Strict 4-part `x.y.z.b` validation; leading zeros and 3-part semver are rejected.
|
|
244
|
+
- **Component flags** — `--major / --minor / --patch / --build N` replace one component while leaving the others alone. Combine flags freely (`--minor 3 --build 0`).
|
|
245
|
+
- Positional and component flags are mutually exclusive — pick a mode.
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Read the current version (CI capture)
|
|
249
|
+
VER=$(wyvrnpm version)
|
|
250
|
+
|
|
251
|
+
# Inject the build number from a pipeline variable
|
|
252
|
+
wyvrnpm version --build "$BUILD_ID"
|
|
253
|
+
|
|
254
|
+
# Cut a minor release — reset the build component to 0
|
|
255
|
+
wyvrnpm version --minor 3 --build 0
|
|
256
|
+
|
|
257
|
+
# Set a full version verbatim
|
|
258
|
+
wyvrnpm version 2.0.0.0
|
|
259
|
+
|
|
260
|
+
# CI-friendly capture
|
|
261
|
+
wyvrnpm version --build "$BUILD_ID" --format json
|
|
262
|
+
# {"command":"version","previous":"1.2.3.4","version":"1.2.3.99","written":true,...}
|
|
263
|
+
|
|
264
|
+
# Preview without writing
|
|
265
|
+
wyvrnpm version --build 99 --dry-run
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Options**
|
|
269
|
+
|
|
270
|
+
| Option | Default | Description |
|
|
271
|
+
|---|---|---|
|
|
272
|
+
| `<newVersion>` positional | — | Full 4-part version (e.g. `1.2.3.4`). Mutex with `--major/--minor/--patch/--build`. |
|
|
273
|
+
| `--major` | — | Replace the 1st component. |
|
|
274
|
+
| `--minor` | — | Replace the 2nd component. |
|
|
275
|
+
| `--patch` | — | Replace the 3rd component. |
|
|
276
|
+
| `--build` | — | Replace the 4th component (typical CI use). |
|
|
277
|
+
| `--dry-run` | `false` | Compute and print the proposed version without writing. |
|
|
278
|
+
| `--format` | `text` | Output format: `text` (human) or `json` (CI — single object on stdout). |
|
|
279
|
+
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### `wyvrnpm install`
|
|
284
|
+
|
|
285
|
+
Resolves the full dependency graph and downloads all packages.
|
|
286
|
+
|
|
287
|
+
**Source priority:** CLI `--source` values are used if provided. If omitted, sources are loaded from the [configuration file](#configuration-file).
|
|
288
|
+
|
|
289
|
+
**Profile resolution:** `--profile` selects the named build profile. If omitted, `config.defaultProfile` is used, falling back to `"default"`. v2 binaries are resolved in this order:
|
|
290
|
+
|
|
291
|
+
1. **Exact profile-hash match** — the preferred path.
|
|
292
|
+
2. **Declarative compatibility** — each published build may advertise a `compatibility` block (e.g. "compatible with any `msvc.version ≥ 193` on `Windows/x86_64`"). The best compatible candidate is picked deterministically.
|
|
293
|
+
3. **Source build** (with `--build=missing`) — clones the package's source at the published `gitSha`, resolves its own dependencies, invokes CMake through the shared toolchain generator, and caches the result under `%LOCALAPPDATA%\wyvrnpm\bc\`. On Windows/MSVC with a Ninja or Make generator, `vcvarsall.bat` is auto-activated.
|
|
294
|
+
4. **v1 legacy path** — only when no v2 entry exists for the package at all.
|
|
295
|
+
|
|
296
|
+
The pre-2.1 "same OS + arch, any compiler" loose fallback is no longer available. Publish a build for your profile, add a declarative `compatibility` block to the recipe, or rerun with `--build=missing` to source-build.
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Use configured sources and the default build profile
|
|
300
|
+
wyvrnpm install
|
|
301
|
+
|
|
302
|
+
# Use a specific named profile
|
|
303
|
+
wyvrnpm install --profile release
|
|
304
|
+
|
|
305
|
+
# Override with explicit sources
|
|
306
|
+
wyvrnpm install --source https://pkg.example.com/cpp
|
|
307
|
+
|
|
308
|
+
# Multiple sources — tried in order, first to respond wins
|
|
309
|
+
wyvrnpm install \
|
|
310
|
+
--source https://primary.example.com/cpp \
|
|
311
|
+
--source https://mirror.example.com/cpp
|
|
312
|
+
|
|
313
|
+
# Build any missing binary from source
|
|
314
|
+
wyvrnpm install --build=missing
|
|
315
|
+
|
|
316
|
+
# Force every dep to be rebuilt from source (debugging / reproducibility check)
|
|
317
|
+
wyvrnpm install --build=always
|
|
318
|
+
|
|
319
|
+
# Print the resolved install plan WITHOUT downloading (CI-friendly with --format=json)
|
|
320
|
+
wyvrnpm install --dry-run
|
|
321
|
+
wyvrnpm install --dry-run --format=json
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Options**
|
|
325
|
+
|
|
326
|
+
| Option | Default | Description |
|
|
327
|
+
|---|---|---|
|
|
328
|
+
| `--source` / `-s` | *(config)* | Base URL of a package source. Repeat for multiple. Overrides config when provided. |
|
|
329
|
+
| `--profile` / `-p` | *(config / "default")* | Named build profile to use for v2 binary resolution. |
|
|
330
|
+
| `--build` | `never` | Resolution mode when no exact or compatible profile match exists: `never` fails; `missing` clones and builds the package from its published `gitRepo@gitSha`; `always` rebuilds even when a binary exists. |
|
|
331
|
+
| `--platform` | `win_x64` | v1 legacy platform sub-path (used as a fallback when no v2 binary is found). |
|
|
332
|
+
| `--timeout` | `300` | HTTP request timeout in seconds. |
|
|
333
|
+
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
334
|
+
| `--root` | `./` | Project root (packages extracted to `{root}/wyvrn_internal/`). |
|
|
335
|
+
| `--dry-run` | `false` | Run the resolver + profile/options math, print the install plan, and exit. No download, no `wyvrn.lock`, no `wyvrn_internal/`, no toolchain. Combine with `--format=json` for CI ingestion (payload carries `command: "install-dry-run"`). |
|
|
336
|
+
| `--conf` | — | Non-ABI build-time override. Repeatable. Format: `<namespace.leaf>=<value>` — e.g. `--conf cmake.cache.CHROMA_ENABLE_TEST=ON`. Layered: CLI > `wyvrn.local.json` > named-profile `conf` > recipe. Does **not** fold into `profileHash`. See [Build-time configuration (`conf`)](#build-time-configuration-conf). |
|
|
337
|
+
| `--build-dir` | `build` | Project-relative subdir for the generated preset's `binaryDir` (`${sourceDir}/<root>/wyvrn-<profile>`). Use when the repo has a `BUILD` Bazel/Buck file at root that collides with `build/` on case-insensitive filesystems (gRPC, …). Persistent override: set `binaryDirRoot` in `wyvrn.local.json`. Validated — must be relative, no `..` segments. |
|
|
338
|
+
|
|
339
|
+
Packages are extracted to `wyvrn_internal/{name}/`. A `wyvrn.lock` file is written alongside the manifest recording the exact resolved versions, profile, and per-package SHA256. On subsequent installs the lock file pins all previously resolved versions — only newly added dependencies are resolved fresh.
|
|
340
|
+
|
|
341
|
+
After download, `install` also generates:
|
|
342
|
+
|
|
343
|
+
- `wyvrn_internal/wyvrn_toolchain.cmake` — CMake toolchain pointing at the resolved packages.
|
|
344
|
+
- `wyvrn_internal/wyvrn_deps.cmake` — post-`project()` include for `find_package()` wiring and runtime DLL copy.
|
|
345
|
+
- `wyvrn_internal/wyvrn_profile.json` — snapshot of the active build profile.
|
|
346
|
+
- `CMakePresets.json` (or `CMakeUserPresets.json` if the project root file is user-owned) with a `wyvrn-<profile>` configure preset. Presets for other profiles are preserved so multiple profiles coexist.
|
|
347
|
+
|
|
348
|
+
**Toolchain variables exposed to your `CMakeLists.txt` (valid BEFORE `project()`)**:
|
|
349
|
+
|
|
350
|
+
| Variable | Value |
|
|
351
|
+
|---|---|
|
|
352
|
+
| `WYVRN_PROFILE_NAME` / `WYVRN_PROFILE_HASH` | Active profile name + 16-char hash |
|
|
353
|
+
| `WYVRN_PROFILE_OS` / `WYVRN_PROFILE_ARCH` | OS + architecture from the profile |
|
|
354
|
+
| `WYVRN_PROFILE_COMPILER` / `WYVRN_PROFILE_COMPILER_VERSION` | Compiler identity |
|
|
355
|
+
| `WYVRN_PROFILE_CPPSTD` / `WYVRN_PROFILE_RUNTIME` | C++ standard + MSVC runtime linkage |
|
|
356
|
+
| `WYVRN_ARCH_SUFFIX` | `"64"` for 64-bit arches, `"32"` for 32-bit, empty for unmapped. Derived at toolchain-generation time so it's usable before `project()` — unlike `CMAKE_SIZEOF_VOID_P`. |
|
|
357
|
+
|
|
358
|
+
The optional helper `WYVRN_APPLY_ARCH_SUFFIX(<target> [BASE_NAME <name>])` from the bundled `macros.cmake` applies the suffix to a target's `OUTPUT_NAME` so x64 and x86 builds of the same library coexist on disk without overwriting each other. Target linkage (`target_link_libraries`) is unaffected — only the produced filename changes.
|
|
359
|
+
|
|
360
|
+
The bundled `variables.cmake` also suffixes the consumer's own output directories with `WYVRN_ARCH_SUFFIX` so multi-arch builds from one source tree don't clobber each other:
|
|
361
|
+
|
|
362
|
+
| Profile arch | Archive/library dir | Runtime (DLL/EXE) dir |
|
|
363
|
+
|---|---|---|
|
|
364
|
+
| `x86_64` / `armv8` | `output/lib64/` | `output/bin64/<CONFIG>/` |
|
|
365
|
+
| `x86` / `armv7` | `output/lib/` | `output/bin/<CONFIG>/` |
|
|
366
|
+
| unmapped | `output/lib/` | `output/bin/<CONFIG>/` |
|
|
367
|
+
|
|
368
|
+
Prior to `2.5.0` the runtime directory was always `output/bin/<CONFIG>/` regardless of arch — a multi-arch consumer building x64 then x86 would silently overwrite the first arch's DLLs. Scripts that hard-code `output/bin/…` expecting x64 payloads need to switch to `output/bin64/…` after upgrading.
|
|
369
|
+
|
|
370
|
+
```cmake
|
|
371
|
+
project(String CXX)
|
|
372
|
+
add_library(String STATIC ...)
|
|
373
|
+
WYVRN_APPLY_ARCH_SUFFIX(String) # → String64.lib / String32.lib
|
|
374
|
+
WYVRN_APPLY_ARCH_SUFFIX(String BASE_NAME my-str) # → my-str64.lib / my-str32.lib
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
### `wyvrnpm build`
|
|
380
|
+
|
|
381
|
+
Configures and builds the project through the wyvrnpm-generated CMake preset. Auto-runs `install` first if `wyvrn_toolchain.cmake` is missing or `wyvrn.lock` is newer than it.
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
# Configure + build with the default profile's preset (wyvrn-default)
|
|
385
|
+
wyvrnpm build
|
|
386
|
+
|
|
387
|
+
# Build Debug, verbose compiler output
|
|
388
|
+
wyvrnpm build --config Debug --verbose
|
|
389
|
+
|
|
390
|
+
# Build multiple configs in one go — configure runs once, build loops per config
|
|
391
|
+
wyvrnpm build --config Debug,Release --install
|
|
392
|
+
|
|
393
|
+
# Build every config the recipe declares (recipe's build.configs, or all four
|
|
394
|
+
# canonical configs if no recipe is present). Pairs naturally with --install.
|
|
395
|
+
wyvrnpm build --all-configs --install
|
|
396
|
+
|
|
397
|
+
# Use a specific profile's preset
|
|
398
|
+
wyvrnpm build --profile release
|
|
399
|
+
|
|
400
|
+
# Explicit preset name (overrides profile-derived default)
|
|
401
|
+
wyvrnpm build --preset wyvrn-release
|
|
402
|
+
|
|
403
|
+
# Build a single target
|
|
404
|
+
wyvrnpm build --target my-lib
|
|
405
|
+
|
|
406
|
+
# Wipe the build directory first
|
|
407
|
+
wyvrnpm build --clean
|
|
408
|
+
|
|
409
|
+
# Override the preset's generator (pair with --clean when switching generators)
|
|
410
|
+
wyvrnpm build --clean --generator "Visual Studio 17 2022"
|
|
411
|
+
wyvrnpm build --clean -G "Ninja Multi-Config"
|
|
412
|
+
|
|
413
|
+
# Build, then install to the CMake install prefix
|
|
414
|
+
wyvrnpm build --install
|
|
415
|
+
wyvrnpm build --install --install-prefix C:\out\stage
|
|
416
|
+
|
|
417
|
+
# Skip the auto-install step
|
|
418
|
+
wyvrnpm build --no-auto-install
|
|
419
|
+
|
|
420
|
+
# Pass extra args through to cmake --build
|
|
421
|
+
wyvrnpm build -- -j 8
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Options**
|
|
425
|
+
|
|
426
|
+
| Option | Default | Description |
|
|
427
|
+
|---|---|---|
|
|
428
|
+
| `--preset` / `-P` | `wyvrn-<profile>` | CMake configure preset name. |
|
|
429
|
+
| `--profile` / `-p` | *(config / "default")* | Build profile — determines the default preset name. |
|
|
430
|
+
| `--config` / `-c` | `Release` | Build configuration (`Debug` \| `Release` \| `RelWithDebInfo` \| `MinSizeRel`). Comma-separated to build multiple in one invocation (e.g. `Debug,Release`) — configure runs once, build (+ `--install`) loops per config. |
|
|
431
|
+
| `--all-configs` | `false` | Build every config from the recipe's `build.configs` (or all four canonical configs when no recipe is present). Takes precedence over `--config`. |
|
|
432
|
+
| `--target` / `-t` | *(all)* | Specific CMake target to build. |
|
|
433
|
+
| `--verbose` / `-v` | `false` | Pass `--verbose` to `cmake --build`. |
|
|
434
|
+
| `--clean` | `false` | Remove the build directory before configuring. |
|
|
435
|
+
| `--generator` / `-G` | *(from preset)* | Override the CMake generator used at configure time (e.g. `"Visual Studio 17 2022"`, `"Ninja"`, `"Ninja Multi-Config"`). CMake bakes the generator into the cache, so pair with `--clean` when switching. When the effective generator is Visual Studio, `-A <platform>` is auto-derived from the profile's arch (`x86→Win32`, `x86_64→x64`, `armv8→ARM64`, `armv7→ARM`) so VS doesn't silently default to x64 on 32-bit profiles. |
|
|
436
|
+
| `--install` | `false` | Run `cmake --install` after a successful build. |
|
|
437
|
+
| `--install-prefix` | *(baked in)* | Override `CMAKE_INSTALL_PREFIX` for `--install` without reconfiguring. |
|
|
438
|
+
| `--auto-install` | `true` | Auto-run `wyvrnpm install` when the toolchain is stale. Disable with `--no-auto-install`. |
|
|
439
|
+
| `--source` / `-s` | *(config)* | Package sources — passed through to `install` when auto-installing. |
|
|
440
|
+
| `--build-dir` | `build` | Project-relative subdir for the build tree. Must match the value used at `wyvrnpm install` time — the baked preset is the source of truth for `binaryDir`. Persist via `wyvrn.local.json:binaryDirRoot` so install + build agree without repeating the flag. See [Per-developer overlay](#per-developer-overlay--wyvrnlocaljson). |
|
|
441
|
+
|
|
442
|
+
Everything after `--` is forwarded verbatim to `cmake --build` (e.g. `-j 8`).
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
### `wyvrnpm publish`
|
|
447
|
+
|
|
448
|
+
Zips the project directory and uploads `wyvrn.json` + `wyvrn.zip` to the destination source, tagged with the active build profile.
|
|
449
|
+
|
|
450
|
+
**Source priority:** CLI `--source` is used if provided (as a URL/URI or a configured source name). If omitted, the first configured publish source is used.
|
|
451
|
+
|
|
452
|
+
**Profile:** `--profile` selects the named build profile to publish under. If omitted, `config.defaultProfile` is used, falling back to `"default"`. The profile hash is included in the upload path so multiple builds of the same version (different compilers, runtimes, etc.) can coexist.
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
# Use configured source and default profile
|
|
456
|
+
wyvrnpm publish
|
|
457
|
+
|
|
458
|
+
# Use a specific profile
|
|
459
|
+
wyvrnpm publish --profile release
|
|
460
|
+
|
|
461
|
+
# Reference a configured source by name
|
|
462
|
+
wyvrnpm publish --source default
|
|
463
|
+
|
|
464
|
+
# Explicit destination URL
|
|
465
|
+
wyvrnpm publish --source s3://my-bucket/packages --aws-profile my-sso
|
|
466
|
+
|
|
467
|
+
# HTTP server with token auth (CI-preferred: --token-env avoids argv leakage)
|
|
468
|
+
wyvrnpm publish --source https://pkg.corp.com --token-env WYVRN_HTTP_TOKEN
|
|
469
|
+
# Equivalent for interactive use; --token lands in shell history / ps output
|
|
470
|
+
wyvrnpm publish --source https://pkg.corp.com --token mytoken
|
|
471
|
+
|
|
472
|
+
# Local directory or SMB share
|
|
473
|
+
wyvrnpm publish --source \\fileserver\packages
|
|
474
|
+
wyvrnpm publish --source /mnt/packages
|
|
475
|
+
|
|
476
|
+
# Publish build artifacts from a specific directory
|
|
477
|
+
wyvrnpm publish --path ./dist
|
|
478
|
+
|
|
479
|
+
# Overwrite an existing build (same version + profile hash)
|
|
480
|
+
wyvrnpm publish --force
|
|
481
|
+
|
|
482
|
+
# Dry-run — show the upload plan without touching the registry
|
|
483
|
+
wyvrnpm publish --dry-run
|
|
484
|
+
wyvrnpm publish --dry-run --format json | jq '.wouldOverwrite, .plan'
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
**Options**
|
|
488
|
+
|
|
489
|
+
| Option | Default | Description |
|
|
490
|
+
|---|---|---|
|
|
491
|
+
| `--source` / `-s` | *(config)* | Destination URL/URI or configured source name. |
|
|
492
|
+
| `--profile` / `-p` | *(config / "default")* | Named build profile to publish under. |
|
|
493
|
+
| `--aws-profile` | *(config)* | AWS SSO profile for S3 authentication. |
|
|
494
|
+
| `--token` | *(config)* | Bearer token for HTTP server authentication. |
|
|
495
|
+
| `--token-env` | *(config)* | Name of an env var holding the bearer token. Preferred for CI — the literal value never lands in `argv` or shell history. |
|
|
496
|
+
| `--path` | `.` | Directory to zip and publish. |
|
|
497
|
+
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
498
|
+
| `--force` / `-f` | `false` | Overwrite an existing published version (same version + profile hash). |
|
|
499
|
+
| `--dry-run` | `false` | Run every step (profile, options, zip, SHA256, `v2Exists` check) and print the upload plan, but skip the provider write. An existing published version is reported as a warning (not an error) so the full plan still prints. Pair with `--format json` to gate CI on `wouldOverwrite`. |
|
|
500
|
+
|
|
501
|
+
During publish the tool also:
|
|
502
|
+
- reads `wyvrn.lock` to pin locked dependency versions into the uploaded manifest
|
|
503
|
+
- captures the current git commit SHA and remote URL as metadata
|
|
504
|
+
- computes a SHA256 of the zip and stores it in the upload metadata
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
### `.wyvrnignore`
|
|
509
|
+
|
|
510
|
+
Place a `.wyvrnignore` file in the directory being published to exclude files from the zip. Uses the same glob syntax as `.gitignore`:
|
|
511
|
+
|
|
512
|
+
```
|
|
513
|
+
# Build artefacts that shouldn't ship
|
|
514
|
+
build/
|
|
515
|
+
*.obj
|
|
516
|
+
*.pdb
|
|
517
|
+
|
|
518
|
+
# Anchored to root with leading /
|
|
519
|
+
/CMakeCache.txt
|
|
520
|
+
/CMakeFiles/
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
### `wyvrnpm clean`
|
|
526
|
+
|
|
527
|
+
Removes the `wyvrn_internal/` package cache and `wyvrn.lock`.
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
# Project-local cleanup
|
|
531
|
+
wyvrnpm clean
|
|
532
|
+
|
|
533
|
+
# Also wipe the machine-wide source-build cache used by --build=missing
|
|
534
|
+
wyvrnpm clean --build-cache
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
**Options**
|
|
538
|
+
|
|
539
|
+
| Option | Default | Description |
|
|
540
|
+
|---|---|---|
|
|
541
|
+
| `--build-cache` | `false` | Also remove the source-build cache under `%LOCALAPPDATA%\wyvrnpm\bc\` (Unix: `~/.cache/wyvrnpm/bc/`). |
|
|
542
|
+
| `--uploaded-built` | `false` | Wipe only the local record of what this machine has uploaded via `--upload-built` (the `.uploaded-to.json` sidecars). Does **not** touch the registry, the artefacts, or `wyvrn_internal/`. |
|
|
543
|
+
|
|
544
|
+
For selective cache pruning (keep last N variants, drop entries older than N days), use `wyvrnpm cache prune` instead — see below.
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
### `wyvrnpm cache` (2.8.0+)
|
|
549
|
+
|
|
550
|
+
Inspect and selectively prune the machine-wide source-build cache at `%LOCALAPPDATA%\wyvrnpm\bc\` (Unix: `~/.cache/wyvrnpm/bc/`). Useful once `--upload-built` adoption balloons cache size on dev rigs — `clean --build-cache` is the blunt alternative that wipes everything.
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
# List every cached entry as a table
|
|
554
|
+
wyvrnpm cache list
|
|
555
|
+
|
|
556
|
+
# Filter by package name (glob)
|
|
557
|
+
wyvrnpm cache list "boost*"
|
|
558
|
+
|
|
559
|
+
# Machine-readable output for CI
|
|
560
|
+
wyvrnpm cache list --format json
|
|
561
|
+
|
|
562
|
+
# Keep the 2 most-recently-touched variants per (name, version)
|
|
563
|
+
wyvrnpm cache prune --keep-last 2
|
|
564
|
+
|
|
565
|
+
# Drop entries older than 30 days
|
|
566
|
+
wyvrnpm cache prune --older-than 30d
|
|
567
|
+
|
|
568
|
+
# Combine: keep 1 recent per version AND drop anything stale
|
|
569
|
+
wyvrnpm cache prune --keep-last 1 --older-than 30d
|
|
570
|
+
|
|
571
|
+
# Preview — print what would be removed, delete nothing
|
|
572
|
+
wyvrnpm cache prune --keep-last 2 --dry-run
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
**`cache list` options**
|
|
576
|
+
|
|
577
|
+
| Option | Default | Description |
|
|
578
|
+
|---|---|---|
|
|
579
|
+
| `[pattern]` / `--pattern` | *(none)* | Glob over package names (`*` for any chars, `?` for one). |
|
|
580
|
+
| `--format` | `text` | `text` (table) or `json` (structured payload for CI). |
|
|
581
|
+
|
|
582
|
+
**`cache prune` options**
|
|
583
|
+
|
|
584
|
+
| Option | Default | Description |
|
|
585
|
+
|---|---|---|
|
|
586
|
+
| `--keep-last <N>` | *(none)* | Retain the N most-recently-touched entries **per (name, version) group**. A four-profile rig keeping-last-2 still retains the two newest profile variants of each version. |
|
|
587
|
+
| `--older-than <dur>` | *(none)* | Remove entries whose mtime is older than the threshold. Format: `<number><unit>`, unit ∈ `s` / `m` / `h` / `d` (e.g. `30d`, `72h`). |
|
|
588
|
+
| `--pattern <glob>` | *(none)* | Restrict scope to package names matching the glob. |
|
|
589
|
+
| `--dry-run` | `false` | Print what would be removed without deleting. |
|
|
590
|
+
|
|
591
|
+
At least one of `--keep-last` / `--older-than` is required — calling `prune` bare errors out with a pointer to `clean --build-cache` (the nuke-everything path).
|
|
592
|
+
|
|
593
|
+
---
|
|
594
|
+
|
|
595
|
+
### `wyvrnpm show`
|
|
596
|
+
|
|
597
|
+
Read-only registry-metadata inspector. Given `<name>[@<version>[@<profileHash>]]`, queries the first configured install source that knows the package (override with `--source`) and prints what's published.
|
|
598
|
+
|
|
599
|
+
```bash
|
|
600
|
+
# Index of every published version (one HTTP round trip per source)
|
|
601
|
+
wyvrnpm show zlib
|
|
602
|
+
|
|
603
|
+
# Narrow to one version — fans out a per-profile query so uploadedBy,
|
|
604
|
+
# compatibility, and declared options show up per build
|
|
605
|
+
wyvrnpm show zlib@1.3.0.0
|
|
606
|
+
|
|
607
|
+
# Narrow to one specific build
|
|
608
|
+
wyvrnpm show zlib@1.3.0.0@a1b2c3d4e5f60718
|
|
609
|
+
|
|
610
|
+
# Pick the source explicitly (skips install-source lookup order)
|
|
611
|
+
wyvrnpm show zlib@1.3.0.0 --source s3://team-pkgs
|
|
612
|
+
|
|
613
|
+
# Machine-readable for CI ingestion
|
|
614
|
+
wyvrnpm show zlib@1.3.0.0 --format json
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
What gets surfaced per profile:
|
|
618
|
+
|
|
619
|
+
- **origin** — `author-publish` vs `consumer-upload` (derived from whether the manifest carries an `uploadedBy` block).
|
|
620
|
+
- **uploadedBy** — when set, the consumer-upload provenance (`kind`, `builtFromGit`, `builtFromSha`, `uploadedAt`, `wyvrnpmVersion`).
|
|
621
|
+
- **compatibility** — the recipe's declarative compat block, if any.
|
|
622
|
+
- **declaredOptions** — the author-declared `options` map from the recipe.
|
|
623
|
+
- **resolvedOptions** — the resolved option values that produced this profile's `profileHash`.
|
|
624
|
+
- **publishedConf** — recipe + CLI `--conf` the publisher captured (informational; doesn't affect resolution).
|
|
625
|
+
- **signature** — when PLAN-SIGNING phase 1 ships, signer identity; absent today.
|
|
626
|
+
|
|
627
|
+
Useful for: auditing consumer uploads (who pushed this artefact, from which commit), spotting profile drift between two consumers, verifying a package's declared options before adding it to a recipe.
|
|
628
|
+
|
|
629
|
+
**Options**
|
|
630
|
+
|
|
631
|
+
| Option | Default | Description |
|
|
632
|
+
|---|---|---|
|
|
633
|
+
| `pkg` *(positional)* | *(required)* | `<name>[@<version>[@<profileHash>]]` |
|
|
634
|
+
| `--source` / `-s` | *(first configured install source)* | URL or configured source name. Repeatable. |
|
|
635
|
+
| `--format` | `text` | `text` or `json` (see [Shape — `show`](#shape--show) below). |
|
|
636
|
+
| `--token` / `--token-env` / `--aws-profile` | | Auth forwarded to the provider the same way `install` does. |
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
### `wyvrnpm install-skill`
|
|
641
|
+
|
|
642
|
+
Installs the bundled wyvrnpm Agent Skill — the authoring guide Claude Code uses when it sees a `wyvrn.json` in the workspace. Ships as a `.skill` zip inside the npm package (`claude/skills/wyvrnpm.skill`) and is extracted into `~/.claude/skills/wyvrnpm/` on demand.
|
|
643
|
+
|
|
644
|
+
```bash
|
|
645
|
+
# One-shot: install the bundled skill for Claude Code
|
|
646
|
+
wyvrnpm install-skill --claude
|
|
647
|
+
|
|
648
|
+
# Overwrite an existing installation (e.g. after upgrading wyvrnpm)
|
|
649
|
+
wyvrnpm install-skill --claude --force
|
|
650
|
+
|
|
651
|
+
# Preview without writing
|
|
652
|
+
wyvrnpm install-skill --claude --dry-run
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
You only need this if you want Claude Code to pick up the skill. The CLI itself works without it.
|
|
656
|
+
|
|
657
|
+
**Options**
|
|
658
|
+
|
|
659
|
+
| Option | Default | Description |
|
|
660
|
+
|---|---|---|
|
|
661
|
+
| `--claude` | `false` | Install for Claude Code (extracts to `~/.claude/skills/wyvrnpm/` + writes the `.skill` zip alongside). Required — present so a future `--cursor` / `--vscode` target can slot in without CLI churn. |
|
|
662
|
+
| `--force` | `false` | Overwrite an existing skill install. Without it, the command refuses to clobber. |
|
|
663
|
+
| `--dry-run` | `false` | Print the destination paths and intended actions without writing. |
|
|
664
|
+
|
|
665
|
+
---
|
|
666
|
+
|
|
667
|
+
### `wyvrnpm link`
|
|
668
|
+
|
|
669
|
+
Links a local package for development, similar to `npm link`. This allows you to test packages from local source directories without publishing to the registry.
|
|
670
|
+
|
|
671
|
+
#### Register a package globally
|
|
672
|
+
|
|
673
|
+
Run `wyvrnpm link` in a package directory to register it for linking:
|
|
674
|
+
|
|
675
|
+
```bash
|
|
676
|
+
cd C:\Dev\my-library
|
|
677
|
+
wyvrnpm link
|
|
678
|
+
# [wyvrn] Registered "my-library" -> C:\Dev\my-library
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
For CMake packages where the installable content is in a subdirectory:
|
|
682
|
+
|
|
683
|
+
```bash
|
|
684
|
+
cd C:\Dev\my-cmake-lib
|
|
685
|
+
wyvrnpm link --subdir output/install
|
|
686
|
+
# [wyvrn] Registered "my-cmake-lib" -> C:\Dev\my-cmake-lib\output\install
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
#### Link a package into your project
|
|
690
|
+
|
|
691
|
+
Link a globally registered package:
|
|
692
|
+
|
|
693
|
+
```bash
|
|
694
|
+
cd C:\Projects\my-app
|
|
695
|
+
wyvrnpm link my-library
|
|
696
|
+
# [wyvrn] Linked: my-library -> C:\Dev\my-library
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
Or link directly from a path (skip global registration):
|
|
700
|
+
|
|
701
|
+
```bash
|
|
702
|
+
wyvrnpm link my-library C:\Dev\my-library
|
|
703
|
+
wyvrnpm link my-library C:\Dev\my-library --subdir output/install
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
#### List registered packages
|
|
707
|
+
|
|
708
|
+
```bash
|
|
709
|
+
wyvrnpm link --list
|
|
710
|
+
# [wyvrn] Globally registered packages:
|
|
711
|
+
# my-library -> C:\Dev\my-library
|
|
712
|
+
# my-cmake-lib -> C:\Dev\my-cmake-lib\output\install [subdir: output/install]
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
**Options**
|
|
716
|
+
|
|
717
|
+
| Option | Description |
|
|
718
|
+
|---|---|
|
|
719
|
+
| `--list` | List all globally registered packages. |
|
|
720
|
+
| `--subdir` | Subdirectory within the package to link (e.g., `output/install` for CMake packages). |
|
|
721
|
+
|
|
722
|
+
**How it works:**
|
|
723
|
+
- Creates a symlink (Unix) or junction (Windows) in `wyvrn_internal/`
|
|
724
|
+
- Junctions on Windows don't require admin rights
|
|
725
|
+
- Linked packages are recorded in `wyvrn.lock` with a `linked:` prefix
|
|
726
|
+
- `wyvrnpm install` automatically skips downloading linked packages
|
|
727
|
+
|
|
728
|
+
---
|
|
729
|
+
|
|
730
|
+
### `wyvrnpm unlink`
|
|
731
|
+
|
|
732
|
+
Removes a linked package from the current project.
|
|
733
|
+
|
|
734
|
+
```bash
|
|
735
|
+
wyvrnpm unlink my-library
|
|
736
|
+
# [wyvrn] Unlinked: my-library
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
To unlink and re-download from the registry:
|
|
740
|
+
|
|
741
|
+
```bash
|
|
742
|
+
wyvrnpm unlink my-library --restore
|
|
743
|
+
# [wyvrn] Unlinked: my-library
|
|
744
|
+
# [wyvrn] Downloading: my-library@1.0.0.0
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
**Options**
|
|
748
|
+
|
|
749
|
+
| Option | Default | Description |
|
|
750
|
+
|---|---|---|
|
|
751
|
+
| `--restore` | `false` | Re-download the package from registry after unlinking. |
|
|
752
|
+
| `--source` | *(config)* | Package source for `--restore`. |
|
|
753
|
+
| `--platform` | `win_x64` | Target platform for v1 fallback when using `--restore`. |
|
|
754
|
+
|
|
755
|
+
---
|
|
756
|
+
|
|
757
|
+
### `wyvrnpm configure`
|
|
758
|
+
|
|
759
|
+
Manages the [configuration file](#configuration-file). All sub-commands read and write `config.json` in the platform config directory.
|
|
760
|
+
|
|
761
|
+
#### `wyvrnpm configure list`
|
|
762
|
+
|
|
763
|
+
Prints all configured sources.
|
|
764
|
+
|
|
765
|
+
```
|
|
766
|
+
Config: C:\Users\you\AppData\Local\wyvrnpm\config.json
|
|
767
|
+
|
|
768
|
+
Install Sources:
|
|
769
|
+
corp-s3 s3://my-bucket/packages [profile: my-sso]
|
|
770
|
+
fallback https://pkg.corp.com [token: ***]
|
|
771
|
+
|
|
772
|
+
Publish Sources:
|
|
773
|
+
default s3://my-bucket/packages [profile: my-sso]
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
#### `wyvrnpm configure add-source`
|
|
777
|
+
|
|
778
|
+
Adds a new source or updates an existing one with the same name.
|
|
779
|
+
|
|
780
|
+
```bash
|
|
781
|
+
# S3 with AWS SSO profile (install)
|
|
782
|
+
wyvrnpm configure add-source \
|
|
783
|
+
--kind install \
|
|
784
|
+
--name corp-s3 \
|
|
785
|
+
--url s3://my-bucket/packages \
|
|
786
|
+
--profile my-sso-profile
|
|
787
|
+
|
|
788
|
+
# HTTPS server with token auth (install)
|
|
789
|
+
wyvrnpm configure add-source \
|
|
790
|
+
--kind install \
|
|
791
|
+
--name fallback \
|
|
792
|
+
--url https://pkg.corp.com \
|
|
793
|
+
--token mytoken
|
|
794
|
+
|
|
795
|
+
# Local or SMB path (no auth required)
|
|
796
|
+
wyvrnpm configure add-source \
|
|
797
|
+
--kind install \
|
|
798
|
+
--name local \
|
|
799
|
+
--url \\fileserver\packages
|
|
800
|
+
|
|
801
|
+
# Publish destination
|
|
802
|
+
wyvrnpm configure add-source \
|
|
803
|
+
--kind publish \
|
|
804
|
+
--name default \
|
|
805
|
+
--url s3://my-bucket/packages \
|
|
806
|
+
--profile my-sso-profile
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
**Options**
|
|
810
|
+
|
|
811
|
+
| Option | Required | Description |
|
|
812
|
+
|---|---|---|
|
|
813
|
+
| `--kind` | Yes | `install` or `publish`. |
|
|
814
|
+
| `--name` | Yes | Unique name for this source. |
|
|
815
|
+
| `--url` | Yes | Destination URL, URI, or file path. |
|
|
816
|
+
| `--profile` | No | AWS SSO profile (S3 sources). |
|
|
817
|
+
| `--token` | No | Bearer token (HTTP sources). Persisted in plaintext in `config.json` — prefer `--token-env` for CI and shared setups. |
|
|
818
|
+
| `--token-env` | No | Name of an env var whose value is the bearer token. Only the **name** lands in `config.json`; the value is resolved fresh on every `wyvrnpm` call. |
|
|
819
|
+
|
|
820
|
+
#### `wyvrnpm configure remove-source`
|
|
821
|
+
|
|
822
|
+
Removes a source by name.
|
|
823
|
+
|
|
824
|
+
```bash
|
|
825
|
+
wyvrnpm configure remove-source --kind install --name fallback
|
|
826
|
+
wyvrnpm configure remove-source --kind publish --name default
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
#### `wyvrnpm configure profile`
|
|
830
|
+
|
|
831
|
+
Manages named build profiles stored in the profiles directory.
|
|
832
|
+
|
|
833
|
+
```bash
|
|
834
|
+
# Auto-detect the current build environment and save it
|
|
835
|
+
wyvrnpm configure profile detect
|
|
836
|
+
wyvrnpm configure profile detect --name msvc_release --dry-run
|
|
837
|
+
|
|
838
|
+
# List all saved profiles (* = default)
|
|
839
|
+
wyvrnpm configure profile list
|
|
840
|
+
|
|
841
|
+
# Show a saved profile
|
|
842
|
+
wyvrnpm configure profile show
|
|
843
|
+
wyvrnpm configure profile show --name msvc_release
|
|
844
|
+
|
|
845
|
+
# Manually set individual fields in a profile
|
|
846
|
+
wyvrnpm configure profile set --name msvc_release --runtime static --cppstd 20
|
|
847
|
+
|
|
848
|
+
# Change which profile is the default
|
|
849
|
+
wyvrnpm configure profile set-default msvc_release
|
|
850
|
+
|
|
851
|
+
# Delete a profile
|
|
852
|
+
wyvrnpm configure profile delete msvc_release
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
**`configure profile detect` options**
|
|
856
|
+
|
|
857
|
+
| Option | Description |
|
|
858
|
+
|---|---|
|
|
859
|
+
| `--name` / `-n` | Profile name to save to (default: `"default"`). |
|
|
860
|
+
| `--dry-run` | Print detected values without saving. |
|
|
861
|
+
|
|
862
|
+
**`configure profile set` options**
|
|
863
|
+
|
|
864
|
+
| Option | Description |
|
|
865
|
+
|---|---|
|
|
866
|
+
| `--name` / `-n` | Profile name to update (default: `"default"`). |
|
|
867
|
+
| `--os` | OS (`Windows` \| `Linux` \| `Macos`). |
|
|
868
|
+
| `--arch` | Architecture (`x86_64` \| `x86` \| `armv8` \| ...). |
|
|
869
|
+
| `--compiler` | Compiler (`msvc` \| `gcc` \| `clang` \| `apple-clang`). |
|
|
870
|
+
| `--compiler-version` | Compiler version (`193` \| `13` \| `17` \| ...). |
|
|
871
|
+
| `--cppstd` | C++ standard (`14` \| `17` \| `20` \| `23`). |
|
|
872
|
+
| `--runtime` | Runtime linkage (`static` \| `dynamic`). |
|
|
873
|
+
|
|
874
|
+
---
|
|
875
|
+
|
|
876
|
+
## JSON output (`--format json`)
|
|
877
|
+
|
|
878
|
+
`install`, `publish`, and `show` accept `--format json` to emit a single machine-readable JSON object on stdout. Log lines (`[wyvrn]` prefix) move to **stderr** in this mode, so stdout is reserved exclusively for the JSON payload — no scraping required.
|
|
879
|
+
|
|
880
|
+
```bash
|
|
881
|
+
wyvrnpm install --format json > install-result.json
|
|
882
|
+
wyvrnpm publish --format json 2>/dev/null # swallow logs, keep JSON
|
|
883
|
+
wyvrnpm show zlib@1.3.0.0 --format json | jq '.versions["1.3.0.0"].profiles[].origin'
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
### Shape — `install`
|
|
887
|
+
|
|
888
|
+
```json
|
|
889
|
+
{
|
|
890
|
+
"command": "install",
|
|
891
|
+
"wyvrnpmVersion": "2.2.1",
|
|
892
|
+
"profile": { "os": "Windows", "arch": "x86_64", "compiler": "msvc", "compiler.version": "193", "compiler.cppstd": "23", "compiler.runtime": "dynamic" },
|
|
893
|
+
"profileName": "default",
|
|
894
|
+
"profileHash": "bf341c08af0aee2d",
|
|
895
|
+
"packages": [
|
|
896
|
+
{
|
|
897
|
+
"name": "zlib",
|
|
898
|
+
"version": "1.3.0.0",
|
|
899
|
+
"versionRange": "^1.3.0.0",
|
|
900
|
+
"profileHash": "a1b2c3d4e5f60718",
|
|
901
|
+
"options": { "shared": false, "minizip": true },
|
|
902
|
+
"contentSha256": "…",
|
|
903
|
+
"gitSha": "…",
|
|
904
|
+
"resolvedFrom": "v2"
|
|
905
|
+
}
|
|
906
|
+
],
|
|
907
|
+
"lockFile": "/abs/path/to/wyvrn.lock",
|
|
908
|
+
"uploadSummary": { "uploaded": 0, "skipped": 0, "failed": 0 }
|
|
909
|
+
}
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
- `versionRange` is `null` when the user pinned an exact version.
|
|
913
|
+
- `options` is `null` for packages that declare no options.
|
|
914
|
+
- `uploadSummary` is `null` unless `--upload-built` was passed.
|
|
915
|
+
- `packages` is sorted by name.
|
|
916
|
+
|
|
917
|
+
### Shape — `publish`
|
|
918
|
+
|
|
919
|
+
```json
|
|
920
|
+
{
|
|
921
|
+
"command": "publish",
|
|
922
|
+
"wyvrnpmVersion": "2.2.1",
|
|
923
|
+
"name": "zlib",
|
|
924
|
+
"version": "1.3.0.0",
|
|
925
|
+
"profileHash": "a1b2c3d4e5f60718",
|
|
926
|
+
"source": "s3://team-pkgs",
|
|
927
|
+
"contentSha256": "…",
|
|
928
|
+
"options": { "shared": false, "minizip": true },
|
|
929
|
+
"gitSha": "…",
|
|
930
|
+
"gitRepo": "…",
|
|
931
|
+
"publishedAt": "2026-04-21T12:34:56.789Z"
|
|
932
|
+
}
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
### Shape — `show`
|
|
936
|
+
|
|
937
|
+
```json
|
|
938
|
+
{
|
|
939
|
+
"command": "show",
|
|
940
|
+
"wyvrnpmVersion": "2.2.1",
|
|
941
|
+
"source": "s3://team-pkgs",
|
|
942
|
+
"package": "zlib",
|
|
943
|
+
"latest": "1.3.0.0",
|
|
944
|
+
"versions": {
|
|
945
|
+
"1.3.0.0": {
|
|
946
|
+
"source": { "gitRepo": "…", "gitSha": "…" },
|
|
947
|
+
"profiles": [
|
|
948
|
+
{
|
|
949
|
+
"profileHash": "a1b2c3d4e5f60718",
|
|
950
|
+
"contentSha256": "…",
|
|
951
|
+
"publishedAt": "…",
|
|
952
|
+
"buildSettings": { "os": "Windows", "...": "...", "options": { "minizip": true } },
|
|
953
|
+
"origin": "author-publish",
|
|
954
|
+
"uploadedBy": null,
|
|
955
|
+
"compatibility": { "compiler.cppstd": "lte" },
|
|
956
|
+
"declaredOptions": { "minizip": { "default": true, "allowed": [true, false] } }
|
|
957
|
+
}
|
|
958
|
+
]
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
- `origin` is `"author-publish"` | `"consumer-source-build"` | `null` (the last when the summary view can't tell without a deep fetch).
|
|
965
|
+
- Bare-name queries (`wyvrnpm show zlib --format json`) skip the per-profile deep fetch; `origin`, `uploadedBy`, `compatibility`, `declaredOptions` are `null` for each profile.
|
|
966
|
+
|
|
967
|
+
Exit codes and error behaviour are identical to text mode. Fatal errors leave stdout empty rather than emitting partial JSON.
|
|
968
|
+
|
|
969
|
+
---
|
|
970
|
+
|
|
971
|
+
## Configuration File
|
|
972
|
+
|
|
973
|
+
wyvrnpm stores persistent configuration in a `config.json` file:
|
|
974
|
+
|
|
975
|
+
| Platform | Path |
|
|
976
|
+
|---|---|
|
|
977
|
+
| Windows | `%LOCALAPPDATA%\wyvrnpm\config.json` |
|
|
978
|
+
| Linux / macOS | `~/.config/wyvrnpm/config.json` |
|
|
979
|
+
|
|
980
|
+
**Example config.json**
|
|
981
|
+
|
|
982
|
+
```json
|
|
983
|
+
{
|
|
984
|
+
"defaultProfile": "default",
|
|
985
|
+
"installSources": [
|
|
986
|
+
{
|
|
987
|
+
"name": "corp-s3",
|
|
988
|
+
"url": "s3://my-bucket/packages",
|
|
989
|
+
"profile": "my-sso-profile"
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
"name": "fallback",
|
|
993
|
+
"url": "https://pkg.corp.com",
|
|
994
|
+
"token": "mytoken"
|
|
995
|
+
}
|
|
996
|
+
],
|
|
997
|
+
"publishSources": [
|
|
998
|
+
{
|
|
999
|
+
"name": "default",
|
|
1000
|
+
"url": "s3://my-bucket/packages",
|
|
1001
|
+
"profile": "my-sso-profile"
|
|
1002
|
+
}
|
|
1003
|
+
],
|
|
1004
|
+
"linkedPackages": {
|
|
1005
|
+
"my-library": { "path": "C:\\Dev\\my-library" },
|
|
1006
|
+
"my-cmake-lib": { "path": "C:\\Dev\\my-cmake-lib", "subdir": "output/install" }
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
The `defaultProfile` field sets which named build profile is used when `--profile` is not provided on the CLI.
|
|
1012
|
+
|
|
1013
|
+
The `linkedPackages` field stores globally registered packages for `wyvrnpm link`. Each entry maps a package name to its local path and optional subdirectory.
|
|
1014
|
+
|
|
1015
|
+
**CLI options always take priority over config.** Config values are only used when the corresponding CLI option is not provided.
|
|
1016
|
+
|
|
1017
|
+
---
|
|
1018
|
+
|
|
1019
|
+
## Publish Providers
|
|
1020
|
+
|
|
1021
|
+
wyvrnpm uses a provider architecture to support different destination types. The correct provider is selected automatically based on the source URL format.
|
|
1022
|
+
|
|
1023
|
+
| Provider | Detected from | Auth |
|
|
1024
|
+
|---|---|---|
|
|
1025
|
+
| **S3** | `s3://` URI, or S3 HTTPS endpoint | `--aws-profile` (AWS SSO) |
|
|
1026
|
+
| **HTTP** | `http://` or `https://` | `--token` (Bearer) |
|
|
1027
|
+
| **File** | Local path or UNC/SMB share | none |
|
|
1028
|
+
|
|
1029
|
+
### S3 Provider
|
|
1030
|
+
|
|
1031
|
+
Accepts any of these source formats:
|
|
1032
|
+
|
|
1033
|
+
```
|
|
1034
|
+
s3://bucket-name/optional/prefix
|
|
1035
|
+
https://bucket-name.s3.amazonaws.com/prefix
|
|
1036
|
+
https://bucket-name.s3.us-east-1.amazonaws.com/prefix
|
|
1037
|
+
https://s3.amazonaws.com/bucket-name/prefix
|
|
1038
|
+
https://s3.us-east-1.amazonaws.com/bucket-name/prefix
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
Authentication uses AWS SSO via `--aws-profile`. If no profile is given, the default AWS credential chain is used.
|
|
1042
|
+
|
|
1043
|
+
### HTTP Provider
|
|
1044
|
+
|
|
1045
|
+
Accepts `http://` and `https://` URLs. Uploads files via HTTP `PUT`. Optionally authenticates with a Bearer token via `--token`.
|
|
1046
|
+
|
|
1047
|
+
### File Provider
|
|
1048
|
+
|
|
1049
|
+
Accepts local directory paths and SMB/UNC network shares. Files are copied with no authentication required.
|
|
1050
|
+
|
|
1051
|
+
```
|
|
1052
|
+
/absolute/unix/path
|
|
1053
|
+
./relative/path
|
|
1054
|
+
C:\Windows\path
|
|
1055
|
+
\\server\share\path
|
|
1056
|
+
//server/share/path
|
|
1057
|
+
file:///absolute/path
|
|
1058
|
+
```
|
|
1059
|
+
|
|
1060
|
+
### Adding a Custom Provider
|
|
1061
|
+
|
|
1062
|
+
1. Create `src/providers/myprovider.js` extending `BaseProvider`:
|
|
1063
|
+
|
|
1064
|
+
```js
|
|
1065
|
+
'use strict';
|
|
1066
|
+
const BaseProvider = require('./base');
|
|
1067
|
+
|
|
1068
|
+
class MyProvider extends BaseProvider {
|
|
1069
|
+
static canHandle(source) {
|
|
1070
|
+
return source.startsWith('myscheme://');
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
static get providerName() { return 'MyProvider'; }
|
|
1074
|
+
|
|
1075
|
+
async v2Publish(files, options) {
|
|
1076
|
+
// files.manifest — path to wyvrn.json
|
|
1077
|
+
// files.zip — path to wyvrn.zip
|
|
1078
|
+
// options.source, options.name, options.version, options.profileHash
|
|
1079
|
+
// options.contentSha256, options.gitSha, options.gitRepo
|
|
1080
|
+
// options.buildSettings, options.lockedDependencies
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
async v2Exists(options) {
|
|
1084
|
+
// Return true if this version+profileHash already exists
|
|
1085
|
+
return false;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
module.exports = MyProvider;
|
|
1090
|
+
```
|
|
1091
|
+
|
|
1092
|
+
2. Register it in `src/providers/index.js`:
|
|
1093
|
+
|
|
1094
|
+
```js
|
|
1095
|
+
const MyProvider = require('./myprovider');
|
|
1096
|
+
|
|
1097
|
+
const PROVIDERS = [
|
|
1098
|
+
S3Provider,
|
|
1099
|
+
HttpProvider,
|
|
1100
|
+
FileProvider,
|
|
1101
|
+
MyProvider, // add here
|
|
1102
|
+
];
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
---
|
|
1106
|
+
|
|
1107
|
+
## Registry Layout
|
|
1108
|
+
|
|
1109
|
+
### v2 layout (current)
|
|
1110
|
+
|
|
1111
|
+
Packages published by v2 tooling are stored under a `v2/` prefix, with the profile hash as a sub-directory:
|
|
1112
|
+
|
|
1113
|
+
```
|
|
1114
|
+
{source}/v2/{name}/{version}/{profileHash}/wyvrn.json <- package manifest + metadata
|
|
1115
|
+
{source}/v2/{name}/{version}/{profileHash}/wyvrn.zip <- package archive
|
|
1116
|
+
{source}/v2/{name}/versions.json <- version index
|
|
1117
|
+
{source}/v2/{name}/latest.json <- latest version pointer
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
The profile hash is a 16-character SHA256 prefix computed from the build profile fields. This allows multiple compiler/platform variants of the same version to coexist in the same registry.
|
|
1121
|
+
|
|
1122
|
+
**Example (S3):**
|
|
1123
|
+
|
|
1124
|
+
```
|
|
1125
|
+
s3://my-bucket/packages/v2/OpenSSL/3.0.0.0/a1b2c3d4e5f60718/wyvrn.json
|
|
1126
|
+
s3://my-bucket/packages/v2/OpenSSL/3.0.0.0/a1b2c3d4e5f60718/wyvrn.zip
|
|
1127
|
+
```
|
|
1128
|
+
|
|
1129
|
+
### v1 layout (legacy)
|
|
1130
|
+
|
|
1131
|
+
v2 tooling also dual-publishes to the v1 path so that older clients can still consume packages:
|
|
1132
|
+
|
|
1133
|
+
```
|
|
1134
|
+
{source}/{platform}/{name}/{version}/wyvrn.json
|
|
1135
|
+
{source}/{platform}/{name}/{version}/wyvrn.zip
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
**Example (HTTP):**
|
|
1139
|
+
|
|
1140
|
+
```
|
|
1141
|
+
https://pkg.corp.com/win_x64/OpenSSL/3.0.0.0/wyvrn.json
|
|
1142
|
+
https://pkg.corp.com/win_x64/OpenSSL/3.0.0.0/wyvrn.zip
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
The tool also falls back to `razer.json` / `razer.zip` for legacy compatibility.
|
|
1146
|
+
|
|
1147
|
+
### Package manifest (wyvrn.json hosted on source)
|
|
1148
|
+
|
|
1149
|
+
```json
|
|
1150
|
+
{
|
|
1151
|
+
"Name": "OpenSSL",
|
|
1152
|
+
"Version": "3.0.0.0",
|
|
1153
|
+
"Description": "TLS/SSL toolkit",
|
|
1154
|
+
"Dependencies": [
|
|
1155
|
+
{ "Name": "zlib", "Version": "1.3.0.0" }
|
|
1156
|
+
]
|
|
1157
|
+
}
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
Fields use PascalCase. `Dependencies` is an array — transitive dependencies are resolved automatically.
|
|
1161
|
+
|
|
1162
|
+
---
|
|
1163
|
+
|
|
1164
|
+
## Project Manifest (wyvrn.json)
|
|
1165
|
+
|
|
1166
|
+
```json
|
|
1167
|
+
{
|
|
1168
|
+
"name": "my-app",
|
|
1169
|
+
"version": "1.0.0.0",
|
|
1170
|
+
"description": "My C++ application",
|
|
1171
|
+
"kind": "ConsoleApp",
|
|
1172
|
+
"dependencies": {
|
|
1173
|
+
"OpenSSL": "3.0.0.0",
|
|
1174
|
+
"zlib": {
|
|
1175
|
+
"version": "1.3.0.0",
|
|
1176
|
+
"settings": {
|
|
1177
|
+
"compiler.runtime": "static"
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
**`kind` values:** `ConsoleApp`, `StaticLib`, `DynamicLib`, `HeaderOnlyLib`, `WebApp`, `Utility`, `Service`, `TestProject`
|
|
1185
|
+
|
|
1186
|
+
**`dependencies`** can be either a plain version string (`"major.minor.patch.build"`) or an object with `version`, an optional `settings` map, and an optional `options` map. The `settings` map overrides individual build profile fields for that specific dependency — useful when a dependency must be consumed with a different runtime linkage or C++ standard than your default profile. The `options` map is covered in the next section.
|
|
1187
|
+
|
|
1188
|
+
### Version ranges
|
|
1189
|
+
|
|
1190
|
+
The `version` field accepts ranges in addition to exact versions and the `"latest"` tag:
|
|
1191
|
+
|
|
1192
|
+
| Spec | Meaning |
|
|
1193
|
+
|---|---|
|
|
1194
|
+
| `"1.2.3.4"` | exact — must match byte-identically |
|
|
1195
|
+
| `"latest"` | resolves to whatever `latest.json` points at |
|
|
1196
|
+
| `"^1.2.3.4"` | major-pinned — `>= 1.2.3.4` and `< 2.0.0.0` |
|
|
1197
|
+
| `"~1.2.3.4"` | minor-pinned — `>= 1.2.3.4` and `< 1.3.0.0` |
|
|
1198
|
+
| `">=1.2.3.4 <2.0.0.0"` | explicit comparators — space-separated, supports `>=`, `>`, `<=`, `<`, `=` |
|
|
1199
|
+
|
|
1200
|
+
Ranges resolve at install time against each source's `versions.json`. wyvrnpm picks the **highest version** that satisfies the range. The resolved exact version is pinned into `wyvrn.lock` alongside the original range string, so re-installs are byte-reproducible — ranges are only re-evaluated when the lock file's entry for that dependency is removed.
|
|
1201
|
+
|
|
1202
|
+
**Error handling:**
|
|
1203
|
+
|
|
1204
|
+
- **No version satisfies the range** → strict failure with every published version listed so you can see what's available.
|
|
1205
|
+
- **Conflicting ranges across the graph** (direct consumer wants `^1.x` but a transitive wants `^2.x`) → precise error naming both contributors and their ranges.
|
|
1206
|
+
- **Malformed range string** → fail fast with a cheat-sheet of supported syntaxes.
|
|
1207
|
+
|
|
1208
|
+
Example:
|
|
1209
|
+
|
|
1210
|
+
```json
|
|
1211
|
+
{
|
|
1212
|
+
"dependencies": {
|
|
1213
|
+
"OpenSSL": "^3.0.0.0",
|
|
1214
|
+
"zlib": "~1.3.0.0",
|
|
1215
|
+
"boost": ">=1.80.0.0 <2.0.0.0"
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
```
|
|
1219
|
+
|
|
1220
|
+
### Per-dependency source pin (2.8.0+)
|
|
1221
|
+
|
|
1222
|
+
When you have more than one configured install source (e.g. a primary S3 bucket plus a mirror), you can pin a security-sensitive dep to its canonical source by name:
|
|
1223
|
+
|
|
1224
|
+
```json
|
|
1225
|
+
{
|
|
1226
|
+
"dependencies": {
|
|
1227
|
+
"OpenSSL": {
|
|
1228
|
+
"version": "3.0.0.0",
|
|
1229
|
+
"source": "primary-s3"
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
```
|
|
1234
|
+
|
|
1235
|
+
`"primary-s3"` must match a `name` from `wyvrnpm configure list`; an unknown name fails install with exit code 1 rather than silently fanning out. The pin closes two common multi-source holes:
|
|
1236
|
+
|
|
1237
|
+
- **Mirror shadowing.** A package accidentally published to the mirror can't substitute for the primary's copy.
|
|
1238
|
+
- **Dependency confusion.** A squatter on a secondary source can't poison the build.
|
|
1239
|
+
|
|
1240
|
+
Pins are direct-only — they don't cascade to the pinned package's own transitive deps. CLI `--source` overrides config entirely, so on a run with `--source`, any manifest pin is ignored with a warning rather than an error. The lockfile records `source: "<name>"` on pinned entries so reviewers can spot at a glance that the artefact came from the declared source; absent on non-pinned entries so pre-2.8.0 locks remain byte-identical.
|
|
1241
|
+
|
|
1242
|
+
### Pattern-based `settingsOverrides` (2.8.0+)
|
|
1243
|
+
|
|
1244
|
+
When many deps need the same settings override — every `boost-*` family member needing `compiler.cppstd: "17"`, or every `*-debug` variant needing `compiler.runtime: "static"` — declare the pattern at the top level of the manifest instead of copy-pasting per dep:
|
|
1245
|
+
|
|
1246
|
+
```json
|
|
1247
|
+
{
|
|
1248
|
+
"dependencies": {
|
|
1249
|
+
"boost-filesystem": "1.80.0.0",
|
|
1250
|
+
"boost-system": "1.80.0.0",
|
|
1251
|
+
"boost-thread": "1.80.0.0",
|
|
1252
|
+
"zlib": "1.3.0.0"
|
|
1253
|
+
},
|
|
1254
|
+
"settingsOverrides": {
|
|
1255
|
+
"boost*": { "compiler.cppstd": "17" },
|
|
1256
|
+
"*-debug": { "compiler.runtime": "static" }
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
```
|
|
1260
|
+
|
|
1261
|
+
Rules:
|
|
1262
|
+
|
|
1263
|
+
- Keys are globs — `*` matches any chars, `?` matches exactly one, literal names work too. Both ends are anchored (no substring match unless you add `*` on either side).
|
|
1264
|
+
- Values accept the same keys as profile overrides: `os`, `arch`, `compiler`, `compiler.version`, `compiler.cppstd`, `compiler.runtime`. Unknown keys fail install with a clear error.
|
|
1265
|
+
- More-specific patterns win: literal `"boost-filesystem"` beats `"boost*"`, which beats `"*"`.
|
|
1266
|
+
- A literal per-dep `settings` block inside `dependencies` still wins over any pattern. Use that for the one dep that deviates from the family rule.
|
|
1267
|
+
|
|
1268
|
+
Each matching pattern shifts that dep's `profileHash`, so different settings produce distinct registry artefacts — identical semantics to literal per-dep `settings`.
|
|
1269
|
+
|
|
1270
|
+
### Package options (`options`)
|
|
1271
|
+
|
|
1272
|
+
A library author can declare **options** — compile-time feature toggles that change the produced binary's ABI. Examples: `shared` (shared vs static library), `minizip` (zlib's minizip support), `fips` (OpenSSL's FIPS mode). Each option produces a distinct `profileHash`, so every option combination gets its own artefact on the registry.
|
|
1273
|
+
|
|
1274
|
+
**Author side — declare in the recipe's `wyvrn.json`:**
|
|
1275
|
+
|
|
1276
|
+
```json
|
|
1277
|
+
{
|
|
1278
|
+
"name": "zlib",
|
|
1279
|
+
"version": "1.3.0.0",
|
|
1280
|
+
"options": {
|
|
1281
|
+
"shared": { "default": false, "allowed": [true, false] },
|
|
1282
|
+
"minizip": { "default": true, "allowed": [true, false] },
|
|
1283
|
+
"api": { "default": "default", "allowed": ["default", "legacy"] }
|
|
1284
|
+
},
|
|
1285
|
+
"build": {
|
|
1286
|
+
"configure": [
|
|
1287
|
+
"-DBUILD_SHARED_LIBS=${options.shared}",
|
|
1288
|
+
"-DZLIB_BUILD_MINIZIP=${options.minizip}",
|
|
1289
|
+
"-DZLIB_API_MODE=${options.api}"
|
|
1290
|
+
]
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
```
|
|
1294
|
+
|
|
1295
|
+
Rules for the declaration:
|
|
1296
|
+
|
|
1297
|
+
- Option names must match `/^[a-z][a-z0-9_-]*$/`.
|
|
1298
|
+
- Each option needs `default` + `allowed`. `default` must be a member of `allowed`.
|
|
1299
|
+
- `allowed` values are `boolean` or `string`. No integers, no lists.
|
|
1300
|
+
- `${options.<name>}` tokens in `build.configure` / `build.buildArgs` are expanded at source-build time. Booleans expand to `ON`/`OFF`; strings expand verbatim. A typo (`${options.fips}` with no `fips` declared) is a hard error — it will not silently reach CMake.
|
|
1301
|
+
|
|
1302
|
+
**Consumer side — override per dependency:**
|
|
1303
|
+
|
|
1304
|
+
```json
|
|
1305
|
+
{
|
|
1306
|
+
"dependencies": {
|
|
1307
|
+
"zlib": {
|
|
1308
|
+
"version": "1.3.0.0",
|
|
1309
|
+
"options": { "minizip": false }
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
```
|
|
1314
|
+
|
|
1315
|
+
**Consumer side — override via CLI (precedence: CLI > wyvrn.json > recipe defaults):**
|
|
1316
|
+
|
|
1317
|
+
```bash
|
|
1318
|
+
wyvrnpm install -o zlib:minizip=false -o zlib:shared=true
|
|
1319
|
+
wyvrnpm publish -o zlib:minizip=false # publishing a specific variant
|
|
1320
|
+
```
|
|
1321
|
+
|
|
1322
|
+
Option overrides are validated against the recipe's `allowed` list at resolve time; unknown option names surface a "did you mean?" suggestion.
|
|
1323
|
+
|
|
1324
|
+
**What happens on the registry.** Options fold into `profileHash`, so `zlib@1.3.0.0` with `minizip=true` and `zlib@1.3.0.0` with `minizip=false` are two distinct artefacts at two different URLs — same version, different hashes. `wyvrnpm show zlib@1.3.0.0` lists all published variants and prints each one's resolved options.
|
|
1325
|
+
|
|
1326
|
+
**Backward compatibility.** Packages that do not declare an `options` block hash byte-identically to how they did before options existed. No registry migration required.
|
|
1327
|
+
|
|
1328
|
+
### Source-build recipe (`build`)
|
|
1329
|
+
|
|
1330
|
+
A library package may include an optional `build` section that tells `wyvrnpm install --build=missing` how to rebuild it from source. Only `system: "cmake"` is supported today.
|
|
1331
|
+
|
|
1332
|
+
```json
|
|
1333
|
+
{
|
|
1334
|
+
"name": "zlib",
|
|
1335
|
+
"version": "1.3.0.0",
|
|
1336
|
+
"kind": "StaticLib",
|
|
1337
|
+
"build": {
|
|
1338
|
+
"system": "cmake",
|
|
1339
|
+
"generator": ["Ninja", "Visual Studio 17 2022"],
|
|
1340
|
+
"configs": ["Release", "Debug"],
|
|
1341
|
+
"configure": ["-DZLIB_BUILD_EXAMPLES=OFF"],
|
|
1342
|
+
"buildArgs": ["--parallel"],
|
|
1343
|
+
"installDir": "install",
|
|
1344
|
+
"sourceSubdir": "."
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
```
|
|
1348
|
+
|
|
1349
|
+
| Field | Default | Description |
|
|
1350
|
+
|---|---|---|
|
|
1351
|
+
| `system` | `cmake` | Build system. Only `cmake` is supported. |
|
|
1352
|
+
| `generator` | *(CMake default)* | Single generator (`"Ninja"`) or an array tried in order — first available wins. |
|
|
1353
|
+
| `configs` | `["Debug","Release","RelWithDebInfo","MinSizeRel"]` | CMake configurations to build and install. |
|
|
1354
|
+
| `configure` | `[]` | Extra args appended to `cmake` at configure time. |
|
|
1355
|
+
| `buildArgs` | `[]` | Extra args appended to `cmake --build`. |
|
|
1356
|
+
| `installDir` | `install` | Install prefix relative to the binary dir. |
|
|
1357
|
+
| `sourceSubdir` | `.` | Where `CMakeLists.txt` lives relative to the clone root. |
|
|
1358
|
+
| `requiredTools` | `[]` | Tools that must be on `PATH` before the build starts (fail-fast check). |
|
|
1359
|
+
|
|
1360
|
+
On Windows with MSVC and a non-Visual-Studio generator (Ninja, Make), `vcvarsall.bat` is auto-activated for the spawned CMake process — no need to launch from a Developer Prompt.
|
|
1361
|
+
|
|
1362
|
+
---
|
|
1363
|
+
|
|
1364
|
+
## Build-time configuration (`conf`)
|
|
1365
|
+
|
|
1366
|
+
`conf` is wyvrnpm's channel for **non-ABI** build-time knobs — CMake cache variables, feature toggles that change `add_subdirectory()` but not the public binary, and (in future phases) other build-tool settings. It is a deliberate sibling of `options`, with the opposite hashing property:
|
|
1367
|
+
|
|
1368
|
+
| | `options` (F1) | `conf` (this section) |
|
|
1369
|
+
|---|---|---|
|
|
1370
|
+
| Folds into `profileHash`? | Yes — every combination is a distinct registry artefact. | **No.** Informational only; two builds with different `conf` still share the same `profileHash`. |
|
|
1371
|
+
| Typical use | `shared`/`minizip`/`fips` — things that genuinely change the binary. | `CHROMA_ENABLE_TEST`, `BUILD_DOCS`, `CMAKE_EXPORT_COMPILE_COMMANDS` — things that don't. |
|
|
1372
|
+
| Consumer can override? | Yes (per-dep `options` in `wyvrn.json` or `-o pkg:name=val` on CLI). | Yes (recipe → named-profile `conf` → `wyvrn.local.json` → `--conf`, in that precedence). |
|
|
1373
|
+
|
|
1374
|
+
Phase 1 (2.6.0+) supports a single namespace: `cmake.cache.<VAR>`. It flows into the generated `CMakePresets.json`'s `cacheVariables`.
|
|
1375
|
+
|
|
1376
|
+
### The four layers
|
|
1377
|
+
|
|
1378
|
+
```
|
|
1379
|
+
highest CLI --conf cmake.cache.X=ON
|
|
1380
|
+
│ ─────
|
|
1381
|
+
│ local wyvrn.local.json (per-developer, gitignored)
|
|
1382
|
+
│ ─────
|
|
1383
|
+
│ profile named-profile JSON.conf (team-shared, checked-in)
|
|
1384
|
+
│ ─────
|
|
1385
|
+
│ recipe wyvrn.json.conf (author defaults)
|
|
1386
|
+
▼ ─────
|
|
1387
|
+
lowest (nothing — key absent)
|
|
1388
|
+
```
|
|
1389
|
+
|
|
1390
|
+
**Per-leaf override, not per-branch replace.** A CLI `--conf cmake.cache.FOO=ON` on top of a recipe setting `BAR=OFF` yields both keys — it does not discard `BAR`. Any omitted layer is equivalent to an empty map at that position — a project with no `wyvrn.local.json` and no profile `conf` merges recipe + CLI exactly as phase 1.
|
|
1391
|
+
|
|
1392
|
+
### Recipe-level defaults
|
|
1393
|
+
|
|
1394
|
+
Authors can declare defaults on their package:
|
|
1395
|
+
|
|
1396
|
+
```json
|
|
1397
|
+
{
|
|
1398
|
+
"name": "ChromaSDK",
|
|
1399
|
+
"version": "2.5.0.0",
|
|
1400
|
+
"conf": {
|
|
1401
|
+
"cmake": {
|
|
1402
|
+
"cache": {
|
|
1403
|
+
"CHROMA_ENABLE_TEST": "OFF",
|
|
1404
|
+
"CHROMA_ENABLE_EXAMPLES": "OFF",
|
|
1405
|
+
"CHROMA_LOG_LEVEL": "WARNING"
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
```
|
|
1411
|
+
|
|
1412
|
+
`true`/`false` in the JSON are normalised to CMake `"ON"`/`"OFF"`; numbers are stringified; strings pass through.
|
|
1413
|
+
|
|
1414
|
+
### Per-developer overlay — `wyvrn.local.json`
|
|
1415
|
+
|
|
1416
|
+
Drop a `wyvrn.local.json` next to `wyvrn.json` for per-machine overrides. `wyvrnpm init` scaffolds a `.gitignore` entry for new projects; existing projects get a one-line nudge on `wyvrnpm install` when the file is present but not ignored.
|
|
1417
|
+
|
|
1418
|
+
```json
|
|
1419
|
+
{
|
|
1420
|
+
"conf": {
|
|
1421
|
+
"cmake": {
|
|
1422
|
+
"cache": {
|
|
1423
|
+
"CHROMA_ENABLE_TEST": "ON",
|
|
1424
|
+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
},
|
|
1428
|
+
"binaryDirRoot": "cmake-out"
|
|
1429
|
+
}
|
|
1430
|
+
```
|
|
1431
|
+
|
|
1432
|
+
Top-level allow-list: `conf` (build-time knobs — see above) and `binaryDirRoot` (build-tree subdir — see below). Anything else is a hard error, foreclosing the silent-inert footgun where a user writes `{ "dependencies": {...} }` expecting local dep overrides.
|
|
1433
|
+
|
|
1434
|
+
**`binaryDirRoot`** (`2.12.0+`) — overrides the default `build/` subdir the generated preset configures into. The preset's `binaryDir` becomes `${sourceDir}/<binaryDirRoot>/wyvrn-<profile>`; `wyvrnpm build` mirrors the same value so `cmake --build <dir>` lands at the matching path. CLI flag `--build-dir <path>` is the one-shot equivalent (CI, ad-hoc); the overlay is the persistent answer for repos that always need the override.
|
|
1435
|
+
|
|
1436
|
+
Why this exists: repos with a `BUILD` Bazel/Buck file at the root collide with `build/` on case-insensitive filesystems (Windows NTFS, default macOS HFS+) — `cmake` cannot create a `build/wyvrn-default` subdirectory because Windows' filesystem treats `BUILD` (the Bazel file) and `build` (the wanted directory) as the same name. **gRPC** is the canonical case. Setting `binaryDirRoot: "cmake-out"` sidesteps the collision entirely.
|
|
1437
|
+
|
|
1438
|
+
Validation: must be a relative path, no absolute / drive-letter prefixes, no `..` segments, no empty value. Backslashes normalise to forward slashes; trailing separators stripped. Lockfile / `profileHash` / published artefacts are unaffected — the value is read at install time only and never written to the registry.
|
|
1439
|
+
|
|
1440
|
+
### Team-shared overlay — named-profile `conf` (phase 2, 2.7.0+)
|
|
1441
|
+
|
|
1442
|
+
When every developer on a team would end up with the same `wyvrn.local.json`, check that shared policy into the named profile instead. A saved profile (e.g. `%LOCALAPPDATA%\wyvrnpm\profiles\team-default.json`) may carry an optional top-level `conf` block alongside its `[settings]`:
|
|
1443
|
+
|
|
1444
|
+
```json
|
|
1445
|
+
{
|
|
1446
|
+
"os": "Windows",
|
|
1447
|
+
"arch": "x86_64",
|
|
1448
|
+
"compiler": "msvc",
|
|
1449
|
+
"compiler.version": "193",
|
|
1450
|
+
"compiler.cppstd": "20",
|
|
1451
|
+
"compiler.runtime": "dynamic",
|
|
1452
|
+
"conf": {
|
|
1453
|
+
"cmake": {
|
|
1454
|
+
"cache": {
|
|
1455
|
+
"CHROMA_ENABLE_SANITIZERS": "OFF",
|
|
1456
|
+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
```
|
|
1462
|
+
|
|
1463
|
+
Edit via the `configure profile set` convenience (repeatable, same `KEY=VAL` / bare-`KEY` / `KEY=` syntax as the other CLI sinks):
|
|
1464
|
+
|
|
1465
|
+
```bash
|
|
1466
|
+
wyvrnpm configure profile set --name team-default --conf cmake.cache.CMAKE_EXPORT_COMPILE_COMMANDS=ON
|
|
1467
|
+
wyvrnpm configure profile set --name team-default --conf cmake.cache.LEGACY_FLAG= # clears it
|
|
1468
|
+
```
|
|
1469
|
+
|
|
1470
|
+
Profile `conf` layers **between recipe and local**: a project's `wyvrn.local.json` (the individual override) still wins over team defaults, and CLI `--conf` still wins over everything. The distinction Conan makes between the `[conf]` block in a profile and the `-c` CLI flag maps directly onto this precedence.
|
|
1471
|
+
|
|
1472
|
+
Profile `conf` is **non-ABI**: adding or changing keys inside it does NOT shift `profileHash`, so switching a team policy between `ENABLE_SANITIZERS=ON` and `=OFF` does not invalidate already-downloaded artefacts. The invariant is locked in by `tests/profile-hash.test.js`.
|
|
1473
|
+
|
|
1474
|
+
Auto-detected profiles (when no on-disk profile file exists) never inject a `conf` layer — detection is about `[settings]` only.
|
|
1475
|
+
|
|
1476
|
+
### CLI — ad-hoc, one invocation
|
|
1477
|
+
|
|
1478
|
+
```bash
|
|
1479
|
+
# Single toggle
|
|
1480
|
+
wyvrnpm build --conf cmake.cache.CHROMA_ENABLE_TEST=ON
|
|
1481
|
+
|
|
1482
|
+
# Repeatable
|
|
1483
|
+
wyvrnpm build \
|
|
1484
|
+
--conf cmake.cache.CHROMA_ENABLE_TEST=ON \
|
|
1485
|
+
--conf cmake.cache.BUILD_DOCS=OFF
|
|
1486
|
+
|
|
1487
|
+
# Bare KEY is sugar for KEY=ON (CMake -D convention)
|
|
1488
|
+
wyvrnpm build --conf cmake.cache.CHROMA_ENABLE_TEST
|
|
1489
|
+
|
|
1490
|
+
# KEY= (empty RHS) clears a value inherited from a lower layer
|
|
1491
|
+
wyvrnpm build --conf cmake.cache.CHROMA_ENABLE_TEST=
|
|
1492
|
+
|
|
1493
|
+
# Also honoured on install and publish (publish records it as
|
|
1494
|
+
# `publishedConf` on the uploaded manifest — informational metadata
|
|
1495
|
+
# that `wyvrnpm show` surfaces).
|
|
1496
|
+
wyvrnpm install --conf cmake.cache.CHROMA_ENABLE_TEST=ON
|
|
1497
|
+
wyvrnpm publish --conf cmake.cache.BUILD_DOCS=OFF
|
|
1498
|
+
```
|
|
1499
|
+
|
|
1500
|
+
`--conf` on `wyvrnpm build` passes through to `cmake --preset` as `-D` / `-U` overrides **for that invocation only** — it does not regenerate `CMakePresets.json`. Persistent per-machine overrides belong in `wyvrn.local.json`; `wyvrnpm install` regenerates the preset deterministically with the overlay applied.
|
|
1501
|
+
|
|
1502
|
+
### Lockfile semantics
|
|
1503
|
+
|
|
1504
|
+
`wyvrn.lock` gains an informational `effectiveConf` block after each install:
|
|
1505
|
+
|
|
1506
|
+
```json
|
|
1507
|
+
{
|
|
1508
|
+
"wyvrnVersion": 2,
|
|
1509
|
+
"profileHash": "a1b2c3d4e5f60718",
|
|
1510
|
+
"effectiveConf": {
|
|
1511
|
+
"cmake": { "cache": { "CHROMA_ENABLE_TEST": "ON" } }
|
|
1512
|
+
},
|
|
1513
|
+
"packages": { ... }
|
|
1514
|
+
}
|
|
1515
|
+
```
|
|
1516
|
+
|
|
1517
|
+
This is diagnostic only — changing `conf` between installs shows up as a lockfile diff but never causes a relock or version change. Conf drift is a legitimate review signal, not an error.
|
|
1518
|
+
|
|
1519
|
+
### Source-build boundary
|
|
1520
|
+
|
|
1521
|
+
When `--build=missing` or `--build=always` source-builds a dependency, **only that dep's own recipe `conf`** flows into its CMake invocation. The root project's merged conf (including `wyvrn.local.json`, named-profile `conf`, and CLI `--conf`) never reaches a dep's source-build. This preserves cross-consumer reproducibility — two developers source-building the same `(name, version, profileHash)` produce the same binary regardless of their local overlays or team profile, which is load-bearing for `--upload-built`.
|
|
1522
|
+
|
|
1523
|
+
### Why this isn't `build.configure`
|
|
1524
|
+
|
|
1525
|
+
Existing authors using `build.configure: ["-DFOO=ON", "-DBAR=OFF"]` keep working unchanged. But `build.configure` has two weaknesses `conf` fixes:
|
|
1526
|
+
|
|
1527
|
+
1. **All-or-nothing.** A consumer can't disable one flag without overriding the whole array.
|
|
1528
|
+
2. **Opaque strings.** `"-DFOO=ON"` is parsed at configure time, not at manifest load.
|
|
1529
|
+
|
|
1530
|
+
Recipe authors writing new packages should prefer `conf.cmake.cache.FOO=ON` for cache variables and keep `build.configure` for non-cache args like `-G`, `-T`, or `-A`. Setting the same KEY in both `build.configure` (`-DKEY=...`) AND `conf.cmake.cache.KEY` is a recipe-normalise error — pick one route.
|
|
1531
|
+
|
|
1532
|
+
---
|
|
1533
|
+
|
|
1534
|
+
## Compatibility Rules
|
|
1535
|
+
|
|
1536
|
+
Publishers declare an optional `compatibility` block in a package's `wyvrn.json`. It tells wyvrnpm which profile fields must match the consumer's profile exactly, and which may legitimately differ without breaking ABI. When no exact `profileHash` match exists on the registry, `install` evaluates this block against every published build for the requested `(name, version)` and picks the best compatible candidate.
|
|
1537
|
+
|
|
1538
|
+
### Block format
|
|
1539
|
+
|
|
1540
|
+
Each field maps to a mode — either as a string shorthand or an object:
|
|
1541
|
+
|
|
1542
|
+
```json
|
|
1543
|
+
{
|
|
1544
|
+
"name": "zlib",
|
|
1545
|
+
"version": "1.3.0.0",
|
|
1546
|
+
"compatibility": {
|
|
1547
|
+
"compiler.cppstd": "lte",
|
|
1548
|
+
"compiler.runtime": "exact",
|
|
1549
|
+
"compiler.version": "exact-or-newer"
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
```
|
|
1553
|
+
|
|
1554
|
+
Object form is accepted too (`{ "mode": "lte" }`) and leaves room for future per-field options.
|
|
1555
|
+
|
|
1556
|
+
### Supported modes
|
|
1557
|
+
|
|
1558
|
+
| Mode | Meaning |
|
|
1559
|
+
|---|---|
|
|
1560
|
+
| `exact` | Package and consumer values must be equal. |
|
|
1561
|
+
| `any` | Field is ignored for compatibility purposes. |
|
|
1562
|
+
| `lte` | Package value ≤ consumer value — e.g. a `cppstd=20` package is usable by a `cppstd=23` consumer. |
|
|
1563
|
+
| `gte` | Package value ≥ consumer value (symmetry; rarely useful). |
|
|
1564
|
+
| `exact-or-newer` | Same as `lte` at MVP — kept as a distinct name because it reads naturally for compiler-version fields. |
|
|
1565
|
+
|
|
1566
|
+
**Defaults:**
|
|
1567
|
+
|
|
1568
|
+
- Any field not listed is treated as `exact`.
|
|
1569
|
+
- `os` and `arch` are **always `exact`** regardless of what the block says. Cross-OS / cross-arch binaries are never ABI-compatible.
|
|
1570
|
+
|
|
1571
|
+
### Where to author it
|
|
1572
|
+
|
|
1573
|
+
The block lives in the **source** `wyvrn.json` (the one you commit). It is read at publish time and written into the uploaded manifest. If the source `wyvrn.json` has no `compatibility` block, `wyvrnpm publish` injects a conservative default (all fields `exact`) so existing packages behave strict-by-default.
|
|
1574
|
+
|
|
1575
|
+
Consumers never author compatibility — it is a property of the published package.
|
|
1576
|
+
|
|
1577
|
+
### Tiebreaker
|
|
1578
|
+
|
|
1579
|
+
When multiple published builds satisfy the consumer's profile, the winner is picked deterministically:
|
|
1580
|
+
|
|
1581
|
+
1. Prefer the candidate whose `compiler` matches the consumer's.
|
|
1582
|
+
2. Prefer the highest numeric `compiler.version`.
|
|
1583
|
+
3. Prefer the candidate whose `compiler.runtime` matches the consumer's.
|
|
1584
|
+
4. Fall back to the lexicographically earliest `profileHash`.
|
|
1585
|
+
|
|
1586
|
+
The chosen candidate is logged along with a per-field summary (e.g. `compiler.cppstd 20→23 (lte), compiler.runtime=dynamic`).
|
|
1587
|
+
|
|
1588
|
+
---
|
|
1589
|
+
|
|
1590
|
+
## Source Builds
|
|
1591
|
+
|
|
1592
|
+
`wyvrnpm install --build=missing` clones a package's source at its published `gitSha` and builds it locally when no prebuilt binary matches (exact or compatible) the consumer's profile. This is the Conan-2.0 `--build=missing` parity feature.
|
|
1593
|
+
|
|
1594
|
+
### When it fires
|
|
1595
|
+
|
|
1596
|
+
1. You run `wyvrnpm install --build=missing`.
|
|
1597
|
+
2. For each dependency, wyvrnpm tries `v2 exact → v2 compat` first.
|
|
1598
|
+
3. If neither hits, it looks up `gitRepo` + `gitSha` from **any** existing build of the same `(name, version)` on the registry (they are equal across profiles for a given version).
|
|
1599
|
+
4. It clones, resolves the package's own transitive deps, invokes CMake through the shared toolchain generator, zips the install dir, and treats the result as a v2 download.
|
|
1600
|
+
|
|
1601
|
+
If the package has no prior publish on the registry at all, there is no `gitSha` to clone — source-build fails fast with a clear error. Source-builds cascade transitively: if package A needs source-build and depends on package B which also needs source-build, both are built.
|
|
1602
|
+
|
|
1603
|
+
### Authoring the `build` recipe
|
|
1604
|
+
|
|
1605
|
+
Libraries that want to be source-buildable declare a `build` section in their own `wyvrn.json`. See [Project Manifest §Source-build recipe](#source-build-recipe-build) for the field list. Only `system: "cmake"` is supported today.
|
|
1606
|
+
|
|
1607
|
+
### Generator fallback
|
|
1608
|
+
|
|
1609
|
+
`build.generator` accepts either a string or an array:
|
|
1610
|
+
|
|
1611
|
+
| Form | Behaviour |
|
|
1612
|
+
|---|---|
|
|
1613
|
+
| `"Ninja"` | Strict — fails if Ninja is not available. |
|
|
1614
|
+
| `["Ninja", "Visual Studio 17 2022"]` | Tried in order — first available wins. Unknown entries are trusted (CMake decides at configure time). |
|
|
1615
|
+
| *(omitted)* | Uses CMake's platform default. |
|
|
1616
|
+
|
|
1617
|
+
### MSVC environment auto-activation (Windows)
|
|
1618
|
+
|
|
1619
|
+
On Windows, when **all** of the following hold:
|
|
1620
|
+
|
|
1621
|
+
- `profile.compiler === "msvc"`
|
|
1622
|
+
- The chosen generator is **not** a Visual Studio generator (e.g. Ninja, Make)
|
|
1623
|
+
- `cl.exe` is not on `PATH`
|
|
1624
|
+
|
|
1625
|
+
…wyvrnpm locates Visual Studio via `vswhere.exe`, runs `vcvarsall.bat <arch>` in a sub-shell, captures the resulting environment, and uses it for the CMake spawn. You do not need to launch from a Developer Prompt.
|
|
1626
|
+
|
|
1627
|
+
Arch mapping follows the active profile:
|
|
1628
|
+
|
|
1629
|
+
| `profile.arch` | `vcvarsall` arg |
|
|
1630
|
+
|---|---|
|
|
1631
|
+
| `x86_64` | `x64` |
|
|
1632
|
+
| `x86` | `x86` |
|
|
1633
|
+
| `armv8` | `arm64` |
|
|
1634
|
+
| `armv7` | `arm` |
|
|
1635
|
+
|
|
1636
|
+
VS generators skip this path entirely — MSBuild resolves MSVC itself.
|
|
1637
|
+
|
|
1638
|
+
### Cache
|
|
1639
|
+
|
|
1640
|
+
Source builds are cached machine-wide, keyed by `(name, version, profileHash)`:
|
|
1641
|
+
|
|
1642
|
+
| Platform | Path |
|
|
1643
|
+
|---|---|
|
|
1644
|
+
| Windows | `%LOCALAPPDATA%\wyvrnpm\bc\{name}-{version}-{profileHash}\` |
|
|
1645
|
+
| Linux / macOS | `~/.cache/wyvrnpm/bc/{name}-{version}-{profileHash}/` |
|
|
1646
|
+
|
|
1647
|
+
Re-running `install --build=missing` with the same inputs short-circuits to the cached artefact. The cache root is deliberately shallow (`bc/`, not `build-cache/`) to keep nested CMake paths under Windows' 260-char limit.
|
|
1648
|
+
|
|
1649
|
+
`--build=always` (2.5.0+) ignores every registry-binary path — exact-match, compat-match, and any already-extracted `wyvrn_internal/{name}/` — and forces a source-build for every dep. Useful for debugging whether a registry binary differs from what the current source tree would produce, or for reproducibility verification. The build-cache short-circuit still applies: re-running `--build=always` with unchanged inputs completes in seconds.
|
|
1650
|
+
|
|
1651
|
+
Clone behaviour is tri-tier:
|
|
1652
|
+
|
|
1653
|
+
1. **Shallow-SHA fetch** (`git fetch origin <sha> --depth=1`) — fastest; works when the git server allows it.
|
|
1654
|
+
2. **Full fetch** — falls back to a full `git clone --tags` when the server rejects shallow-SHA (older Bitbucket installs disable `uploadpack.allowReachableSHA1InWant`).
|
|
1655
|
+
3. **Rebuild from scratch** — if the cached clone is broken, wipes and retries.
|
|
1656
|
+
|
|
1657
|
+
After every clone/fetch, wyvrnpm runs `git cat-file -e <sha>^{commit}` to verify the SHA is actually reachable. If it is not, the error points at the likely cause: the publisher forgot to push before running `wyvrnpm publish`.
|
|
1658
|
+
|
|
1659
|
+
### Publish-time guard
|
|
1660
|
+
|
|
1661
|
+
To catch the unpushed-commit case before consumers hit it, `wyvrnpm publish` checks whether the current `HEAD` is reachable from any remote branch or tag and warns if it is not:
|
|
1662
|
+
|
|
1663
|
+
```
|
|
1664
|
+
[wyvrn] warn: git SHA abc1234 is not on origin — source-build consumers will fail until pushed
|
|
1665
|
+
```
|
|
1666
|
+
|
|
1667
|
+
The warning does **not** block publishing.
|
|
1668
|
+
|
|
1669
|
+
### Header-only libraries
|
|
1670
|
+
|
|
1671
|
+
`kind: "HeaderOnlyLib"` packages still need a `build` section and a CMake `install()` rule that copies headers. There is no fast-path that zips the source tree directly — consumers get exactly what the `install()` step produces, same as any other kind.
|
|
1672
|
+
|
|
1673
|
+
### Clearing the cache
|
|
1674
|
+
|
|
1675
|
+
```bash
|
|
1676
|
+
# Remove the project-local cache (wyvrn_internal/ + wyvrn.lock)
|
|
1677
|
+
wyvrnpm clean
|
|
1678
|
+
|
|
1679
|
+
# Also wipe the machine-wide source-build cache
|
|
1680
|
+
wyvrnpm clean --build-cache
|
|
1681
|
+
```
|
|
1682
|
+
|
|
1683
|
+
### Credentials for private repos
|
|
1684
|
+
|
|
1685
|
+
wyvrnpm uses your ambient git configuration (SSH keys, credential helpers, Windows Credential Manager). It does not manage git credentials itself. If `git clone <gitRepo>` works from your shell, source-build works.
|
|
1686
|
+
|
|
1687
|
+
### Upload back to the registry (`--upload-built`)
|
|
1688
|
+
|
|
1689
|
+
`--build=missing` warms *your* cache. `--build=missing --upload-built` warms the *team's* cache: after a successful source-build, the freshly-zipped artefact is pushed back to the registry under the consumer's `profileHash`, so the next teammate on the same profile gets a direct v2 download.
|
|
1690
|
+
|
|
1691
|
+
```bash
|
|
1692
|
+
# Build missing artefacts locally AND publish them back under your profile.
|
|
1693
|
+
wyvrnpm install --build=missing --upload-built
|
|
1694
|
+
|
|
1695
|
+
# Override the upload destination (URL or configured publish-source name).
|
|
1696
|
+
wyvrnpm install --build=missing --upload-built --upload-source team-s3
|
|
1697
|
+
|
|
1698
|
+
# Upload auth is resolved in order: CLI flag → named-source config → first configured publish source.
|
|
1699
|
+
wyvrnpm install --build=missing --upload-built --aws-profile my-sso
|
|
1700
|
+
wyvrnpm install --build=missing --upload-built --token-env WYVRN_HTTP_TOKEN
|
|
1701
|
+
```
|
|
1702
|
+
|
|
1703
|
+
Semantics:
|
|
1704
|
+
|
|
1705
|
+
- **Opt-in.** Nothing uploads unless `--upload-built` is passed. Requires `--build=missing`.
|
|
1706
|
+
- **Skip if exists.** If `(name, version, profileHash)` already lives on the upload source, the upload is a silent no-op. A consumer cannot overwrite an existing artefact; use `wyvrnpm publish --force` from the source repo for that.
|
|
1707
|
+
- **`latest.json` is untouched.** A consumer upload is a new `profileHash` of an existing version, not a new version release.
|
|
1708
|
+
- **Upload failures never break the install.** The consumer already has a working `wyvrn_internal/` on disk — a broken upload is logged as a warning and the install continues.
|
|
1709
|
+
- **Provenance.** Uploaded manifests carry a small `uploadedBy` block so maintainers can tell consumer builds apart from author publishes:
|
|
1710
|
+
|
|
1711
|
+
```json
|
|
1712
|
+
{
|
|
1713
|
+
"uploadedBy": {
|
|
1714
|
+
"kind": "source-build",
|
|
1715
|
+
"profileHash": "a1b2c3d4e5f60718",
|
|
1716
|
+
"builtFromGit": "https://github.com/madler/zlib",
|
|
1717
|
+
"builtFromSha": "abcdef01...",
|
|
1718
|
+
"uploadedAt": "2026-04-21T12:34:56.789Z",
|
|
1719
|
+
"wyvrnpmVersion": "2.1.0"
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
```
|
|
1723
|
+
|
|
1724
|
+
Absence of `uploadedBy` means the artefact was published by the author via `wyvrnpm publish`.
|
|
1725
|
+
|
|
1726
|
+
At the end of an install with `--upload-built`, a one-line summary is printed:
|
|
1727
|
+
|
|
1728
|
+
```
|
|
1729
|
+
[wyvrn] upload-built summary: 2 artefacts uploaded, 1 skipped (already existed), 0 failed
|
|
1730
|
+
```
|
|
1731
|
+
|
|
1732
|
+
**Trust model.** Registry write auth is the gate — only consumers with credentials for the upload destination can upload at all. The same `v2Publish` path is used as `wyvrnpm publish`, so the resulting artefact is byte-identical in layout. SHA256 verification on the download side protects against in-transit tampering. Uploading deliberately opts into "your machine's build of this package is trusted by everyone else on this profile" — use CI with clean toolchains rather than developer workstations if you care about reproducibility.
|
|
1733
|
+
|
|
1734
|
+
#### Auditing consumer uploads (`wyvrnpm show`)
|
|
1735
|
+
|
|
1736
|
+
Maintainers can list every build of a package and tell author-published artefacts apart from consumer uploads:
|
|
1737
|
+
|
|
1738
|
+
```bash
|
|
1739
|
+
wyvrnpm show zlib # all versions + their profile hashes
|
|
1740
|
+
wyvrnpm show zlib@1.3.0.0 # every profile for that version, with origin + builtFromSha
|
|
1741
|
+
wyvrnpm show zlib@1.3.0.0@a1b2c3d4... # one specific build, full metadata
|
|
1742
|
+
```
|
|
1743
|
+
|
|
1744
|
+
With a version specified, `show` fetches each build's `wyvrn.json` and reports `author publish` or `consumer upload (source-build)` alongside the relevant `uploadedBy` fields. Sources default to the configured install sources; override with `--source <url>`.
|
|
1745
|
+
|
|
1746
|
+
#### Forgetting uploads (`clean --uploaded-built`)
|
|
1747
|
+
|
|
1748
|
+
Each successful upload writes a `.uploaded-to.json` sidecar alongside the cached artefact under `%LOCALAPPDATA%\wyvrnpm\bc\{name}-{version}-{profileHash}\`. It records destination, timestamp, and SHA — purely informational, nothing reads it during install.
|
|
1749
|
+
|
|
1750
|
+
To wipe just those local records (no effect on the registry, the artefact zips, or `wyvrn_internal/`):
|
|
1751
|
+
|
|
1752
|
+
```bash
|
|
1753
|
+
wyvrnpm clean --uploaded-built
|
|
1754
|
+
```
|
|
1755
|
+
|
|
1756
|
+
This is a privacy / local-audit cleanup knob — `clean --build-cache` already removes sidecars as a side effect of nuking the cache.
|
|
1757
|
+
|
|
1758
|
+
---
|
|
1759
|
+
|
|
1760
|
+
## Lock File (wyvrn.lock)
|
|
1761
|
+
|
|
1762
|
+
The v2 lock file records the full build profile alongside the resolved packages:
|
|
1763
|
+
|
|
1764
|
+
```json
|
|
1765
|
+
{
|
|
1766
|
+
"wyvrnVersion": 2,
|
|
1767
|
+
"generatedAt": "2025-01-01T00:00:00.000Z",
|
|
1768
|
+
"platform": "win_x64",
|
|
1769
|
+
"profileName": "default",
|
|
1770
|
+
"profile": {
|
|
1771
|
+
"os": "Windows",
|
|
1772
|
+
"arch": "x86_64",
|
|
1773
|
+
"compiler": "msvc",
|
|
1774
|
+
"compiler.version": "193",
|
|
1775
|
+
"compiler.cppstd": "20",
|
|
1776
|
+
"compiler.runtime": "dynamic"
|
|
1777
|
+
},
|
|
1778
|
+
"profileHash": "a1b2c3d4e5f60718",
|
|
1779
|
+
"packages": {
|
|
1780
|
+
"OpenSSL": {
|
|
1781
|
+
"version": "3.0.0.0",
|
|
1782
|
+
"profileHash": "a1b2c3d4e5f60718",
|
|
1783
|
+
"contentSha256": "abc123...",
|
|
1784
|
+
"gitSha": "def456..."
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
```
|
|
1789
|
+
|
|
1790
|
+
Locked versions always take priority over transitive requests. A warning is printed for every version conflict detected.
|
|
1791
|
+
|
|
1792
|
+
---
|
|
1793
|
+
|
|
1794
|
+
## CMake Integration
|
|
1795
|
+
|
|
1796
|
+
`wyvrnpm install` emits a ready-to-use CMake toolchain alongside the downloaded packages. Most projects only need to run:
|
|
1797
|
+
|
|
1798
|
+
```bash
|
|
1799
|
+
wyvrnpm install
|
|
1800
|
+
wyvrnpm build
|
|
1801
|
+
```
|
|
1802
|
+
|
|
1803
|
+
…which is equivalent to:
|
|
1804
|
+
|
|
1805
|
+
```bash
|
|
1806
|
+
cmake --preset wyvrn-default
|
|
1807
|
+
cmake --build build/wyvrn-default --config Release
|
|
1808
|
+
```
|
|
1809
|
+
|
|
1810
|
+
**Generated files (inside the project)**
|
|
1811
|
+
|
|
1812
|
+
| Path | Purpose |
|
|
1813
|
+
|---|---|
|
|
1814
|
+
| `wyvrn_internal/wyvrn_toolchain.cmake` | Toolchain file — sets `CMAKE_PREFIX_PATH`, compiler/runtime, and standards from the active profile. Include via the preset or `-DCMAKE_TOOLCHAIN_FILE=…`. |
|
|
1815
|
+
| `wyvrn_internal/wyvrn_deps.cmake` | Include **after** `project()` (e.g. `include(${CMAKE_BINARY_DIR}/../wyvrn_internal/wyvrn_deps.cmake)`). Wires `find_package()` calls and defines `wyvrnpm_finalize_targets(<tgt>…)` for runtime DLL copy next to your executable. |
|
|
1816
|
+
| `wyvrn_internal/wyvrn_profile.json` | Snapshot of the profile the toolchain was generated against. |
|
|
1817
|
+
| `CMakePresets.json` / `CMakeUserPresets.json` | `wyvrn-<profile>` configure preset. Regenerating preserves other profiles' presets. |
|
|
1818
|
+
|
|
1819
|
+
**Bundled CMake utilities** (shipped in the npm tarball under `cmake/`) are auto-included by `wyvrn_toolchain.cmake`:
|
|
1820
|
+
|
|
1821
|
+
| File | Provides |
|
|
1822
|
+
|---|---|
|
|
1823
|
+
| `cpp.cmake` | Post-`project()` C++ language defaults. `CMAKE_CXX_STANDARD` is owned by the toolchain (set unconditionally from `profile.compiler.cppstd` before `project()` — a `-DCMAKE_CXX_STANDARD=…` on the cmake CLI cannot override it). |
|
|
1824
|
+
| `variables.cmake` | Platform detection (`WYVRN_PLATFORM_WIN`, …) and compiler flags. |
|
|
1825
|
+
| `options.cmake` | Feature toggles (`WYVRN_ENABLE_LOG`, …). |
|
|
1826
|
+
| `functions.cmake` | `SETUP_LIBRARY` / `SETUP_EXE` plus HAL source-collection helpers. |
|
|
1827
|
+
| `macros.cmake` | `WYVRN_INSTALL_MODULE`, `WYVRN_CONFIGURE_VERSION_HEADER`. |
|
|
1828
|
+
|
|
1829
|
+
**Minimal `CMakeLists.txt`:**
|
|
1830
|
+
|
|
1831
|
+
```cmake
|
|
1832
|
+
cmake_minimum_required(VERSION 3.21)
|
|
1833
|
+
project(my-app CXX)
|
|
1834
|
+
|
|
1835
|
+
include(${CMAKE_SOURCE_DIR}/wyvrn_internal/wyvrn_deps.cmake)
|
|
1836
|
+
|
|
1837
|
+
add_executable(my-app src/main.cpp)
|
|
1838
|
+
target_link_libraries(my-app PRIVATE OpenSSL::SSL zlib::zlib)
|
|
1839
|
+
|
|
1840
|
+
wyvrnpm_finalize_targets(my-app) # copies runtime DLLs next to the .exe
|
|
1841
|
+
```
|
|
1842
|
+
|
|
1843
|
+
---
|
|
1844
|
+
|
|
1845
|
+
## Installing Build Artifacts (`wyvrnpm build --install`)
|
|
1846
|
+
|
|
1847
|
+
`wyvrnpm build --install` runs `cmake --install <binaryDir>` after a successful build, invoking every `install()` rule in your `CMakeLists.txt`. This is the step that produces a redistributable layout (headers + libs + runtime files in a tidy tree) rather than the raw CMake build directory.
|
|
1848
|
+
|
|
1849
|
+
### Typical use
|
|
1850
|
+
|
|
1851
|
+
```bash
|
|
1852
|
+
# Configure, build, and install to the default prefix (baked in at configure time)
|
|
1853
|
+
wyvrnpm build --install
|
|
1854
|
+
|
|
1855
|
+
# Override the install prefix without reconfiguring
|
|
1856
|
+
wyvrnpm build --install --install-prefix C:\out\stage
|
|
1857
|
+
|
|
1858
|
+
# Install a specific config
|
|
1859
|
+
wyvrnpm build --install --config Debug
|
|
1860
|
+
|
|
1861
|
+
# Install multiple configs in one invocation — configure runs once,
|
|
1862
|
+
# build + install loops per config. Before 2.9.0 this required two
|
|
1863
|
+
# separate `wyvrnpm build --install ...` invocations.
|
|
1864
|
+
wyvrnpm build --install --config Debug,Release
|
|
1865
|
+
|
|
1866
|
+
# Install every config declared in the recipe's build.configs
|
|
1867
|
+
# (or all four canonical configs when no recipe is present).
|
|
1868
|
+
wyvrnpm build --install --all-configs
|
|
1869
|
+
```
|
|
1870
|
+
|
|
1871
|
+
### What it does, in order
|
|
1872
|
+
|
|
1873
|
+
1. **Staleness check** — if `wyvrn_internal/wyvrn_toolchain.cmake` is missing or `wyvrn.lock` is newer than it, auto-runs `wyvrnpm install` first. Disable with `--no-auto-install`.
|
|
1874
|
+
2. **Optional clean** — `--clean` wipes the build directory before configuring.
|
|
1875
|
+
3. **Configure** — `cmake --preset wyvrn-<profile>` (or the value of `--preset`).
|
|
1876
|
+
4. **Build** — `cmake --build <binaryDir> --config <config>`.
|
|
1877
|
+
5. **Install** — `cmake --install <binaryDir> --config <config> [--prefix <install-prefix>]`.
|
|
1878
|
+
|
|
1879
|
+
### `--auto-install` vs `--install`
|
|
1880
|
+
|
|
1881
|
+
These two flags are easy to confuse — they control unrelated things:
|
|
1882
|
+
|
|
1883
|
+
| Flag | What it does | When it runs |
|
|
1884
|
+
|---|---|---|
|
|
1885
|
+
| `--auto-install` *(default: on)* | Runs `wyvrnpm install` if the toolchain is stale. Disable with `--no-auto-install`. | **Before** configure. |
|
|
1886
|
+
| `--install` *(default: off)* | Runs `cmake --install` after a successful build. | **After** build. |
|
|
1887
|
+
|
|
1888
|
+
### `--install-prefix`
|
|
1889
|
+
|
|
1890
|
+
CMake bakes `CMAKE_INSTALL_PREFIX` into the build cache at configure time. Passing `--install-prefix` at install time uses `cmake --install --prefix <path>` to override the baked value **without** re-running configure — cheaper than a full reconfigure when you only want to stage to a different location.
|
|
1891
|
+
|
|
1892
|
+
If you omit `--install-prefix`, the baked default is used. The baked default comes from the generated preset, typically under `build/wyvrn-<profile>/install`.
|
|
1893
|
+
|
|
1894
|
+
### Permissions
|
|
1895
|
+
|
|
1896
|
+
Installing to a system path (`/usr/local`, `C:\Program Files`) requires the usual elevated permissions — wyvrnpm does not auto-elevate. For staging or packaging, point `--install-prefix` at a writable user directory instead.
|
|
1897
|
+
|
|
1898
|
+
---
|
|
1899
|
+
|
|
1900
|
+
## Version Conflict Resolution
|
|
1901
|
+
|
|
1902
|
+
When the dependency graph requires the same package at multiple versions, the highest version wins. If a `wyvrn.lock` exists, locked versions always take priority over any conflicting transitive request. A warning is printed for every conflict detected.
|
|
1903
|
+
|
|
1904
|
+
---
|
|
1905
|
+
|
|
1906
|
+
## Ignoring generated files
|
|
1907
|
+
|
|
1908
|
+
Add the following to your `.gitignore`:
|
|
1909
|
+
|
|
1910
|
+
```
|
|
1911
|
+
wyvrn_internal/
|
|
1912
|
+
wyvrn.lock
|
|
1913
|
+
*.zip
|
|
1914
|
+
```
|