wyvrnpm 2.20.1 → 2.20.2
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/package.json +1 -1
- package/src/commands/build.js +63 -25
- package/src/context.js +1 -1
- package/src/toolchain/presets.js +31 -0
package/package.json
CHANGED
package/src/commands/build.js
CHANGED
|
@@ -7,6 +7,7 @@ const { spawn } = require('child_process');
|
|
|
7
7
|
const { normalizeRecipe, hasBuildRecipe, VALID_CMAKE_CONFIGS, DEFAULT_RECIPE } = require('../build/recipe');
|
|
8
8
|
const { loadMsvcEnv } = require('../build/msvc-env');
|
|
9
9
|
const { archToVsPlatform, isVisualStudioGenerator } = require('../toolchain');
|
|
10
|
+
const { readConfigurePresetGenerator } = require('../toolchain/presets');
|
|
10
11
|
const { resolveEffectiveGenerator } = require('../build/default-generator');
|
|
11
12
|
const { resolveCmakeExe } = require('../build/cmake-exe');
|
|
12
13
|
const { LOCAL_OVERLAY_FILENAME, readLocalOverlay } = require('../conf');
|
|
@@ -226,6 +227,54 @@ function buildInstallArgs({ binaryDir, config, prefix }) {
|
|
|
226
227
|
return args;
|
|
227
228
|
}
|
|
228
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Resolve the generator `cmake --preset <presetName>` will actually use, so
|
|
232
|
+
* the caller can decide generator-dependent flags (the Visual Studio `-A`
|
|
233
|
+
* arch pin, and whether to activate vcvarsall) against reality.
|
|
234
|
+
*
|
|
235
|
+
* Precedence — each step mirrors what CMake itself does:
|
|
236
|
+
* 1. CLI `--generator` — `build` passes it as `-G`, which overrides the
|
|
237
|
+
* preset, so it wins here too.
|
|
238
|
+
* 2. The generator baked into the configure preset by `install`. This file,
|
|
239
|
+
* not the project's recipe, is the contract `cmake --preset` consumes;
|
|
240
|
+
* the recipe and the emitted preset can legitimately diverge (an
|
|
241
|
+
* install-time `--generator`, or a recipe edited after the last install).
|
|
242
|
+
* Trusting a re-derived recipe value is exactly the bug this guards
|
|
243
|
+
* against — it pins `-A` against a non-VS preset (a hard CMake error) and
|
|
244
|
+
* wrongly skips vcvarsall.
|
|
245
|
+
* 3. The detected default (Windows/MSVC → newest VS) for a generator-less
|
|
246
|
+
* preset — emitted by a pre-arch-pin client, or any non-Windows
|
|
247
|
+
* toolchain. Keeps the recipe-less arch pin firing. See
|
|
248
|
+
* claude/PLAN-VS-ARCH-PIN.md.
|
|
249
|
+
*
|
|
250
|
+
* `readPresetGenerator` and `detect` are injectable for hermetic tests.
|
|
251
|
+
*
|
|
252
|
+
* @param {{
|
|
253
|
+
* rootDir: string,
|
|
254
|
+
* presetName: string,
|
|
255
|
+
* cliGenerator?: string|null,
|
|
256
|
+
* profile?: { os?: string, compiler?: string, arch?: string }|null,
|
|
257
|
+
* readPresetGenerator?: (args: { projectRoot: string, presetName: string }) => string|null,
|
|
258
|
+
* detect?: () => Promise<string|null>,
|
|
259
|
+
* }} args
|
|
260
|
+
* @returns {Promise<string|null>}
|
|
261
|
+
*/
|
|
262
|
+
async function resolveConfigureGenerator({
|
|
263
|
+
rootDir,
|
|
264
|
+
presetName,
|
|
265
|
+
cliGenerator = null,
|
|
266
|
+
profile = null,
|
|
267
|
+
readPresetGenerator = readConfigurePresetGenerator,
|
|
268
|
+
detect,
|
|
269
|
+
}) {
|
|
270
|
+
if (typeof cliGenerator === 'string' && cliGenerator.trim()) return cliGenerator;
|
|
271
|
+
|
|
272
|
+
const fromPreset = readPresetGenerator({ projectRoot: rootDir, presetName });
|
|
273
|
+
if (fromPreset) return fromPreset;
|
|
274
|
+
|
|
275
|
+
return resolveEffectiveGenerator({ explicit: null, profile, detect });
|
|
276
|
+
}
|
|
277
|
+
|
|
229
278
|
// ---------------------------------------------------------------------------
|
|
230
279
|
// Spawn wrapper
|
|
231
280
|
// ---------------------------------------------------------------------------
|
|
@@ -370,32 +419,20 @@ async function build(argv) {
|
|
|
370
419
|
//
|
|
371
420
|
// Same mechanism the source-build path already uses (src/build/msvc-env.js).
|
|
372
421
|
let cmakeEnv = null;
|
|
373
|
-
|
|
374
|
-
let
|
|
422
|
+
const effectiveProfile = activeProfile;
|
|
423
|
+
let effectiveGenerator = null;
|
|
375
424
|
try {
|
|
376
|
-
|
|
377
|
-
//
|
|
378
|
-
// project's
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
} catch { /* templates need options → skip env activation */ }
|
|
388
|
-
}
|
|
389
|
-
// CLI --generator wins, then the recipe's generator, then — on a
|
|
390
|
-
// Windows/MSVC profile with neither — CMake's detected default VS
|
|
391
|
-
// generator. Resolving the default here keeps the `-A` pin below and the
|
|
392
|
-
// vcvarsall-skip decision consistent with the generator `cmake --preset`
|
|
393
|
-
// will actually use (install pins the same generator into the preset).
|
|
394
|
-
// Non-Windows / non-MSVC → null, unchanged from before.
|
|
395
|
-
// See claude/PLAN-VS-ARCH-PIN.md.
|
|
396
|
-
effectiveGenerator = await resolveEffectiveGenerator({
|
|
397
|
-
explicit: effectiveGenerator ?? presetGenerator,
|
|
398
|
-
profile: activeProfile,
|
|
425
|
+
// The generator `cmake --preset` will actually use is the one baked into
|
|
426
|
+
// the configure preset by `install` (a CLI --generator overrides it). That
|
|
427
|
+
// value — not the project's recipe — drives both the `-A` pin below and the
|
|
428
|
+
// vcvarsall-skip decision, so they stay consistent with reality even when
|
|
429
|
+
// the recipe and the emitted preset disagree. See resolveConfigureGenerator
|
|
430
|
+
// and claude/PLAN-VS-ARCH-PIN.md.
|
|
431
|
+
effectiveGenerator = await resolveConfigureGenerator({
|
|
432
|
+
rootDir,
|
|
433
|
+
presetName,
|
|
434
|
+
cliGenerator: argv.generator,
|
|
435
|
+
profile: activeProfile,
|
|
399
436
|
});
|
|
400
437
|
cmakeEnv = await loadMsvcEnv({
|
|
401
438
|
profile: activeProfile,
|
|
@@ -486,6 +523,7 @@ module.exports._helpers = {
|
|
|
486
523
|
resolvePresetName,
|
|
487
524
|
resolveBinaryDir,
|
|
488
525
|
resolveConfigList,
|
|
526
|
+
resolveConfigureGenerator,
|
|
489
527
|
buildConfigureArgs,
|
|
490
528
|
buildBuildArgs,
|
|
491
529
|
buildInstallArgs,
|
package/src/context.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* re-read config, re-resolve auth, and each toggle JSON mode on the logger.
|
|
8
8
|
* The divergence was cheap at 11 commands; it starts costing real bugs
|
|
9
9
|
* once F3 (`tool_requires`) and F4 (build/host profile split) double the
|
|
10
|
-
* flag surface. See [claude/
|
|
10
|
+
* flag surface. See [.claude-wyvrn-local/plans/2026-04-23-command-context.md](../.claude-wyvrn-local/plans/2026-04-23-command-context.md).
|
|
11
11
|
*
|
|
12
12
|
* `buildContext(argv)` runs once at the top of each command. It:
|
|
13
13
|
* - resolves filesystem anchors (rootDir, manifestPath)
|
package/src/toolchain/presets.js
CHANGED
|
@@ -388,6 +388,36 @@ function generateCMakePresets({
|
|
|
388
388
|
return { path: null, action: 'skipped', isUser: false };
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
+
/**
|
|
392
|
+
* Read the `generator` of a named configure preset from the project's
|
|
393
|
+
* CMakePresets.json (falling back to CMakeUserPresets.json). This is the
|
|
394
|
+
* generator `cmake --preset <name>` will actually use, so callers deciding
|
|
395
|
+
* generator-dependent flags — the Visual Studio `-A` arch pin, or whether to
|
|
396
|
+
* activate vcvarsall — must trust it over a value re-derived from the recipe.
|
|
397
|
+
* The recipe and the emitted preset can legitimately diverge (an install-time
|
|
398
|
+
* `--generator`, or a recipe edited after the last install); trusting the
|
|
399
|
+
* recipe pins `-A` against a Ninja preset, which CMake rejects with a hard
|
|
400
|
+
* "does not support platform specification" error.
|
|
401
|
+
*
|
|
402
|
+
* Returns the generator string, or null when the file/preset is absent or the
|
|
403
|
+
* preset declares no generator — the latter means CMake will fall back to its
|
|
404
|
+
* platform default, which the caller's detection path handles.
|
|
405
|
+
*
|
|
406
|
+
* @param {{ projectRoot: string, presetName: string }} args
|
|
407
|
+
* @returns {string|null}
|
|
408
|
+
*/
|
|
409
|
+
function readConfigurePresetGenerator({ projectRoot, presetName }) {
|
|
410
|
+
for (const file of ['CMakePresets.json', 'CMakeUserPresets.json']) {
|
|
411
|
+
const parsed = safeReadJson(path.join(projectRoot, file));
|
|
412
|
+
const presets = parsed && Array.isArray(parsed.configurePresets) ? parsed.configurePresets : [];
|
|
413
|
+
const match = presets.find((p) => p && p.name === presetName);
|
|
414
|
+
if (match && typeof match.generator === 'string' && match.generator.trim()) {
|
|
415
|
+
return match.generator;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
|
|
391
421
|
/**
|
|
392
422
|
* Strip every wyvrnpm-generated entry from a parsed presets object.
|
|
393
423
|
* Mirror of `mergeIntoExisting` — used by `wyvrnpm clean --all` to
|
|
@@ -475,6 +505,7 @@ function stripWyvrnPresets(existing) {
|
|
|
475
505
|
|
|
476
506
|
module.exports = {
|
|
477
507
|
generateCMakePresets,
|
|
508
|
+
readConfigurePresetGenerator,
|
|
478
509
|
stripWyvrnPresets,
|
|
479
510
|
safeReadJson,
|
|
480
511
|
// Exported for tests
|