wyvrnpm 2.0.4 → 2.1.0
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 +382 -4
- package/bin/wyvrn.js +96 -3
- package/cmake/cpp.cmake +9 -0
- package/cmake/functions.cmake +224 -0
- package/cmake/macros.cmake +233 -0
- package/cmake/options.cmake +23 -0
- package/cmake/variables.cmake +171 -0
- package/package.json +2 -1
- package/src/build/cache.js +101 -0
- package/src/build/clone.js +170 -0
- package/src/build/cmake.js +342 -0
- package/src/build/index.js +244 -0
- package/src/build/msvc-env.js +217 -0
- package/src/build/recipe.js +129 -0
- package/src/commands/build.js +242 -0
- package/src/commands/clean.js +25 -9
- package/src/commands/configure.js +6 -5
- package/src/commands/init.js +3 -2
- package/src/commands/install.js +61 -14
- package/src/commands/link.js +18 -15
- package/src/commands/profile.js +15 -12
- package/src/commands/publish.js +67 -31
- package/src/compat.js +232 -0
- package/src/config.js +3 -1
- package/src/download.js +369 -87
- package/src/logger.js +78 -0
- package/src/profile.js +28 -0
- package/src/providers/file.js +4 -3
- package/src/providers/http.js +3 -2
- package/src/providers/s3.js +3 -2
- package/src/resolve.js +9 -7
- package/src/toolchain/deps.js +164 -0
- package/src/toolchain/index.js +141 -0
- package/src/toolchain/presets.js +191 -0
- package/src/toolchain/template.cmake +66 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A simple, private C++ package manager that works with any static file hosting pr
|
|
|
4
4
|
|
|
5
5
|
There is no central registry. You control where packages are hosted.
|
|
6
6
|
|
|
7
|
-
> **README version: 2.0
|
|
7
|
+
> **README version: 2.1.0** — Adds CMake toolchain generation, the `wyvrnpm build` command, declarative compatibility, and `--build=missing` source-build.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -40,10 +40,13 @@ wyvrnpm configure profile detect
|
|
|
40
40
|
# 4. Install dependencies (resolved against your build profile)
|
|
41
41
|
wyvrnpm install
|
|
42
42
|
|
|
43
|
-
# 5.
|
|
43
|
+
# 5. Configure and build via the generated CMake preset
|
|
44
|
+
wyvrnpm build
|
|
45
|
+
|
|
46
|
+
# 6. Publish your package (uses the active profile automatically)
|
|
44
47
|
wyvrnpm publish
|
|
45
48
|
|
|
46
|
-
#
|
|
49
|
+
# 7. (Optional) Link local packages for development
|
|
47
50
|
cd ../my-local-lib && wyvrnpm link
|
|
48
51
|
cd ../my-app && wyvrnpm link my-local-lib
|
|
49
52
|
```
|
|
@@ -112,7 +115,14 @@ Resolves the full dependency graph and downloads all packages.
|
|
|
112
115
|
|
|
113
116
|
**Source priority:** CLI `--source` values are used if provided. If omitted, sources are loaded from the [configuration file](#configuration-file).
|
|
114
117
|
|
|
115
|
-
**Profile resolution:** `--profile` selects the named build profile. If omitted, `config.defaultProfile` is used, falling back to `"default"`. v2 binaries are
|
|
118
|
+
**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:
|
|
119
|
+
|
|
120
|
+
1. **Exact profile-hash match** — the preferred path.
|
|
121
|
+
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.
|
|
122
|
+
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.
|
|
123
|
+
4. **v1 legacy path** — only when no v2 entry exists for the package at all.
|
|
124
|
+
|
|
125
|
+
The pre-2.1 "same OS + arch, any compiler" loose fallback is removed from the default path. It remains reachable for one release cycle via `WYVRNPM_ALLOW_LOOSE_COMPAT=1` and prints a deprecation warning.
|
|
116
126
|
|
|
117
127
|
```bash
|
|
118
128
|
# Use configured sources and the default build profile
|
|
@@ -128,6 +138,9 @@ wyvrnpm install --source https://pkg.example.com/cpp
|
|
|
128
138
|
wyvrnpm install \
|
|
129
139
|
--source https://primary.example.com/cpp \
|
|
130
140
|
--source https://mirror.example.com/cpp
|
|
141
|
+
|
|
142
|
+
# Build any missing binary from source
|
|
143
|
+
wyvrnpm install --build=missing
|
|
131
144
|
```
|
|
132
145
|
|
|
133
146
|
**Options**
|
|
@@ -136,6 +149,7 @@ wyvrnpm install \
|
|
|
136
149
|
|---|---|---|
|
|
137
150
|
| `--source` / `-s` | *(config)* | Base URL of a package source. Repeat for multiple. Overrides config when provided. |
|
|
138
151
|
| `--profile` / `-p` | *(config / "default")* | Named build profile to use for v2 binary resolution. |
|
|
152
|
+
| `--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. |
|
|
139
153
|
| `--platform` | `win_x64` | v1 legacy platform sub-path (used as a fallback when no v2 binary is found). |
|
|
140
154
|
| `--timeout` | `300` | HTTP request timeout in seconds. |
|
|
141
155
|
| `--manifest` | `./wyvrn.json` | Path to the manifest file. |
|
|
@@ -143,6 +157,66 @@ wyvrnpm install \
|
|
|
143
157
|
|
|
144
158
|
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.
|
|
145
159
|
|
|
160
|
+
After download, `install` also generates:
|
|
161
|
+
|
|
162
|
+
- `wyvrn_internal/wyvrn_toolchain.cmake` — CMake toolchain pointing at the resolved packages.
|
|
163
|
+
- `wyvrn_internal/wyvrn_deps.cmake` — post-`project()` include for `find_package()` wiring and runtime DLL copy.
|
|
164
|
+
- `wyvrn_internal/wyvrn_profile.json` — snapshot of the active build profile.
|
|
165
|
+
- `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.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### `wyvrnpm build`
|
|
170
|
+
|
|
171
|
+
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.
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Configure + build with the default profile's preset (wyvrn-default)
|
|
175
|
+
wyvrnpm build
|
|
176
|
+
|
|
177
|
+
# Build Debug, verbose compiler output
|
|
178
|
+
wyvrnpm build --config Debug --verbose
|
|
179
|
+
|
|
180
|
+
# Use a specific profile's preset
|
|
181
|
+
wyvrnpm build --profile release
|
|
182
|
+
|
|
183
|
+
# Explicit preset name (overrides profile-derived default)
|
|
184
|
+
wyvrnpm build --preset wyvrn-release
|
|
185
|
+
|
|
186
|
+
# Build a single target
|
|
187
|
+
wyvrnpm build --target my-lib
|
|
188
|
+
|
|
189
|
+
# Wipe the build directory first
|
|
190
|
+
wyvrnpm build --clean
|
|
191
|
+
|
|
192
|
+
# Build, then install to the CMake install prefix
|
|
193
|
+
wyvrnpm build --install
|
|
194
|
+
wyvrnpm build --install --install-prefix C:\out\stage
|
|
195
|
+
|
|
196
|
+
# Skip the auto-install step
|
|
197
|
+
wyvrnpm build --no-auto-install
|
|
198
|
+
|
|
199
|
+
# Pass extra args through to cmake --build
|
|
200
|
+
wyvrnpm build -- -j 8
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Options**
|
|
204
|
+
|
|
205
|
+
| Option | Default | Description |
|
|
206
|
+
|---|---|---|
|
|
207
|
+
| `--preset` / `-P` | `wyvrn-<profile>` | CMake configure preset name. |
|
|
208
|
+
| `--profile` / `-p` | *(config / "default")* | Build profile — determines the default preset name. |
|
|
209
|
+
| `--config` / `-c` | `Release` | Build configuration (`Debug` \| `Release` \| `RelWithDebInfo` \| `MinSizeRel`). |
|
|
210
|
+
| `--target` / `-t` | *(all)* | Specific CMake target to build. |
|
|
211
|
+
| `--verbose` / `-v` | `false` | Pass `--verbose` to `cmake --build`. |
|
|
212
|
+
| `--clean` | `false` | Remove the build directory before configuring. |
|
|
213
|
+
| `--install` | `false` | Run `cmake --install` after a successful build. |
|
|
214
|
+
| `--install-prefix` | *(baked in)* | Override `CMAKE_INSTALL_PREFIX` for `--install` without reconfiguring. |
|
|
215
|
+
| `--auto-install` | `true` | Auto-run `wyvrnpm install` when the toolchain is stale. Disable with `--no-auto-install`. |
|
|
216
|
+
| `--source` / `-s` | *(config)* | Package sources — passed through to `install` when auto-installing. |
|
|
217
|
+
|
|
218
|
+
Everything after `--` is forwarded verbatim to `cmake --build` (e.g. `-j 8`).
|
|
219
|
+
|
|
146
220
|
---
|
|
147
221
|
|
|
148
222
|
### `wyvrnpm publish`
|
|
@@ -221,9 +295,19 @@ build/
|
|
|
221
295
|
Removes the `wyvrn_internal/` package cache and `wyvrn.lock`.
|
|
222
296
|
|
|
223
297
|
```bash
|
|
298
|
+
# Project-local cleanup
|
|
224
299
|
wyvrnpm clean
|
|
300
|
+
|
|
301
|
+
# Also wipe the machine-wide source-build cache used by --build=missing
|
|
302
|
+
wyvrnpm clean --build-cache
|
|
225
303
|
```
|
|
226
304
|
|
|
305
|
+
**Options**
|
|
306
|
+
|
|
307
|
+
| Option | Default | Description |
|
|
308
|
+
|---|---|---|
|
|
309
|
+
| `--build-cache` | `false` | Also remove the source-build cache under `%LOCALAPPDATA%\wyvrnpm\bc\` (Unix: `~/.cache/wyvrnpm/bc/`). |
|
|
310
|
+
|
|
227
311
|
---
|
|
228
312
|
|
|
229
313
|
### `wyvrnpm link`
|
|
@@ -651,6 +735,203 @@ Fields use PascalCase. `Dependencies` is an array — transitive dependencies ar
|
|
|
651
735
|
|
|
652
736
|
**`dependencies`** can be either a plain version string (`"major.minor.patch.build"`) or an object with `version` and an optional `settings` 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.
|
|
653
737
|
|
|
738
|
+
### Source-build recipe (`build`)
|
|
739
|
+
|
|
740
|
+
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.
|
|
741
|
+
|
|
742
|
+
```json
|
|
743
|
+
{
|
|
744
|
+
"name": "zlib",
|
|
745
|
+
"version": "1.3.0.0",
|
|
746
|
+
"kind": "StaticLib",
|
|
747
|
+
"build": {
|
|
748
|
+
"system": "cmake",
|
|
749
|
+
"generator": ["Ninja", "Visual Studio 17 2022"],
|
|
750
|
+
"configs": ["Release", "Debug"],
|
|
751
|
+
"configure": ["-DZLIB_BUILD_EXAMPLES=OFF"],
|
|
752
|
+
"buildArgs": ["--parallel"],
|
|
753
|
+
"installDir": "install",
|
|
754
|
+
"sourceSubdir": "."
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
| Field | Default | Description |
|
|
760
|
+
|---|---|---|
|
|
761
|
+
| `system` | `cmake` | Build system. Only `cmake` is supported. |
|
|
762
|
+
| `generator` | *(CMake default)* | Single generator (`"Ninja"`) or an array tried in order — first available wins. |
|
|
763
|
+
| `configs` | `["Debug","Release","RelWithDebInfo","MinSizeRel"]` | CMake configurations to build and install. |
|
|
764
|
+
| `configure` | `[]` | Extra args appended to `cmake` at configure time. |
|
|
765
|
+
| `buildArgs` | `[]` | Extra args appended to `cmake --build`. |
|
|
766
|
+
| `installDir` | `install` | Install prefix relative to the binary dir. |
|
|
767
|
+
| `sourceSubdir` | `.` | Where `CMakeLists.txt` lives relative to the clone root. |
|
|
768
|
+
| `requiredTools` | `[]` | Tools that must be on `PATH` before the build starts (fail-fast check). |
|
|
769
|
+
|
|
770
|
+
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.
|
|
771
|
+
|
|
772
|
+
---
|
|
773
|
+
|
|
774
|
+
## Compatibility Rules
|
|
775
|
+
|
|
776
|
+
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.
|
|
777
|
+
|
|
778
|
+
### Block format
|
|
779
|
+
|
|
780
|
+
Each field maps to a mode — either as a string shorthand or an object:
|
|
781
|
+
|
|
782
|
+
```json
|
|
783
|
+
{
|
|
784
|
+
"name": "zlib",
|
|
785
|
+
"version": "1.3.0.0",
|
|
786
|
+
"compatibility": {
|
|
787
|
+
"compiler.cppstd": "lte",
|
|
788
|
+
"compiler.runtime": "exact",
|
|
789
|
+
"compiler.version": "exact-or-newer"
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
Object form is accepted too (`{ "mode": "lte" }`) and leaves room for future per-field options.
|
|
795
|
+
|
|
796
|
+
### Supported modes
|
|
797
|
+
|
|
798
|
+
| Mode | Meaning |
|
|
799
|
+
|---|---|
|
|
800
|
+
| `exact` | Package and consumer values must be equal. |
|
|
801
|
+
| `any` | Field is ignored for compatibility purposes. |
|
|
802
|
+
| `lte` | Package value ≤ consumer value — e.g. a `cppstd=20` package is usable by a `cppstd=23` consumer. |
|
|
803
|
+
| `gte` | Package value ≥ consumer value (symmetry; rarely useful). |
|
|
804
|
+
| `exact-or-newer` | Same as `lte` at MVP — kept as a distinct name because it reads naturally for compiler-version fields. |
|
|
805
|
+
|
|
806
|
+
**Defaults:**
|
|
807
|
+
|
|
808
|
+
- Any field not listed is treated as `exact`.
|
|
809
|
+
- `os` and `arch` are **always `exact`** regardless of what the block says. Cross-OS / cross-arch binaries are never ABI-compatible.
|
|
810
|
+
|
|
811
|
+
### Where to author it
|
|
812
|
+
|
|
813
|
+
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.
|
|
814
|
+
|
|
815
|
+
Consumers never author compatibility — it is a property of the published package.
|
|
816
|
+
|
|
817
|
+
### Tiebreaker
|
|
818
|
+
|
|
819
|
+
When multiple published builds satisfy the consumer's profile, the winner is picked deterministically:
|
|
820
|
+
|
|
821
|
+
1. Prefer the candidate whose `compiler` matches the consumer's.
|
|
822
|
+
2. Prefer the highest numeric `compiler.version`.
|
|
823
|
+
3. Prefer the candidate whose `compiler.runtime` matches the consumer's.
|
|
824
|
+
4. Fall back to the lexicographically earliest `profileHash`.
|
|
825
|
+
|
|
826
|
+
The chosen candidate is logged along with a per-field summary (e.g. `compiler.cppstd 20→23 (lte), compiler.runtime=dynamic`).
|
|
827
|
+
|
|
828
|
+
### Legacy loose fallback
|
|
829
|
+
|
|
830
|
+
The pre-2.1 "same OS + arch, any compiler" fallback is removed from the default resolution path. For one release cycle it remains reachable via an env var:
|
|
831
|
+
|
|
832
|
+
```bash
|
|
833
|
+
WYVRNPM_ALLOW_LOOSE_COMPAT=1 wyvrnpm install
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
This prints a deprecation warning every time it fires and will be removed in the next minor release. Prefer adding a real `compatibility` block to affected packages, or rebuilding with `--build=missing`.
|
|
837
|
+
|
|
838
|
+
---
|
|
839
|
+
|
|
840
|
+
## Source Builds
|
|
841
|
+
|
|
842
|
+
`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.
|
|
843
|
+
|
|
844
|
+
### When it fires
|
|
845
|
+
|
|
846
|
+
1. You run `wyvrnpm install --build=missing`.
|
|
847
|
+
2. For each dependency, wyvrnpm tries `v2 exact → v2 compat` first.
|
|
848
|
+
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).
|
|
849
|
+
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.
|
|
850
|
+
|
|
851
|
+
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.
|
|
852
|
+
|
|
853
|
+
### Authoring the `build` recipe
|
|
854
|
+
|
|
855
|
+
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.
|
|
856
|
+
|
|
857
|
+
### Generator fallback
|
|
858
|
+
|
|
859
|
+
`build.generator` accepts either a string or an array:
|
|
860
|
+
|
|
861
|
+
| Form | Behaviour |
|
|
862
|
+
|---|---|
|
|
863
|
+
| `"Ninja"` | Strict — fails if Ninja is not available. |
|
|
864
|
+
| `["Ninja", "Visual Studio 17 2022"]` | Tried in order — first available wins. Unknown entries are trusted (CMake decides at configure time). |
|
|
865
|
+
| *(omitted)* | Uses CMake's platform default. |
|
|
866
|
+
|
|
867
|
+
### MSVC environment auto-activation (Windows)
|
|
868
|
+
|
|
869
|
+
On Windows, when **all** of the following hold:
|
|
870
|
+
|
|
871
|
+
- `profile.compiler === "msvc"`
|
|
872
|
+
- The chosen generator is **not** a Visual Studio generator (e.g. Ninja, Make)
|
|
873
|
+
- `cl.exe` is not on `PATH`
|
|
874
|
+
|
|
875
|
+
…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.
|
|
876
|
+
|
|
877
|
+
Arch mapping follows the active profile:
|
|
878
|
+
|
|
879
|
+
| `profile.arch` | `vcvarsall` arg |
|
|
880
|
+
|---|---|
|
|
881
|
+
| `x86_64` | `x64` |
|
|
882
|
+
| `x86` | `x86` |
|
|
883
|
+
| `armv8` | `arm64` |
|
|
884
|
+
| `armv7` | `arm` |
|
|
885
|
+
|
|
886
|
+
VS generators skip this path entirely — MSBuild resolves MSVC itself.
|
|
887
|
+
|
|
888
|
+
### Cache
|
|
889
|
+
|
|
890
|
+
Source builds are cached machine-wide, keyed by `(name, version, profileHash)`:
|
|
891
|
+
|
|
892
|
+
| Platform | Path |
|
|
893
|
+
|---|---|
|
|
894
|
+
| Windows | `%LOCALAPPDATA%\wyvrnpm\bc\{name}-{version}-{profileHash}\` |
|
|
895
|
+
| Linux / macOS | `~/.cache/wyvrnpm/bc/{name}-{version}-{profileHash}/` |
|
|
896
|
+
|
|
897
|
+
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.
|
|
898
|
+
|
|
899
|
+
Clone behaviour is tri-tier:
|
|
900
|
+
|
|
901
|
+
1. **Shallow-SHA fetch** (`git fetch origin <sha> --depth=1`) — fastest; works when the git server allows it.
|
|
902
|
+
2. **Full fetch** — falls back to a full `git clone --tags` when the server rejects shallow-SHA (older Bitbucket installs disable `uploadpack.allowReachableSHA1InWant`).
|
|
903
|
+
3. **Rebuild from scratch** — if the cached clone is broken, wipes and retries.
|
|
904
|
+
|
|
905
|
+
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`.
|
|
906
|
+
|
|
907
|
+
### Publish-time guard
|
|
908
|
+
|
|
909
|
+
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:
|
|
910
|
+
|
|
911
|
+
```
|
|
912
|
+
[wyvrn] warn: git SHA abc1234 is not on origin — source-build consumers will fail until pushed
|
|
913
|
+
```
|
|
914
|
+
|
|
915
|
+
The warning does **not** block publishing.
|
|
916
|
+
|
|
917
|
+
### Header-only libraries
|
|
918
|
+
|
|
919
|
+
`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.
|
|
920
|
+
|
|
921
|
+
### Clearing the cache
|
|
922
|
+
|
|
923
|
+
```bash
|
|
924
|
+
# Remove the project-local cache (wyvrn_internal/ + wyvrn.lock)
|
|
925
|
+
wyvrnpm clean
|
|
926
|
+
|
|
927
|
+
# Also wipe the machine-wide source-build cache
|
|
928
|
+
wyvrnpm clean --build-cache
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
### Credentials for private repos
|
|
932
|
+
|
|
933
|
+
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.
|
|
934
|
+
|
|
654
935
|
---
|
|
655
936
|
|
|
656
937
|
## Lock File (wyvrn.lock)
|
|
@@ -687,6 +968,103 @@ Locked versions always take priority over transitive requests. A warning is prin
|
|
|
687
968
|
|
|
688
969
|
---
|
|
689
970
|
|
|
971
|
+
## CMake Integration
|
|
972
|
+
|
|
973
|
+
`wyvrnpm install` emits a ready-to-use CMake toolchain alongside the downloaded packages. Most projects only need to run:
|
|
974
|
+
|
|
975
|
+
```bash
|
|
976
|
+
wyvrnpm install
|
|
977
|
+
wyvrnpm build
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
…which is equivalent to:
|
|
981
|
+
|
|
982
|
+
```bash
|
|
983
|
+
cmake --preset wyvrn-default
|
|
984
|
+
cmake --build build/wyvrn-default --config Release
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
**Generated files (inside the project)**
|
|
988
|
+
|
|
989
|
+
| Path | Purpose |
|
|
990
|
+
|---|---|
|
|
991
|
+
| `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=…`. |
|
|
992
|
+
| `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. |
|
|
993
|
+
| `wyvrn_internal/wyvrn_profile.json` | Snapshot of the profile the toolchain was generated against. |
|
|
994
|
+
| `CMakePresets.json` / `CMakeUserPresets.json` | `wyvrn-<profile>` configure preset. Regenerating preserves other profiles' presets. |
|
|
995
|
+
|
|
996
|
+
**Bundled CMake utilities** (shipped in the npm tarball under `cmake/`) are auto-included by `wyvrn_toolchain.cmake`:
|
|
997
|
+
|
|
998
|
+
| File | Provides |
|
|
999
|
+
|---|---|
|
|
1000
|
+
| `cpp.cmake` | C++ standard defaults (guarded — toolchain wins). |
|
|
1001
|
+
| `variables.cmake` | Platform detection (`WYVRN_PLATFORM_WIN`, …) and compiler flags. |
|
|
1002
|
+
| `options.cmake` | Feature toggles (`WYVRN_ENABLE_LOG`, …). |
|
|
1003
|
+
| `functions.cmake` | `SETUP_LIBRARY` / `SETUP_EXE` plus HAL source-collection helpers. |
|
|
1004
|
+
| `macros.cmake` | `WYVRN_INSTALL_MODULE`, `WYVRN_CONFIGURE_VERSION_HEADER`. |
|
|
1005
|
+
|
|
1006
|
+
**Minimal `CMakeLists.txt`:**
|
|
1007
|
+
|
|
1008
|
+
```cmake
|
|
1009
|
+
cmake_minimum_required(VERSION 3.21)
|
|
1010
|
+
project(my-app CXX)
|
|
1011
|
+
|
|
1012
|
+
include(${CMAKE_SOURCE_DIR}/wyvrn_internal/wyvrn_deps.cmake)
|
|
1013
|
+
|
|
1014
|
+
add_executable(my-app src/main.cpp)
|
|
1015
|
+
target_link_libraries(my-app PRIVATE OpenSSL::SSL zlib::zlib)
|
|
1016
|
+
|
|
1017
|
+
wyvrnpm_finalize_targets(my-app) # copies runtime DLLs next to the .exe
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
---
|
|
1021
|
+
|
|
1022
|
+
## Installing Build Artifacts (`wyvrnpm build --install`)
|
|
1023
|
+
|
|
1024
|
+
`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.
|
|
1025
|
+
|
|
1026
|
+
### Typical use
|
|
1027
|
+
|
|
1028
|
+
```bash
|
|
1029
|
+
# Configure, build, and install to the default prefix (baked in at configure time)
|
|
1030
|
+
wyvrnpm build --install
|
|
1031
|
+
|
|
1032
|
+
# Override the install prefix without reconfiguring
|
|
1033
|
+
wyvrnpm build --install --install-prefix C:\out\stage
|
|
1034
|
+
|
|
1035
|
+
# Install a specific config
|
|
1036
|
+
wyvrnpm build --install --config Debug
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
### What it does, in order
|
|
1040
|
+
|
|
1041
|
+
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`.
|
|
1042
|
+
2. **Optional clean** — `--clean` wipes the build directory before configuring.
|
|
1043
|
+
3. **Configure** — `cmake --preset wyvrn-<profile>` (or the value of `--preset`).
|
|
1044
|
+
4. **Build** — `cmake --build <binaryDir> --config <config>`.
|
|
1045
|
+
5. **Install** — `cmake --install <binaryDir> --config <config> [--prefix <install-prefix>]`.
|
|
1046
|
+
|
|
1047
|
+
### `--auto-install` vs `--install`
|
|
1048
|
+
|
|
1049
|
+
These two flags are easy to confuse — they control unrelated things:
|
|
1050
|
+
|
|
1051
|
+
| Flag | What it does | When it runs |
|
|
1052
|
+
|---|---|---|
|
|
1053
|
+
| `--auto-install` *(default: on)* | Runs `wyvrnpm install` if the toolchain is stale. Disable with `--no-auto-install`. | **Before** configure. |
|
|
1054
|
+
| `--install` *(default: off)* | Runs `cmake --install` after a successful build. | **After** build. |
|
|
1055
|
+
|
|
1056
|
+
### `--install-prefix`
|
|
1057
|
+
|
|
1058
|
+
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.
|
|
1059
|
+
|
|
1060
|
+
If you omit `--install-prefix`, the baked default is used. The baked default comes from the generated preset, typically under `build/wyvrn-<profile>/install`.
|
|
1061
|
+
|
|
1062
|
+
### Permissions
|
|
1063
|
+
|
|
1064
|
+
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.
|
|
1065
|
+
|
|
1066
|
+
---
|
|
1067
|
+
|
|
690
1068
|
## Version Conflict Resolution
|
|
691
1069
|
|
|
692
1070
|
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.
|
package/bin/wyvrn.js
CHANGED
|
@@ -9,9 +9,11 @@ const clean = require('../src/commands/clean');
|
|
|
9
9
|
const publish = require('../src/commands/publish');
|
|
10
10
|
const configure = require('../src/commands/configure');
|
|
11
11
|
const profile = require('../src/commands/profile');
|
|
12
|
+
const build = require('../src/commands/build');
|
|
12
13
|
const { link, unlink } = require('../src/commands/link');
|
|
13
14
|
|
|
14
15
|
yargs
|
|
16
|
+
.parserConfiguration({ 'populate--': true })
|
|
15
17
|
.option('manifest', {
|
|
16
18
|
type: 'string',
|
|
17
19
|
description: 'Path to manifest file',
|
|
@@ -48,6 +50,14 @@ yargs
|
|
|
48
50
|
type: 'string',
|
|
49
51
|
description: 'Build profile name to use (default: config.defaultProfile → "default")',
|
|
50
52
|
})
|
|
53
|
+
.option('build', {
|
|
54
|
+
type: 'string',
|
|
55
|
+
choices: ['never', 'missing', 'always'],
|
|
56
|
+
default: 'never',
|
|
57
|
+
description:
|
|
58
|
+
'Resolution mode when no exact profile match exists. ' +
|
|
59
|
+
'never=fail; missing=build from source (pending phase 3); always=rebuild (pending phase 3)',
|
|
60
|
+
})
|
|
51
61
|
.option('platform', {
|
|
52
62
|
type: 'string',
|
|
53
63
|
description: 'v1 legacy platform path (used as fallback if v2 not found)',
|
|
@@ -63,12 +73,95 @@ yargs
|
|
|
63
73
|
(argv) => install(argv),
|
|
64
74
|
)
|
|
65
75
|
|
|
76
|
+
// ── build ─────────────────────────────────────────────────────────────────
|
|
77
|
+
.command(
|
|
78
|
+
'build',
|
|
79
|
+
'Configure and build the project via the wyvrnpm-generated CMake preset. ' +
|
|
80
|
+
'Auto-runs `install` if the toolchain is missing or stale.',
|
|
81
|
+
(y) => {
|
|
82
|
+
y
|
|
83
|
+
.option('preset', {
|
|
84
|
+
alias: 'P',
|
|
85
|
+
type: 'string',
|
|
86
|
+
description: 'CMake configure preset name (default: wyvrn-<profile>)',
|
|
87
|
+
})
|
|
88
|
+
.option('profile', {
|
|
89
|
+
alias: 'p',
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Build profile name — determines the default preset',
|
|
92
|
+
})
|
|
93
|
+
.option('config', {
|
|
94
|
+
alias: 'c',
|
|
95
|
+
type: 'string',
|
|
96
|
+
choices: ['Debug', 'Release', 'RelWithDebInfo', 'MinSizeRel'],
|
|
97
|
+
default: 'Release',
|
|
98
|
+
description: 'Build configuration',
|
|
99
|
+
})
|
|
100
|
+
.option('target', {
|
|
101
|
+
alias: 't',
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: 'CMake target to build (default: all)',
|
|
104
|
+
})
|
|
105
|
+
.option('verbose', {
|
|
106
|
+
alias: 'v',
|
|
107
|
+
type: 'boolean',
|
|
108
|
+
default: false,
|
|
109
|
+
description: 'Pass --verbose to cmake --build (detailed compiler output)',
|
|
110
|
+
})
|
|
111
|
+
.option('clean', {
|
|
112
|
+
type: 'boolean',
|
|
113
|
+
default: false,
|
|
114
|
+
description: 'Remove the build directory before configuring',
|
|
115
|
+
})
|
|
116
|
+
.option('install', {
|
|
117
|
+
type: 'boolean',
|
|
118
|
+
default: false,
|
|
119
|
+
description: 'Run `cmake --install` after the build (installs to the prefix baked at configure time, or --install-prefix)',
|
|
120
|
+
})
|
|
121
|
+
.option('install-prefix', {
|
|
122
|
+
type: 'string',
|
|
123
|
+
description: 'Override CMAKE_INSTALL_PREFIX for `--install` without reconfiguring',
|
|
124
|
+
})
|
|
125
|
+
.option('auto-install', {
|
|
126
|
+
type: 'boolean',
|
|
127
|
+
default: true,
|
|
128
|
+
description: 'Auto-run `wyvrnpm install` when the toolchain is stale. Disable with --no-auto-install.',
|
|
129
|
+
})
|
|
130
|
+
.option('source', {
|
|
131
|
+
alias: 's',
|
|
132
|
+
type: 'string',
|
|
133
|
+
array: true,
|
|
134
|
+
description: 'Package source(s) — passed through to `install` when auto-installing',
|
|
135
|
+
})
|
|
136
|
+
.option('platform', {
|
|
137
|
+
type: 'string',
|
|
138
|
+
choices: ['win_x64', 'win_x86', 'linux_x64', 'linux_x86', 'osx_x64', 'osx_arm64'],
|
|
139
|
+
default: 'win_x64',
|
|
140
|
+
})
|
|
141
|
+
.option('timeout', {
|
|
142
|
+
type: 'number',
|
|
143
|
+
default: 300,
|
|
144
|
+
});
|
|
145
|
+
},
|
|
146
|
+
(argv) => build({
|
|
147
|
+
...argv,
|
|
148
|
+
autoInstall: argv['auto-install'],
|
|
149
|
+
installPrefix: argv['install-prefix'],
|
|
150
|
+
}),
|
|
151
|
+
)
|
|
152
|
+
|
|
66
153
|
// ── clean ─────────────────────────────────────────────────────────────────
|
|
67
154
|
.command(
|
|
68
155
|
'clean',
|
|
69
|
-
'Remove downloaded packages and lock file',
|
|
70
|
-
() => {
|
|
71
|
-
|
|
156
|
+
'Remove downloaded packages and lock file. --build-cache also wipes the machine-wide source-build cache.',
|
|
157
|
+
(y) => {
|
|
158
|
+
y.option('build-cache', {
|
|
159
|
+
type: 'boolean',
|
|
160
|
+
default: false,
|
|
161
|
+
description: 'Also remove the source-build cache under %LOCALAPPDATA%\\wyvrnpm\\bc\\',
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
(argv) => clean({ ...argv, buildCache: argv['build-cache'] }),
|
|
72
165
|
)
|
|
73
166
|
|
|
74
167
|
// ── publish ───────────────────────────────────────────────────────────────
|
package/cmake/cpp.cmake
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Define the cpp information ( version, compilation type, thread type, exception handling )
|
|
2
|
+
# Set a C++20 default only if the consumer (or wyvrnpm's toolchain) has not
|
|
3
|
+
# already chosen a standard — the toolchain sets CMAKE_CXX_STANDARD from the
|
|
4
|
+
# active build profile before project(), and that explicit choice must win.
|
|
5
|
+
if(NOT DEFINED CMAKE_CXX_STANDARD)
|
|
6
|
+
set(CMAKE_CXX_STANDARD 20)
|
|
7
|
+
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|
8
|
+
endif()
|
|
9
|
+
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API OFF)
|