|
7 | 7 | * `powershell.exe`. Override 7z path: `PROMETHEUS_7Z`; override PowerShell: `PROMETHEUS_PWSH`. |
8 | 8 | * 7-Zip is also used for Ghostscript Inno extract + ImageMagick `.7z`. |
9 | 9 | * Skip entirely: PROMETHEUS_SKIP_STAGE_BINS=1. Invoked from run-electrobun-with-build-at.ts before build. |
| 10 | + * |
| 11 | + * macOS: pack key follows **hardware** (Apple Silicon → `darwin-arm64`, Intel → `darwin-x64`), not `process.arch`, |
| 12 | + * so a Rosetta-translated `bun` still stages arm64 CLIs on M-series Macs. |
10 | 13 | */ |
11 | 14 | import { createHash } from "node:crypto"; |
12 | 15 | import { |
@@ -118,16 +121,19 @@ function stage_script_sha256(): string { |
118 | 121 | return sha256_file(script_path); |
119 | 122 | } |
120 | 123 |
|
| 124 | +function darwin_bundled_cli_platform_key(): "darwin-arm64" | "darwin-x64" { |
| 125 | + const out = spawnSync("sysctl", ["-n", "hw.optional.arm64"], { encoding: "utf8" }); |
| 126 | + if (out.status === 0 && out.stdout.trim() === "1") { |
| 127 | + return "darwin-arm64"; |
| 128 | + } |
| 129 | + return "darwin-x64"; |
| 130 | +} |
| 131 | + |
121 | 132 | function host_platform_key(): string { |
122 | | - const arch = process.arch; |
123 | 133 | if (process.platform === "darwin") { |
124 | | - if (arch === "arm64") { |
125 | | - return "darwin-arm64"; |
126 | | - } |
127 | | - if (arch === "x64") { |
128 | | - return "darwin-x64"; |
129 | | - } |
| 134 | + return darwin_bundled_cli_platform_key(); |
130 | 135 | } |
| 136 | + const arch = process.arch; |
131 | 137 | if (process.platform === "linux" && arch === "x64") { |
132 | 138 | return "linux-x64"; |
133 | 139 | } |
@@ -541,7 +547,9 @@ async function stage_yt_dlp(): Promise<void> { |
541 | 547 |
|
542 | 548 | async function stage_qpdf(): Promise<void> { |
543 | 549 | if (process.platform === "darwin") { |
544 | | - stage_macos_homebrew_bottle_binary("qpdf", "qpdf", path.join(out_dir, "qpdf")); |
| 550 | + stage_macos_homebrew_bottle_qpdf_with_libs(); |
| 551 | + /** libqpdf links to Homebrew openssl (@@HOMEBREW_PREFIX@@); ship those dylibs next to qpdf. */ |
| 552 | + stage_macos_merge_formula_lib_into_destinations("openssl@3", [path.join(out_dir, "qpdf-lib")]); |
545 | 553 | return; |
546 | 554 | } |
547 | 555 | if (process.platform === "linux") { |
@@ -633,17 +641,37 @@ function macos_resolve_latest_bottle_tarball(formula: string): string { |
633 | 641 | return path.join(downloads_dir, bottle); |
634 | 642 | } |
635 | 643 |
|
636 | | -function stage_macos_homebrew_bottle_binary(formula: string, binary_name: string, dest_path: string): void { |
637 | | - const bottle_path = macos_resolve_latest_bottle_tarball(formula); |
638 | | - const tmp = mkdtempSync(path.join(tmpdir(), `prometheus-${formula}-`)); |
| 644 | +/** |
| 645 | + * qpdf binary plus libqpdf dylibs for a relocatable bundle (dyld / @rpath). |
| 646 | + */ |
| 647 | +function stage_macos_homebrew_bottle_qpdf_with_libs(): void { |
| 648 | + const bottle_path = macos_resolve_latest_bottle_tarball("qpdf"); |
| 649 | + const tmp = mkdtempSync(path.join(tmpdir(), "prometheus-qpdf-prefix-")); |
639 | 650 | try { |
640 | 651 | run("tar", ["-xzf", bottle_path, "-C", tmp]); |
641 | | - const found = find_file_by_basename(tmp, binary_name); |
642 | | - if (!found) { |
643 | | - throw new Error(`Could not find ${binary_name} in ${formula} bottle extract`); |
| 652 | + const formula_root = path.join(tmp, "qpdf"); |
| 653 | + if (!existsSync(formula_root)) { |
| 654 | + throw new Error("Bottle extract missing qpdf/ (formula root)"); |
| 655 | + } |
| 656 | + const versions = readdirSync(formula_root); |
| 657 | + if (versions.length < 1) { |
| 658 | + throw new Error("Empty version list for qpdf bottle"); |
| 659 | + } |
| 660 | + const prefix = path.join(formula_root, versions[0]!); |
| 661 | + const bin_src = path.join(prefix, "bin", "qpdf"); |
| 662 | + if (!existsSync(bin_src)) { |
| 663 | + throw new Error("qpdf bottle missing bin/qpdf"); |
| 664 | + } |
| 665 | + const dest_bin = path.join(out_dir, "qpdf"); |
| 666 | + copyFileSync(bin_src, dest_bin); |
| 667 | + chmodSync(dest_bin, 0o755); |
| 668 | + const lib_src = path.join(prefix, "lib"); |
| 669 | + const lib_dest = path.join(out_dir, "qpdf-lib"); |
| 670 | + if (!existsSync(lib_src)) { |
| 671 | + throw new Error("qpdf bottle missing lib/ (libqpdf dylibs required at runtime)"); |
644 | 672 | } |
645 | | - copyFileSync(found, dest_path); |
646 | | - chmodSync(dest_path, 0o755); |
| 673 | + rmSync(lib_dest, { recursive: true, force: true }); |
| 674 | + cpSync(lib_src, lib_dest, { recursive: true, dereference: true }); |
647 | 675 | } finally { |
648 | 676 | rmSync(tmp, { recursive: true, force: true }); |
649 | 677 | } |
|
0 commit comments