From 0748462e90d3dcd9a1b6b16bc2779742379df156 Mon Sep 17 00:00:00 2001 From: euxaristia Date: Mon, 14 Sep 2026 23:31:59 -0400 Subject: [PATCH 1/2] build(llvm-win32): support CMAKE_GENERATOR and newer Visual Studio releases `packages/llvm-win32-x64-msvc/scripts/build.mjs` previously hardcoded `-G "Visual Studio 17 2022"`, failing on systems with Visual Studio 18 2026 or where a custom generator was configured. Respect `process.env.CMAKE_GENERATOR` if defined, or probe `vswhere.exe` for installed Visual Studio major versions (18/17/16), only passing `-A x64` for Visual Studio generators. Fixes #326 --- .../llvm-win32-x64-msvc/scripts/build.mjs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/llvm-win32-x64-msvc/scripts/build.mjs b/packages/llvm-win32-x64-msvc/scripts/build.mjs index 4eb345446..86fada0ce 100644 --- a/packages/llvm-win32-x64-msvc/scripts/build.mjs +++ b/packages/llvm-win32-x64-msvc/scripts/build.mjs @@ -6,9 +6,40 @@ import { fileURLToPath } from "node:url"; const root = dirname(dirname(fileURLToPath(import.meta.url))); const repo = fileURLToPath(new URL("../../..", import.meta.url)); if (process.platform !== "win32" || process.arch !== "x64") { process.stdout.write("@scriptc/llvm-win32-x64-msvc: skipped on this host\n"); process.exit(0); } const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8")); const build = join(repo, "node_modules/.cache/scriptc-llvm-win32-x64-msvc"); +function resolveGenerator() { + if (process.env.CMAKE_GENERATOR) return process.env.CMAKE_GENERATOR; + const vswhereCandidates = [ + join(process.env["ProgramFiles(x86)"] ?? "C:/Program Files (x86)", "Microsoft Visual Studio/Installer/vswhere.exe"), + join(process.env["ProgramFiles"] ?? "C:/Program Files", "Microsoft Visual Studio/Installer/vswhere.exe"), + ]; + for (const vswhere of vswhereCandidates) { + try { + const ver = execFileSync(vswhere, ["-latest", "-products", "*", "-property", "installationVersion"], { encoding: "utf8" }).trim(); + const major = parseInt(ver, 10); + if (major === 18) return "Visual Studio 18 2026"; + if (major === 17) return "Visual Studio 17 2022"; + if (major === 16) return "Visual Studio 16 2019"; + } catch {} + } + return "Visual Studio 17 2022"; +} + // LLVM's official Windows development archive contains MSVC-built static // libraries. Use Visual Studio's generator, rather than inheriting a caller's // clang/ninja defaults, so it selects the matching CRT, SDK, manifest tools, // and current MSVC standard-library implementation. -execFileSync("cmake", ["-S", join(repo, "native/llvm-codegen"), "-B", build, "-G", "Visual Studio 17 2022", "-A", "x64", `-DLLVM_DIR=${process.env.LLVM_DIR ?? "C:/Program Files/LLVM/lib/cmake/llvm"}`, `-DSCRIPTC_PACKAGE_VERSION=${manifest.version}`, "-DSCRIPTC_DEFAULT_TARGET=x86_64-pc-windows-msvc", "-DSCRIPTC_DEFAULT_DATA_LAYOUT=e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", "-DSCRIPTC_TARGET_BACKENDS=X86;WebAssembly", "-DSCRIPTC_ALLOWED_TARGETS=x86_64-pc-windows-msvc,wasm32-unknown-wasi"], { stdio: "inherit" }); +const generator = resolveGenerator(); +const cmakeArgs = [ + "-S", join(repo, "native/llvm-codegen"), + "-B", build, + "-G", generator, + ...(generator.startsWith("Visual Studio") ? ["-A", "x64"] : []), + `-DLLVM_DIR=${process.env.LLVM_DIR ?? "C:/Program Files/LLVM/lib/cmake/llvm"}`, + `-DSCRIPTC_PACKAGE_VERSION=${manifest.version}`, + "-DSCRIPTC_DEFAULT_TARGET=x86_64-pc-windows-msvc", + "-DSCRIPTC_DEFAULT_DATA_LAYOUT=e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", + "-DSCRIPTC_TARGET_BACKENDS=X86;WebAssembly", + "-DSCRIPTC_ALLOWED_TARGETS=x86_64-pc-windows-msvc,wasm32-unknown-wasi", +]; +execFileSync("cmake", cmakeArgs, { stdio: "inherit" }); execFileSync("cmake", ["--build", build, "--config", "Release", "--target", "scriptc-llvm-codegen"], { stdio: "inherit" }); mkdirSync(join(root, "bin"), { recursive: true }); copyFileSync(join(build, "Release", "scriptc-llvm-codegen.exe"), join(root, "bin", "scriptc-llvm-codegen.exe")); From bb7c81dab310d004fd926f3a3efbbe5041a4db1c Mon Sep 17 00:00:00 2001 From: euxaristia Date: Thu, 17 Sep 2026 09:59:53 -0400 Subject: [PATCH 2/2] fix(llvm-win32): support single-config generator output paths Pass -DCMAKE_BUILD_TYPE=Release when configuring with single-config generators such as Ninja, and probe candidate output directories before copying scriptc-llvm-codegen.exe to prevent ENOENT. Refs #326 --- packages/llvm-win32-x64-msvc/scripts/build.mjs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/llvm-win32-x64-msvc/scripts/build.mjs b/packages/llvm-win32-x64-msvc/scripts/build.mjs index 86fada0ce..59d926929 100644 --- a/packages/llvm-win32-x64-msvc/scripts/build.mjs +++ b/packages/llvm-win32-x64-msvc/scripts/build.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node import { execFileSync } from "node:child_process"; -import { copyFileSync, mkdirSync, readFileSync } from "node:fs"; +import { copyFileSync, existsSync, mkdirSync, readFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; const root = dirname(dirname(fileURLToPath(import.meta.url))); const repo = fileURLToPath(new URL("../../..", import.meta.url)); @@ -29,11 +29,13 @@ function resolveGenerator() { // clang/ninja defaults, so it selects the matching CRT, SDK, manifest tools, // and current MSVC standard-library implementation. const generator = resolveGenerator(); +const isMultiConfig = generator.startsWith("Visual Studio") || generator === "Ninja Multi-Config" || generator === "Xcode"; const cmakeArgs = [ "-S", join(repo, "native/llvm-codegen"), "-B", build, "-G", generator, ...(generator.startsWith("Visual Studio") ? ["-A", "x64"] : []), + ...(!isMultiConfig ? ["-DCMAKE_BUILD_TYPE=Release"] : []), `-DLLVM_DIR=${process.env.LLVM_DIR ?? "C:/Program Files/LLVM/lib/cmake/llvm"}`, `-DSCRIPTC_PACKAGE_VERSION=${manifest.version}`, "-DSCRIPTC_DEFAULT_TARGET=x86_64-pc-windows-msvc", @@ -42,4 +44,14 @@ const cmakeArgs = [ "-DSCRIPTC_ALLOWED_TARGETS=x86_64-pc-windows-msvc,wasm32-unknown-wasi", ]; execFileSync("cmake", cmakeArgs, { stdio: "inherit" }); -execFileSync("cmake", ["--build", build, "--config", "Release", "--target", "scriptc-llvm-codegen"], { stdio: "inherit" }); mkdirSync(join(root, "bin"), { recursive: true }); copyFileSync(join(build, "Release", "scriptc-llvm-codegen.exe"), join(root, "bin", "scriptc-llvm-codegen.exe")); +const buildArgs = ["--build", build, ...(isMultiConfig ? ["--config", "Release"] : []), "--target", "scriptc-llvm-codegen"]; +execFileSync("cmake", buildArgs, { stdio: "inherit" }); +const candidateOutputs = [ + join(build, "Release", "scriptc-llvm-codegen.exe"), + join(build, "scriptc-llvm-codegen.exe"), + join(build, "RelWithDebInfo", "scriptc-llvm-codegen.exe"), +]; +const built = candidateOutputs.find(existsSync); +if (!built) throw new Error(`Could not find built scriptc-llvm-codegen.exe in ${build}`); +mkdirSync(join(root, "bin"), { recursive: true }); +copyFileSync(built, join(root, "bin", "scriptc-llvm-codegen.exe"));