From 5d749b26fe40bf26008257089b81bc60242428eb Mon Sep 17 00:00:00 2001 From: Benjamin Carlsson Date: Thu, 10 Sep 2026 16:29:45 -0700 Subject: [PATCH] Stage Linux-only voice alpha rehearsal --- .../scripts/build-codex-package-archive.sh | 7 +- .github/scripts/setup-voice-windows.ps1 | 96 ------- .github/scripts/test_voice_cygwin_inputs.py | 83 ------ .github/scripts/voice-cygwin-inputs.py | 98 ------- .github/scripts/voice-cygwin-snapshot.json | 145 ---------- .github/scripts/voice_windows_tools.py | 80 ------ .github/workflows/rust-release-windows.yml | 255 ++---------------- MODULE.bazel | 2 - patches/BUILD.bazel | 2 - patches/ring_windows_msvc_include_dirs.patch | 20 +- .../rules_foreign_cc_make_msvc_stdint.patch | 13 - patches/rules_rs_windows_msvc_linker.patch | 7 +- ...les_rust_windows_execroot_separators.patch | 52 ---- ...s_rust_windows_msvc_direct_link_args.patch | 2 +- third_party/voice/BUILD.bazel | 3 +- third_party/voice/NOTICE.md | 10 - third_party/voice/README.md | 14 +- third_party/voice/assemble_package.py | 1 - third_party/voice/release_runtime.py | 2 - third_party/voice/test_assemble_package.py | 41 --- third_party/voice/windows-crt.json | 18 -- third_party/voice/windows_crt.py | 83 ------ 22 files changed, 29 insertions(+), 1005 deletions(-) delete mode 100644 .github/scripts/setup-voice-windows.ps1 delete mode 100644 .github/scripts/test_voice_cygwin_inputs.py delete mode 100644 .github/scripts/voice-cygwin-inputs.py delete mode 100644 .github/scripts/voice-cygwin-snapshot.json delete mode 100644 .github/scripts/voice_windows_tools.py delete mode 100644 patches/rules_foreign_cc_make_msvc_stdint.patch delete mode 100644 patches/rules_rust_windows_execroot_separators.patch delete mode 100644 third_party/voice/windows-crt.json delete mode 100644 third_party/voice/windows_crt.py diff --git a/.github/scripts/build-codex-package-archive.sh b/.github/scripts/build-codex-package-archive.sh index ecac99f533..1ac54c0cce 100644 --- a/.github/scripts/build-codex-package-archive.sh +++ b/.github/scripts/build-codex-package-archive.sh @@ -117,8 +117,8 @@ if [[ -z "$target" || -z "$bundle" || -z "$entrypoint_dir" || -z "$archive_dir" usage >&2 exit 1 fi -if [[ ( -n "$voice_release_dir" || -n "$release_version" ) && ( -z "$voice_release_dir" || -z "$release_version" || "$bundle" != "primary" || ( "$target" != *-apple-darwin && "$target" != *-unknown-linux-musl && "$target" != *-pc-windows-msvc ) ) ]]; then - echo "Voice resources require a primary supported release package version" >&2 +if [[ ( -n "$voice_release_dir" || -n "$release_version" ) && ( -z "$voice_release_dir" || -z "$release_version" || "$bundle" != "primary" || ( "$target" != *-apple-darwin && "$target" != *-unknown-linux-musl ) ) ]]; then + echo "Voice resources require a primary macOS or Linux release package version" >&2 exit 1 fi @@ -221,10 +221,9 @@ if [[ -n "$voice_release_dir" ]]; then fi voice_package="${RUNNER_TEMP:-/tmp}/${archive_stem}-voice-${target}" rm -rf "$voice_package" - voice_helper="${voice_release_dir%/}/codex-voice-host${exe_suffix}" "$python_bin" "${repo_root}/third_party/voice/assemble_package.py" \ --package "$package_dir" \ - --helper "$voice_helper" \ + --helper "${voice_release_dir%/}/codex-voice-host" \ --runtime "${voice_release_dir%/}/runtime" \ --voice-target "$voice_target" \ --build-commit "$(git -C "$repo_root" rev-parse HEAD)" \ diff --git a/.github/scripts/setup-voice-windows.ps1 b/.github/scripts/setup-voice-windows.ps1 deleted file mode 100644 index a24d29b1f0..0000000000 --- a/.github/scripts/setup-voice-windows.ps1 +++ /dev/null @@ -1,96 +0,0 @@ -# CI-only prerequisites. Never install these tools into a Codex package. -param( - [Parameter(Mandatory = $true)][string]$Target, - [Parameter(Mandatory = $true)][string]$SnapshotArchive -) - -$ErrorActionPreference = "Stop" -$PkgHashes = @{ - "x86_64-pc-windows-msvc" = @("x64", "5604cf25ef38bb6a09520cff25ae9f0ecd8c2443053b15e40df4ad1eae0e4405") - "aarch64-pc-windows-msvc" = @("arm64", "d5752ce2ac2296c8abb91fb12c12e75ee99ba8a18b52ce5febf325847b6f062b") -} -if (-not $PkgHashes.ContainsKey($Target)) { throw "Unsupported target: $Target" } -$Root = Join-Path $env:RUNNER_TEMP "voice-windows-build-tools" -$Evidence = Join-Path $Root "evidence" -$Cygwin = Join-Path $Root "cygwin" -$Cache = Join-Path $Root "cache" -New-Item -ItemType Directory -Path $Root, $Evidence | Out-Null -$ManifestPath = Join-Path $PSScriptRoot "voice-cygwin-snapshot.json" -$Manifest = Get-Content -Raw $ManifestPath | ConvertFrom-Json -$SnapshotTool = Join-Path $PSScriptRoot "voice-cygwin-inputs.py" -& python $SnapshotTool extract --archive $SnapshotArchive --directory (Join-Path $Cache $Manifest.cacheDirectory) -if ($LASTEXITCODE -ne 0) { throw "Cygwin snapshot could not be verified and extracted" } -Copy-Item $ManifestPath (Join-Path $Evidence "cygwin-snapshot.json") - -# Official https://cygwin.com/setup/sha512.sum and pkgconf release asset digests. -# The complete package closure is pinned separately in cygwin-snapshot.json. -$Inputs = @( - @{ - url = "https://cygwin.com/setup/setup-2.937.x86_64.exe" - file = "setup.exe" - algorithm = "SHA512" - digest = "6acea47c59781c9e7f544a18d53935d59df6e44d5d52ac95ee165671b8e388820455eebf30ccc7d254b00c3d0eb694269a0f8dc84b17944c1f355dac9c5aafcc" - }, - @{ - url = "https://github.com/pkgconf/pkgconf/releases/download/pkgconf-3.0.6/pkgconf-$($PkgHashes[$Target][0])-3.0.6.msi" - file = "pkgconf.msi" - algorithm = "SHA256" - digest = $PkgHashes[$Target][1] - } -) -foreach ($InputFile in $Inputs) { - $Destination = Join-Path $Root $InputFile.file - Invoke-WebRequest -Uri $InputFile.url -OutFile $Destination - $Actual = (Get-FileHash -Path $Destination -Algorithm $InputFile.algorithm).Hash.ToLowerInvariant() - if ($Actual -ne $InputFile.digest) { throw "Build input digest mismatch: $($InputFile.file)" } -} -$Inputs | ConvertTo-Json | Set-Content (Join-Path $Evidence "bootstrap-inputs.json") -$Packages = $Manifest.requestedPackages -join "," -# Only setup.xz + setup.xz.sig are present: local mode still verifies that -# signature. Never substitute an unsigned setup.ini or enable a network fallback. -$Setup = Start-Process -FilePath (Join-Path $Root "setup.exe") -Wait -PassThru -ArgumentList @( - "--quiet-mode", "--no-admin", "--no-shortcuts", "--only-site", - "--local-install", "--no-version-check", - "--root", "`"$Cygwin`"", "--local-package-dir", "`"$Cache`"", - "--packages", $Packages -) -if ($Setup.ExitCode -ne 0) { throw "Cygwin setup failed: $($Setup.ExitCode)" } -Copy-Item (Join-Path $Cygwin "var/log/setup.log*") $Evidence -Copy-Item (Join-Path $Cygwin "etc/setup/installed.db") $Evidence -& (Join-Path $Cygwin "bin/cygcheck.exe") -cd | Set-Content (Join-Path $Evidence "packages.txt") -if ($LASTEXITCODE -ne 0) { throw "Cannot inventory Cygwin packages" } -& python $SnapshotTool check-installed --inventory (Join-Path $Evidence "packages.txt") -if ($LASTEXITCODE -ne 0) { throw "Installed Cygwin package set differs from the snapshot" } -Get-ChildItem $Cache -File -Recurse | ForEach-Object { - @{ file = [IO.Path]::GetRelativePath($Cache, $_.FullName); bytes = $_.Length; - sha512 = (Get-FileHash $_.FullName -Algorithm SHA512).Hash.ToLowerInvariant() } -} | ConvertTo-Json | Set-Content (Join-Path $Evidence "package-cache.json") - -# Administrative extraction uses TARGETDIR, not a normal MSI installation: -# no product registration or system PATH modification. Fail rather than fall -# back to an ambient executable or ordinary installer if the payload is absent. -$Image = Join-Path $Root "pkgconf-image" -$Extract = Start-Process msiexec.exe -Wait -PassThru -ArgumentList @( - "/a", "`"$(Join-Path $Root 'pkgconf.msi')`"", "/qn", "/norestart", - "TARGETDIR=`"$Image`"", "/L*v", "`"$(Join-Path $Evidence 'pkgconf-extract.log')`"" -) -if ($Extract.ExitCode -ne 0) { throw "pkgconf extraction failed: $($Extract.ExitCode)" } -$Candidates = @(Get-ChildItem $Image -Filter pkgconf.exe -File -Recurse) -if ($Candidates.Count -ne 1) { throw "Expected exactly one native pkgconf executable" } -# Bazel shell-quotes execpaths containing spaces; Cargo executes PKG_CONFIG -# directly. Keep the executable and its support files at a space-free execpath. -$Native = Join-Path $Image "native" -if (Test-Path $Native) { throw "Native pkgconf destination must be fresh" } -Move-Item -LiteralPath $Candidates[0].Directory.FullName -Destination $Native -$PkgConfig = Join-Path $Native "pkgconf.exe" -$Version = & $PkgConfig --version -if ($LASTEXITCODE -ne 0 -or $Version -ne "3.0.6") { throw "Unexpected native pkgconf version" } -@{ target = $Target; cygwin_root = $Cygwin; pkg_config = $PkgConfig; - pkgconf_version = $Version; requested_packages = $Packages } | - ConvertTo-Json | Set-Content (Join-Path $Evidence "tools.json") -# Declare complete installed support trees only after snapshot and tool checks. -& python (Join-Path $PSScriptRoot "voice_windows_tools.py") --root $Root --target $Target --pkg-config $PkgConfig -if ($LASTEXITCODE -ne 0) { throw "Cannot declare Windows Bazel tool inputs" } -"VOICE_WINDOWS_BAZEL_REPOSITORY=$Root" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append -"VOICE_CYGWIN_ROOT=$Cygwin" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append -"VOICE_PKG_CONFIG=$PkgConfig" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append diff --git a/.github/scripts/test_voice_cygwin_inputs.py b/.github/scripts/test_voice_cygwin_inputs.py deleted file mode 100644 index 3b5a4d31ae..0000000000 --- a/.github/scripts/test_voice_cygwin_inputs.py +++ /dev/null @@ -1,83 +0,0 @@ -"""Offline checks for the public Windows build-input bootstrap.""" - -import hashlib -import importlib.util -import io -from pathlib import Path -import tarfile -import tempfile -import unittest - - -SCRIPT = Path(__file__).with_name("voice-cygwin-inputs.py") -SPEC = importlib.util.spec_from_file_location("voice_cygwin_inputs", SCRIPT) -inputs = importlib.util.module_from_spec(SPEC) -SPEC.loader.exec_module(inputs) - - -class VoiceCygwinInputsTests(unittest.TestCase): - def test_input_paths_cannot_escape_the_local_cache(self): - manifest = { - "metadata": [ - {"file": "x86_64/setup.xz"}, - {"file": "x86_64/setup.xz.sig"}, - ], - "packages": [{"file": "../outside.tar.xz"}], - } - with self.assertRaisesRegex(ValueError, "unsafe Cygwin input"): - inputs.records(manifest) - - def test_extract_verifies_archive_and_every_input_before_offline_installation(self): - with tempfile.TemporaryDirectory() as directory: - root = Path(directory) - payloads = { - "x86_64/setup.xz": b"metadata", - "x86_64/setup.xz.sig": b"signature", - "x86_64/release/bash/bash.tar.xz": b"package", - } - records = [ - { - "file": name, - "bytes": len(data), - "sha512": hashlib.sha512(data).hexdigest(), - } - for name, data in payloads.items() - ] - archive = root / "inputs.tar.gz" - - def write_archive(contents): - with tarfile.open(archive, "w:gz") as bundle: - for name, data in contents.items(): - info = tarfile.TarInfo(name) - info.size = len(data) - bundle.addfile(info, io.BytesIO(data)) - return { - "bytes": archive.stat().st_size, - "sha256": hashlib.sha256(archive.read_bytes()).hexdigest(), - } - - manifest = { - "metadata": records[:2], - "packages": records[2:], - "archive": write_archive(payloads), - } - destination = root / "cache" - inputs.extract(manifest, archive, destination) - self.assertEqual( - { - record["file"]: (destination / record["file"]).read_bytes() - for record in records - }, - payloads, - ) - - (destination / records[2]["file"]).unlink() - payloads[records[2]["file"]] = b"wrong" - manifest["archive"] = write_archive(payloads) - with self.assertRaisesRegex(ValueError, "Cygwin input mismatch"): - inputs.extract(manifest, archive, root / "rejected") - self.assertFalse((root / "rejected").exists()) - - -if __name__ == "__main__": - unittest.main() diff --git a/.github/scripts/voice-cygwin-inputs.py b/.github/scripts/voice-cygwin-inputs.py deleted file mode 100644 index 11b2ebda7d..0000000000 --- a/.github/scripts/voice-cygwin-inputs.py +++ /dev/null @@ -1,98 +0,0 @@ -"""Verify the pinned Cygwin build-input archive before offline installation.""" - -import argparse -import hashlib -import json -from pathlib import Path, PurePosixPath -import shutil -import tarfile - - -def records(manifest): - metadata = manifest["metadata"] - if {item["file"] for item in metadata} != { - "x86_64/setup.xz", - "x86_64/setup.xz.sig", - }: - raise ValueError("signed setup metadata is required") - entries = metadata + manifest["packages"] - expected = {entry["file"]: entry for entry in entries} - if len(expected) != len(entries): - raise ValueError("duplicate Cygwin input") - for name in expected: - path = PurePosixPath(name) - if ( - not path.parts - or path.is_absolute() - or ".." in path.parts - or path.as_posix() != name - or "\\" in name - or ":" in name - ): - raise ValueError(f"unsafe Cygwin input: {name}") - return expected - - -def extract(manifest, archive, destination): - expected = records(manifest) - pin = manifest["archive"] - with archive.open("rb") as stream: - if ( - archive.stat().st_size != pin["bytes"] - or hashlib.file_digest(stream, "sha256").hexdigest() != pin["sha256"] - ): - raise ValueError("Cygwin archive digest or size mismatch") - stream.seek(0) - with tarfile.open(fileobj=stream, mode="r:gz") as bundle: - members = bundle.getmembers() - if len(members) != len(expected) or {m.name for m in members} != set( - expected - ): - raise ValueError("missing, extra, or duplicate Cygwin inputs") - for member in members: - if not member.isfile() or member.issparse(): - raise ValueError(f"non-regular Cygwin input: {member.name}") - with bundle.extractfile(member) as source: - if ( - member.size != expected[member.name]["bytes"] - or hashlib.file_digest(source, "sha512").hexdigest() - != expected[member.name]["sha512"] - ): - raise ValueError(f"Cygwin input mismatch: {member.name}") - destination.mkdir(parents=True) - try: - bundle.extractall(destination, members=members, filter="data") - except BaseException: - shutil.rmtree(destination) - raise - - -def check_installed(manifest, inventory): - installed = sorted( - tuple(line.split()) - for line in inventory.read_text().splitlines() - if len(line.split()) == 2 and not line.startswith("Package ") - ) - expected = sorted((item["name"], item["version"]) for item in manifest["packages"]) - if installed != expected: - raise ValueError("installed Cygwin packages differ from reviewed inputs") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("command", choices=("extract", "check-installed")) - parser.add_argument("--archive", type=Path) - parser.add_argument("--directory", type=Path) - parser.add_argument("--inventory", type=Path) - args = parser.parse_args() - pinned = json.loads( - Path(__file__).with_name("voice-cygwin-snapshot.json").read_text() - ) - if args.command == "extract": - if args.archive is None or args.directory is None: - parser.error("extract requires --archive and --directory") - extract(pinned, args.archive, args.directory) - else: - if args.inventory is None: - parser.error("check-installed requires --inventory") - check_installed(pinned, args.inventory) diff --git a/.github/scripts/voice-cygwin-snapshot.json b/.github/scripts/voice-cygwin-snapshot.json deleted file mode 100644 index 8679adca1e..0000000000 --- a/.github/scripts/voice-cygwin-snapshot.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "schemaVersion": 1, - "sourceMirror": "https://mirrors.kernel.org/sourceware/cygwin/", - "cacheDirectory": "https%3a%2f%2fmirrors.kernel.org%2fsourceware%2fcygwin%2f", - "requestedPackages": [ - "bash", - "make", - "automake1.18", - "coreutils", - "diffutils", - "findutils", - "grep", - "sed", - "gawk" - ], - "signingFingerprint": "56405CF6FCC81574682A5D561A698DE9E2E56300", - "archive": { - "tag": "voice-cygwin-108b38cf67cbb731", - "name": "cygwin-build-inputs.tar.gz", - "bytes": 62276721, - "sha256": "108b38cf67cbb731801e5ca8d8412b8f349961e4e71d8e3d5a1768f1a8d15c50" - }, - "metadata": [ - { - "file": "x86_64/setup.xz", - "bytes": 3598392, - "sha512": "306bffefa1e86178d9c6ff78a8add2e1af3c96f7cd698d62b58d0237a568e1a9f1b30016ed5891f9fe1d1c8a1e58089c3d9cb8989eb7bed758a928f212078e25" - }, - { - "file": "x86_64/setup.xz.sig", - "bytes": 566, - "sha512": "7c466da6446bbef67762ff4038dd4986018ed09432bd6ee6ca9e33150874dbb9d61c7e4b06bd925f932a55fda345401224689bbaddc135d7300651f67ec8160b" - } - ], - "sourceArchive": { - "name": "cygwin-build-sources.tar", - "bytes": 368824320, - "sha256": "13a42ea4e6465f77c32f91e4162f41bcfeab7c0eca47701bb6a8b9aca1eb99f4" - }, - "packages": [ - {"name": "_autorebase", "version": "001091-1", "file": "noarch/release/_autorebase/_autorebase-001091-1.tar.zst", "bytes": 4696, "sha512": "a9416ce992ca57f3a6208f46517520d21dfac61988ac84cbb5b17b76e053a0845c15368ccb8ca9c483d8935f9e3db81568433c0d08d0265ec5e6916ea30f2831"}, - {"name": "alternatives", "version": "1.31-1", "file": "x86_64/release/alternatives/alternatives-1.31-1.tar.xz", "bytes": 123748, "sha512": "94adf3376e7fcaf937594be718f54a99f2a2b66367eb2bb294b6fd4a933a9515954a9e9f309ed74cc62fbb353adb053d8500bbaf42994e4355f7180664afa62c"}, - {"name": "autoconf", "version": "15-3", "file": "noarch/release/autoconf/autoconf-15-3-noarch.tar.zst", "bytes": 2396, "sha512": "edaa6c97c5b50e138acef4b80406bfdd0988da3360cc622be2541593f6e926a4fbe1088ff608ddadfacf275b3924605d54f59e140cc7c79b31f4885e5878ad6f"}, - {"name": "autoconf2.1", "version": "2.13-12", "file": "noarch/release/autoconf2.1/autoconf2.1-2.13-12.tar.bz2", "bytes": 204911, "sha512": "96f8f592fff4665512c0023d6a7844fdc281ba99dc98dee9e55c37523b3a1279ae8fd31559fa6426edb1da7559a483b3eae99ae7911d50646ec60338ef209c18"}, - {"name": "autoconf2.5", "version": "2.69-5", "file": "noarch/release/autoconf2.5/autoconf2.5-2.69-5.tar.zst", "bytes": 341597, "sha512": "3739719f29ad3ab1c1045b72ccbfe6c58e3f7696ac063c2ff4e09e11e1a9015f289fa8fc267a62b43cb2f6b682b83d3b4b6450040e733f9f41d086dc4a2f36b9"}, - {"name": "autoconf2.7", "version": "2.73-1", "file": "noarch/release/autoconf2.7/autoconf2.7-2.73-1-noarch.tar.zst", "bytes": 906344, "sha512": "0493d68a7ea9cd61e403b6b7086b5302bad5bc1cc35715349f59605a795ac7a9f901c444cb387e5f44d1860de3e5d0fcfceee4ee2726d68904cfc5e2db6e90e9"}, - {"name": "automake1.18", "version": "1.18.1-1", "file": "noarch/release/automake1.18/automake1.18-1.18.1-1-noarch.tar.zst", "bytes": 921189, "sha512": "416ef8041505ecddc23e9e72394ef3a81311c6c378b8b6d348e989584c77924d40aa427b47ab4d3a9a2b83438d13995bb7c6302afb73af3d3af7f2e9061579c0"}, - {"name": "base-cygwin", "version": "3.8-2", "file": "noarch/release/base-cygwin/base-cygwin-3.8-2.tar.xz", "bytes": 1260, "sha512": "e03949b4ae6b692858e1d29fb764afbda990c07a6b70b0eb7219fc12f28dfba3cf7e757a7570c31e315be79f091b012d6a6ddafdb4b0b8961afe9af9f4977fab"}, - {"name": "base-files", "version": "4.3-3", "file": "noarch/release/base-files/base-files-4.3-3.tar.zst", "bytes": 46481, "sha512": "dfafbe28fbe89d9b72a2eeb10901712e04de71d9089a85cfd2b8d45ffd739bdd49dadb7b57d098f01b8902456f5b839e9d4a10dbd6a8001573e035fde6797b63"}, - {"name": "bash", "version": "5.2.21-1", "file": "x86_64/release/bash/bash-5.2.21-1.tar.xz", "bytes": 1650932, "sha512": "c3a5594f1c248dd27a3b5aa10c31fb1651072eae878479d3d8cab09c28354ce4509a2fe230f176ad200a6484a561bc10c2dc9c74c4e9f03164190dac2e683d65"}, - {"name": "bzip2", "version": "1.0.8-2", "file": "x86_64/release/bzip2/bzip2-1.0.8-2-x86_64.tar.xz", "bytes": 36396, "sha512": "86e4b0b21b64d17b9fb60260a787626125102b0cb786de67893cb1d39a109457637bdb93956c992429f1135f64b07def64dd0116682a6190b635ba12f81395d7"}, - {"name": "ca-certificates", "version": "2025.2.80_v9.0.304-1", "file": "noarch/release/ca-certificates/ca-certificates-2025.2.80_v9.0.304-1-noarch.tar.zst", "bytes": 902180, "sha512": "49d08f490db12855f8794cd5cfc721940504d36deffdd3b9aea0fc75909e27471f795d48c739630498fd4baeecb76ee0adb5e5c4cecab4db2ea39b03391a02d0"}, - {"name": "coreutils", "version": "9.0-1", "file": "x86_64/release/coreutils/coreutils-9.0-1.tar.xz", "bytes": 2767296, "sha512": "530f47640d878f5953580f3556c492a93786191abe573322026b70206a46c7f17d05927784db3e7f2c044d1555f35941880316f7288b887eaec770a9eda4c687"}, - {"name": "crypto-policies", "version": "20190218-1", "file": "noarch/release/crypto-policies/crypto-policies-20190218-1.tar.xz", "bytes": 14032, "sha512": "44d50ff08528df786eeb26ec1d312445ec92d77ecc9f448a3b741f7647e187f11eabdc0b38f8ab8de803e21d2e610f67eb44de7554f3fa83f6e8172e609b0054"}, - {"name": "cygutils", "version": "1.4.17-4", "file": "x86_64/release/cygutils/cygutils-1.4.17-4-x86_64.tar.xz", "bytes": 90580, "sha512": "a9c63f8ac86e529fa8809c9637bb80651721003160726e2058c361687e5df6377c4cdbea2d023677b23e1d166bbce37d5a412f7d1135baf075ae2631fdeb77b2"}, - {"name": "cygwin", "version": "3.6.10-1", "file": "x86_64/release/cygwin/cygwin-3.6.10-1-x86_64.tar.xz", "bytes": 1626060, "sha512": "50e5a100f5229eecba279799363a30d599f8c6ad06967eabc4fc8ed9105736576a522539abc250110282cf18da8536d4e408823cc6c0d2abd8692a91d9fd3341"}, - {"name": "dash", "version": "0.5.12-5", "file": "x86_64/release/dash/dash-0.5.12-5.tar.xz", "bytes": 79612, "sha512": "8891165224ca8531ad7b601309bc1a74f8b68dad24721060fd3db5d12ae504e3c96bbd0217006bbcbe0650d13283f04c1f58412bde54c40f19acb5291dfaced9"}, - {"name": "diffutils", "version": "3.12-1", "file": "x86_64/release/diffutils/diffutils-3.12-1-x86_64.tar.xz", "bytes": 431400, "sha512": "2a9d8fa0acd5a6108f74afe515f55a2a7cade6fa7f96368e46a6f33cf3b49d270b50dc3cee0320740c8f1729edcbf8dd3824f4b268261fba7aeed0d75a4e943c"}, - {"name": "editrights", "version": "1.04-1", "file": "x86_64/release/editrights/editrights-1.04-1.tar.xz", "bytes": 7112, "sha512": "aadc188201441ee1ff5710df0e5550c8ca5cb65421d025c5845921510560a2875c317d1f35b6ea8abbb5077172c0de7fc8f2f55ae95dc8d1e59d26c963c93aa7"}, - {"name": "file", "version": "5.46-1", "file": "x86_64/release/file/file-5.46-1-x86_64.tar.xz", "bytes": 840940, "sha512": "e4b52477d353557d36af625a6a55c97a11ae41053ce17602624210df2a6d2683f46250c2b9f6db5a9f9e5fcccb7b0be4b24705a36d196cee677bf47d90dfee99"}, - {"name": "findutils", "version": "4.11.0-1", "file": "x86_64/release/findutils/findutils-4.11.0-1-x86_64.tar.xz", "bytes": 768172, "sha512": "cbb1359fd81c55f98da1485f84f11f905a7a3fe9ce1676424e86da4d7f0effa5fc298546bd5c62c9707e8ddf93c31597d6da01e60be0610c50b9b22ef9475814"}, - {"name": "gawk", "version": "5.4.0-1", "file": "x86_64/release/gawk/gawk-5.4.0-1-x86_64.tar.xz", "bytes": 1496256, "sha512": "3604c99921d0cff387279aec1d3b332e8afcd2746b052304c0511221efdb6ae6d4a3117b36593e44adc43c67b6f6c4c48bccf6b686e2e1a5cac644c89613d829"}, - {"name": "getent", "version": "2.18.90-5", "file": "x86_64/release/getent/getent-2.18.90-5.tar.xz", "bytes": 17864, "sha512": "b860f3d01f32da7312a0ce118bdaa53e2418c53f0ac5cfd52b3e4267f353fa21ae27fd2649eb9c6bff48b3d10a0a9f7bcaa2d644f770f0f3916f5d969beedd65"}, - {"name": "gettext-locale-alias", "version": "0.26-1", "file": "x86_64/release/gettext/gettext-locale-alias/gettext-locale-alias-0.26-1-x86_64.tar.xz", "bytes": 1596, "sha512": "289feafbe00598a2451527b64b0187ab62115577ceaa960774b020270e5a8c5bff4038f389a44c7d9eb870f7e2741c7bb2b27be507843cc8c4ae5c33bc74c8f3"}, - {"name": "grep", "version": "3.12-1", "file": "x86_64/release/grep/grep-3.12-1-x86_64.tar.xz", "bytes": 418788, "sha512": "2ba28b5d93c352bc3f3f0f232e2052e6651b71cc535841f4ff8cedb23e61e9e4c030d7d5516ed9c797074e1a59cbf3a56732ca678cb0e986e86dcbbf25955976"}, - {"name": "groff", "version": "1.24.1-1", "file": "x86_64/release/groff/groff-1.24.1-1-x86_64.tar.zst", "bytes": 5878965, "sha512": "9e8aaab0e6f464df3fec6b96fed6679673091aaeafaa463ed518081cb156ef7441fb5f9341a251f602334862640ea0b0fc1b158746c08a1e2529cceeb37e9802"}, - {"name": "gzip", "version": "1.14-1", "file": "x86_64/release/gzip/gzip-1.14-1-x86_64.tar.xz", "bytes": 164124, "sha512": "57995d2e90bf435ffff8f61cd79c4970ad7260e0c407ab52d4dbacb0540a74c7f8fd0d8bd905316eff31525d9b0367284f9f250950f78f179e5260ce59be3a98"}, - {"name": "hostname", "version": "3.13-1", "file": "x86_64/release/hostname/hostname-3.13-1.tar.bz2", "bytes": 14024, "sha512": "75114326fa4575b8341434658a881feb81a6565e7e0adf8fd100dde87022d3818b5fc3df430bd9b3298d818a1d23f6b6c4bc7ff33efb3ded5f0ea0bf118c1aae"}, - {"name": "info", "version": "7.3-1", "file": "x86_64/release/texinfo/info/info-7.3-1-x86_64.tar.zst", "bytes": 607040, "sha512": "3af0e7c2edc34a068d88974c6c1b0f529663f4bbce145b5a33f3b7e90671fd908fb4a544e033b98a6906d3244c64a18732104c5f1d323c0ccac8a5134e13f411"}, - {"name": "ipc-utils", "version": "1.1-1", "file": "x86_64/release/ipc-utils/ipc-utils-1.1-1.tar.xz", "bytes": 11120, "sha512": "374ef40c871d00eb3b4774c383bb85872443a2e8b9abf74b8b9b9b27984598abfb6284716c2d2cd264181e6d012cf7dc8cd04f6bab91f9b083f72e9b51e6226b"}, - {"name": "less", "version": "704-1", "file": "x86_64/release/less/less-704-1-x86_64.tar.xz", "bytes": 171024, "sha512": "2d1ecf29272e7c1781bb0df5b0f0531b009972edc8d246d63e17edf7d8314109f0a8f38668b371c6f5e1dc1f948d63384eecdca5409eacb927c4f267f89f4bfe"}, - {"name": "libargp", "version": "20250917-2", "file": "x86_64/release/libargp/libargp-20250917-2-x86_64.tar.xz", "bytes": 19508, "sha512": "a83ef7c1809cae1b10a50e228643a640ea14e1be324429b9f53be9a4c8cee03ddd0efb46b24e159493dfa36569e73b636bc897943d61cdb90511e5e4cbb54257"}, - {"name": "libattr1", "version": "2.5.2-2", "file": "x86_64/release/attr/libattr1/libattr1-2.5.2-2-x86_64.tar.xz", "bytes": 6160, "sha512": "345b8f84b9c4df2eeea5e211dbaff5e0382aaee788435e1f4cc69f546e1603bbb45e9baec02a37d935674fcd55fb782d924c3a1540d2f829bde4969c96945ce4"}, - {"name": "libblkid1", "version": "2.40.2-2", "file": "x86_64/release/util-linux/libblkid1/libblkid1-2.40.2-2.tar.xz", "bytes": 120936, "sha512": "d931c47cce5a7caf18799a16ed526e0f0d0f82c0f6d0af952420d50d88f1e0f0ea9d6c07be72f9d0baa06a3299b2db8c3bd3c43d13d94400edc816e7c00da148"}, - {"name": "libbz2_1", "version": "1.0.8-2", "file": "x86_64/release/bzip2/libbz2_1/libbz2_1-1.0.8-2-x86_64.tar.xz", "bytes": 26884, "sha512": "d15d88e8e0fae69f7c4c3025515e748c273d758a0f470312162cec46c4cf0d340d2ef036e3a4f4d03b5edf4508b4927834ffa0f9aa45585a5f3bc3b3163ff675"}, - {"name": "libcrypt2", "version": "4.5.2-1", "file": "x86_64/release/libxcrypt/libcrypt2/libcrypt2-4.5.2-1-x86_64.tar.xz", "bytes": 106104, "sha512": "7668d29aaebba8ca94e48e810d92108db72b067b2786cea8dcf4a049c29f20f0aeb8653a6e9524869c69e0b1df9d4d0ac499a052a86f0d44178e8a8167002c97"}, - {"name": "libdb18.1", "version": "18.1.40-1", "file": "x86_64/release/db/libdb18.1/libdb18.1-18.1.40-1.tar.xz", "bytes": 733872, "sha512": "51955ae95823c54051b5345a7dbe6927521411754dff416ad6af2061bd3c9b2230ca2ea88f9b921b4b09b7654c7dac924b0ae08af708a93604cc193d6a18f4ff"}, - {"name": "libfdisk1", "version": "2.40.2-2", "file": "x86_64/release/util-linux/libfdisk1/libfdisk1-2.40.2-2.tar.xz", "bytes": 160264, "sha512": "0c8e6854eb72bb8cc51fc33565ee0d36a747e520e98e074a1d2400672a45651807b53be0f5a1c97efa0ce34975063f86953c9465312dcfdaba8104edb1298d62"}, - {"name": "libffi8", "version": "3.8.0-1", "file": "x86_64/release/libffi/libffi8/libffi8-3.8.0-1-x86_64.tar.xz", "bytes": 196924, "sha512": "935a0567f740a314d70ecd4adc8c4cf5ad37c6fb43f2d26dee882d4fda71f08efb2646bee10cee6e2000f52e25cce87fa29ce07665ba6d22532e0daa76bc887c"}, - {"name": "libgc1", "version": "8.2.12-1", "file": "x86_64/release/libgc/libgc1/libgc1-8.2.12-1-x86_64.tar.xz", "bytes": 62392, "sha512": "faf226ea2b58949da714e2c50f1aa95738082c3499e2ae4828af5173bdd617248f000bf4868636b31a2b76b3a905057ab307c4f6a0d7112f23422531a97be92d"}, - {"name": "libgcc1", "version": "14.4.0-1", "file": "x86_64/release/gcc/libgcc1/libgcc1-14.4.0-1-x86_64.tar.zst", "bytes": 59166, "sha512": "5ac8a56e5eee285efcd6dbd05a473e795e181021d7194b8a98dfe2fa201a71f0abe2908e0b4c81490eb5ef472efaeac8e56a61a5f289eee4ad6e90e52a844ff8"}, - {"name": "libgdbm6", "version": "1.26-1", "file": "x86_64/release/gdbm/libgdbm6/libgdbm6-1.26-1-x86_64.tar.xz", "bytes": 25436, "sha512": "8ed666a5b978b40f8cfc69d270d47cd674a31eb41bac499f783137eedfde6aa02ba4346de3d5dc3184d9af10ec80f57730c7517a88732616f4c6e0ef637d4bce"}, - {"name": "libgdbm_compat4", "version": "1.26-1", "file": "x86_64/release/gdbm/libgdbm_compat4/libgdbm_compat4-1.26-1-x86_64.tar.xz", "bytes": 3892, "sha512": "fd026dd74c495c1ee67b790269e77e8525ad78d52d4895923443feab55f7bb32dc07b115d490143c7e0277167d9cdbef5dad4707ecc7ca6df13a9f1a5184f8ca"}, - {"name": "libgmp10", "version": "6.3.0-1", "file": "x86_64/release/gmp/libgmp10/libgmp10-6.3.0-1.tar.zst", "bytes": 254680, "sha512": "947cd56e1945ddf180622b453f17e6655b4ee3e79fcc91238370a8826b88cd07c31d939f1ed7b87d91344d46fee90af2560105267a9207dcca800cba72459191"}, - {"name": "libguile3.0_1", "version": "3.0.11-1", "file": "x86_64/release/guile3.0/libguile3.0_1/libguile3.0_1-3.0.11-1-x86_64.tar.xz", "bytes": 6969492, "sha512": "a559914ed5d62d0a701e4ce3810276436cf1ce54d579c72fc72c3b4688f2af71ef93f3cdae7089ad7f85107c7ca5c87f2e497cac6f2550b38df1bc6ba7f16230"}, - {"name": "libiconv2", "version": "1.19-2", "file": "x86_64/release/libiconv/libiconv2/libiconv2-1.19-2-x86_64.tar.xz", "bytes": 555664, "sha512": "a1b23e24e0a495e7163923bcf40a4b933403e0826cfc0d9bde785bc92c909b8c4fb94b1e6b2c0242f4328a723855e72ff3baab9f557ef855b7fe7a7d901b0943"}, - {"name": "libintl8", "version": "0.22.5-1", "file": "x86_64/release/gettext/libintl8/libintl8-0.22.5-1.tar.xz", "bytes": 43256, "sha512": "370a19af888bc7c9ed95cf8ade0d36d5e7cdb634abdebcba260cad61fa9a4cc05b5e748e315c9709f66861e8756b227d6757d529846591189e19ee2b2d00002d"}, - {"name": "liblastlog2", "version": "2.40.2-2", "file": "x86_64/release/util-linux/liblastlog2/liblastlog2-2.40.2-2.tar.xz", "bytes": 4908, "sha512": "89350921fe76c9065662dd9d72dd464d2f404f1690e806210cbb828ae8325ea5f3f9909d8eb04c8342b80417a4e1e22c3569241515762ad081ecd58d56927c02"}, - {"name": "liblz4_1", "version": "1.9.4-1", "file": "x86_64/release/lz4/liblz4_1/liblz4_1-1.9.4-1.tar.xz", "bytes": 53296, "sha512": "70e6b0f3af2c5e04089c955b46c13293ab935ee4683e4690da0cebfffba4ba91614004aede99dd804f54e4def93461159f55d151e7fbb647d1ca97ca29e619cc"}, - {"name": "liblzma5", "version": "5.8.3-1", "file": "x86_64/release/xz/liblzma5/liblzma5-5.8.3-1-x86_64.tar.zst", "bytes": 87321, "sha512": "7399c6d117f23788a7edb11cf7f5eec77724aad2bf7cf8a437001fc1515941f6ca415f42363981be35361290f43cd60cd04e15bb1b01cffc0fd275f3167037e0"}, - {"name": "libmpfr6", "version": "4.2.2-1", "file": "x86_64/release/mpfr/libmpfr6/libmpfr6-4.2.2-1.tar.zst", "bytes": 284416, "sha512": "8203dc61bf646041c71f7fece9fe59422ded96ac28dd24826ffb00a9607f274f3226673f9bee441f32b424a7e26c2f178281bd7836db26b0253d37da208d06a8"}, - {"name": "libncursesw10", "version": "6.5+20240427-1", "file": "x86_64/release/ncurses/libncursesw10/libncursesw10-6.5+20240427-1.tar.xz", "bytes": 393928, "sha512": "08102f7a7083cb5663fecc46d819f2ece4123444a8f94c42300f03f7eebd40395f556c44b22ab58bf57321b44d9b8fb8b19358e535c7500d36e52d48b05dcca8"}, - {"name": "libp11-kit0", "version": "0.26.5-1", "file": "x86_64/release/p11-kit/libp11-kit0/libp11-kit0-0.26.5-1-x86_64.tar.xz", "bytes": 212700, "sha512": "dd64f129fe71233e26e0845b6711db5cf2eb2e6d2d050f07b6aec0d9dd54d980e87390614744fbf022cf57aa2b3f7edbdc30c548c2f9d480188c22bcde0c2eba"}, - {"name": "libpcre1", "version": "8.45-1", "file": "x86_64/release/pcre/libpcre1/libpcre1-8.45-1.tar.zst", "bytes": 166711, "sha512": "85c793ed3622a00b811773b94c45376882513e267b9f1d2a3efa0bc42ff86a4e4bebd8362a193d302e66ae9e5c9b93befc1bb1096c0fd397e2cd0f5632c808dd"}, - {"name": "libpcre2_8_0", "version": "10.47-1", "file": "x86_64/release/pcre2/libpcre2_8_0/libpcre2_8_0-10.47-1-x86_64.tar.zst", "bytes": 237134, "sha512": "a98b38e1591c19404a5794cef488810747d86cc27ce5ee326e706cfa7069cf088d8a64571933f4c1f7a611fd8c232008837271bebe2e81c04a3f6ec571f0009e"}, - {"name": "libpipeline1", "version": "1.5.8-1", "file": "x86_64/release/libpipeline/libpipeline1/libpipeline1-1.5.8-1-x86_64.tar.xz", "bytes": 24880, "sha512": "1d062ac4909d37fbac3ce66b07ac691df0ae5acbd01f08c5019a5ed897cb2bbef95f9e347c5bc71185ae3317d89383306e46f2c59acae5d28a18fa65f66d4e80"}, - {"name": "libpopt-common", "version": "1.19-1", "file": "x86_64/release/popt/libpopt-common/libpopt-common-1.19-1.tar.xz", "bytes": 18536, "sha512": "4d69e6d7e196cdb4caad558c5d7543f706a4c6d7053476be861be07672506e378084126f22903deab8113557f757d2a07578f4a790ae316a2ea50ba612148a43"}, - {"name": "libpopt0", "version": "1.19-1", "file": "x86_64/release/popt/libpopt0/libpopt0-1.19-1.tar.xz", "bytes": 18748, "sha512": "e820a7bac13cdd3bff07673ac54dcb80f342c6a32917035f218ef255bdb707d654ee6a1684242d7ce8439eebf050ade6566f27f5118896fbf8e0171173b5bfee"}, - {"name": "libreadline7", "version": "8.2-2", "file": "x86_64/release/readline/libreadline7/libreadline7-8.2-2.tar.xz", "bytes": 113340, "sha512": "1d27576cf49b056f35f90ad933e39c5d946bc271ddcd109daa98f95b97123b428256827889ff45ca8a76409cdb1afd0146e99c9b70150b302538356512acfe38"}, - {"name": "libreadline8", "version": "8.3-1", "file": "x86_64/release/readline/libreadline8/libreadline8-8.3-1-x86_64.tar.xz", "bytes": 120084, "sha512": "64142c5f305b9836c5be9a4271e4163d8b3e739a0451c0d152373eeb3338342f7cf5691e4437b8e6d0a8404c30ea7a21832e342e7a1ca3b5f3e8e3403051b96e"}, - {"name": "libsmartcols1", "version": "2.40.2-2", "file": "x86_64/release/util-linux/libsmartcols1/libsmartcols1-2.40.2-2.tar.xz", "bytes": 96124, "sha512": "71ded6f02d264343d068b90450d96f4fdeb4087f278b990709aaa814c16123f4ae947714e5f10020260c30a6d78865c2d35d9ffe57a51b038815db52c3274317"}, - {"name": "libsqlite3_0", "version": "3.49.1-1", "file": "x86_64/release/sqlite3/libsqlite3_0/libsqlite3_0-3.49.1-1.tar.xz", "bytes": 686212, "sha512": "cd81686fe5778a94ab91e4aebdd2a229cb963318ce7b393e0a0299e29ed7648c24135733c1978cbebbb926813d7f994b9e38318ede12c72fe79ad404dbfdeaf2"}, - {"name": "libssl3", "version": "3.5.7-1", "file": "x86_64/release/openssl/libssl3/libssl3-3.5.7-1-x86_64.tar.zst", "bytes": 2081790, "sha512": "18161f1292404554742ced4beaa10548c7e1bbfb9398ec0b733e632401dfaa49c33336ad4b1e80e2b7bd77c20f00c10196c5804c327e37f641d49da2288837b8"}, - {"name": "libstdc++6", "version": "14.4.0-1", "file": "x86_64/release/gcc/libstdc++6/libstdc++6-14.4.0-1-x86_64.tar.zst", "bytes": 651767, "sha512": "3d86409193c952618eee7e2dea32bdeb97f22ee800e13cc46f98b5095d4d0b1b31ac4336dc5819abb2d553ad1c2151619e9f6f337dfe921ba80fda1323f6f4e3"}, - {"name": "libtasn1_6", "version": "4.21.0-1", "file": "x86_64/release/libtasn1/libtasn1_6/libtasn1_6-4.21.0-1-x86_64.tar.xz", "bytes": 32072, "sha512": "d28713b27d5d41408b29caed785e29380da4d8b4ccdc1c479ae13906e6765bedc6d6b9e6c1c22fd2111d678fcf1663187d3de27d7ad2e104cd48c38086189e36"}, - {"name": "libuchardet0", "version": "0.0.8-1", "file": "x86_64/release/uchardet/libuchardet0/libuchardet0-0.0.8-1.tar.zst", "bytes": 72637, "sha512": "1fad5711590a82a8386c2492286dd9c0ad7cbe086aab249d07ad27277757327a6a67264e9718aef7d30307515462fe67d64f23582f08f0ced85a19cc8e0afe23"}, - {"name": "libunistring-devel", "version": "1.4.1-1", "file": "x86_64/release/libunistring/libunistring-devel/libunistring-devel-1.4.1-1-x86_64.tar.xz", "bytes": 43332, "sha512": "14e067719e5c0a973950955a05685c18d6fa97df5defa8d0915125ea3af1d01ac921c2a84565a49cc7fb785b15a8be4640ee209f3f0d2e13cb542eb6c75b51f9"}, - {"name": "libunistring5", "version": "1.4.1-1", "file": "x86_64/release/libunistring/libunistring5/libunistring5-1.4.1-1-x86_64.tar.xz", "bytes": 498220, "sha512": "cbd454f5068bfb9291d440a3b03b0c58437aa0342a199007d5cce6fa006b6b5ea4d3ba10c136fb0257ffb0d0199db73484275c632506e4ec31c81e1746667b80"}, - {"name": "libuuid1", "version": "2.40.2-2", "file": "x86_64/release/util-linux/libuuid1/libuuid1-2.40.2-2.tar.xz", "bytes": 12532, "sha512": "3ba0c5d5a401c88796077e9f45164532408882f2f5d9f0ab99b2fdf6eb915917250124cde3653a7c53b648866e091aa3baf3304d0b243337f0d4e254a7631f55"}, - {"name": "libzstd1", "version": "1.5.7-1", "file": "x86_64/release/zstd/libzstd1/libzstd1-1.5.7-1.tar.zst", "bytes": 253786, "sha512": "f89cdaa004487ec8c4796b8f56887c81f6f497873c1495b9cb585ffe6c8d6e6b8ad4b52617d5238075f965f1fe001da287d9a00d121590274b2d87672b415a0f"}, - {"name": "login", "version": "1.13-1", "file": "x86_64/release/login/login-1.13-1.tar.xz", "bytes": 17264, "sha512": "66acc3255962a27af8d701a8c02846f3b9180b7b1d65d946f6fb27cd24aeedc8e6a9a2601b419e981c94b356ef376a5c565ea31a4a220e5add9d70ae501a11d1"}, - {"name": "m4", "version": "1.4.21-1", "file": "x86_64/release/m4/m4-1.4.21-1-x86_64.tar.xz", "bytes": 363204, "sha512": "0d86c88d4bbbfc59e136bba3101ca3714139fba2ab7fea2883bc773ca884c3876f8a8f3a2ea8b05c29fd5280c1fb2d686401346f2761160917edf0818a2b232b"}, - {"name": "make", "version": "4.4.1-2", "file": "x86_64/release/make/make-4.4.1-2.tar.xz", "bytes": 598004, "sha512": "9a89a0f4ceadf5c2d0390029d16274fbed0190d2410ad6beb76e39b7153f38d0d1169ad0abf57c96929e6ab0523a0a76c345868e9ae46f9cd3d708d23f6fa3e6"}, - {"name": "man-db", "version": "2.13.1-1", "file": "x86_64/release/man-db/man-db-2.13.1-1-x86_64.tar.zst", "bytes": 1301518, "sha512": "a1e8a0d6d5a75465e32be83c13e685a73f084fa41abc5500d9437837a2c9de2f897827d3516c1076fa6cdd07a3d1aaaa4751f3b393fcfe64c370ff8f6b8b7f84"}, - {"name": "mintty", "version": "3.8.3-1", "file": "x86_64/release/mintty/mintty-3.8.3-1-x86_64.tar.xz", "bytes": 1190356, "sha512": "79068708c81a7bf6abba3ad1cd0550a2c3eb6f6eea21adade8b0d2b77339cd2519716f528159da9f0972f93bb624867e394d782c3e3b0b7e841a8db985395b92"}, - {"name": "ncurses", "version": "6.5+20240427-1", "file": "x86_64/release/ncurses/ncurses-6.5+20240427-1.tar.xz", "bytes": 111396, "sha512": "e15664bdab3f4d82bac6481deaa66476adbe34404937079983b5165930fa18cec3aa0345b93fbb2c390f8304ef20f041cd47d268552b92d01a51adb6abde0fc5"}, - {"name": "openssl", "version": "3.5.7-1", "file": "x86_64/release/openssl/openssl-3.5.7-1-x86_64.tar.zst", "bytes": 1392875, "sha512": "c50821b61eec47d58d1624a4a3d5a4013c80a8b48cdc803d81a656e6859079d321b34fa0ff97db4c093735a76b71a68c8a7f12184b2c4f0677014e910d1ba9d3"}, - {"name": "p11-kit", "version": "0.26.5-1", "file": "x86_64/release/p11-kit/p11-kit-0.26.5-1-x86_64.tar.xz", "bytes": 332724, "sha512": "1f057de789a5553f04649c80e6f78385135b57de7ba078e9dd51f2db60afee37717bb6de9dcf0a330cf72fce1359e08c0186988632b5f858992ebf95739bb840"}, - {"name": "p11-kit-trust", "version": "0.26.5-1", "file": "x86_64/release/p11-kit/p11-kit-trust/p11-kit-trust-0.26.5-1-x86_64.tar.xz", "bytes": 110096, "sha512": "2f98ae11e42f69fa4626638f7cefe2ba2fed808ae618093c1e6c568f8a8be79e6690b40e39e20df02a8d363c371cca8b8320fea7b288e8561cd299f15cc5b796"}, - {"name": "perl", "version": "5.44.0-1", "file": "x86_64/release/perl/perl-5.44.0-1-x86_64.tar.zst", "bytes": 5129424, "sha512": "42f80064ff94ea778319a24e011d4a7236944c79d9db22e0ed64a7ca7d9b65bc2df5998130eb64c50aa95c173937776cc42665174c5717e84fe6dca523368f27"}, - {"name": "perl-Algorithm-Diff", "version": "1.2010-5", "file": "noarch/release/perl-Algorithm-Diff/perl-Algorithm-Diff-1.2010-5-noarch.tar.zst", "bytes": 31580, "sha512": "d840b605043448ceab8ded77313e12653c81fd7db08062a99010fb19b334429c15628b1a0a805f88110e7aae4dcd3f667b515c18870ba873169533663f4374de"}, - {"name": "perl-Archive-Zip", "version": "1.680.0-1", "file": "noarch/release/perl-Archive-Zip/perl-Archive-Zip-1.680.0-1-noarch.tar.zst", "bytes": 85917, "sha512": "de23da6dac8aa8c8218c141c845723d092f6eaf2f1e67ced96d7b0385206c2e335b150bb7066bd0c7d257125ad1b3fc7691686dc535c56429b4a0f4535b6c73a"}, - {"name": "perl-Class-Inspector", "version": "1.360.0-1", "file": "noarch/release/perl-Class-Inspector/perl-Class-Inspector-1.360.0-1-noarch.tar.zst", "bytes": 21261, "sha512": "299489c9d0bc86fe8ba625c0ec0530f0e6ecacab3f67b2826760413f6bc58252c6c11f45583063cfcf0944f9127ed2bece9168fd76220e735841f374a57943f5"}, - {"name": "perl-Devel-Cycle", "version": "1.120.0-1", "file": "noarch/release/perl-Devel-Cycle/perl-Devel-Cycle-1.120.0-1-noarch.tar.zst", "bytes": 8884, "sha512": "308211af5b57106629b168be340fd682e23670fd97cc7c7f80c3bac48223984c1a226148c99cf5d904b09e352f1008f13bd4645897223a162a22af819aa7af11"}, - {"name": "perl-File-ShareDir", "version": "1.118.0-1", "file": "noarch/release/perl-File-ShareDir/perl-File-ShareDir-1.118.0-1-noarch.tar.zst", "bytes": 19857, "sha512": "7cb0f5fe4c327e9f870fc9c303f5e7e1483d2d2d012dbb5487f4b08f350170b7eb0a345766bd0a809bb4b8fa138788112eed2528b92718e817a5f21a9b82774d"}, - {"name": "perl-Text-Diff", "version": "1.450.0-1", "file": "noarch/release/perl-Text-Diff/perl-Text-Diff-1.450.0-1-noarch.tar.zst", "bytes": 30982, "sha512": "c19c80564d50d1d8efd44b156013aa5620b79205fd291897b938735c49214c84867a1337dfe9e7857f97e6f924ec919f5a0197df2d3bfeae78e0ec9dc8b9a6ac"}, - {"name": "perl-Win32-API", "version": "0.840.0-1", "file": "x86_64/release/perl-Win32-API/perl-Win32-API-0.840.0-1-x86_64.tar.zst", "bytes": 84514, "sha512": "758b1881d55942e91365780bede1dca63838995ad6574f9a242c15f613e7e3211a029e9bd3a3bd24d834ca6838e7a85c2812411783423ba23ccf808d094b6890"}, - {"name": "perl_autorebase", "version": "5.44.0-1", "file": "x86_64/release/perl/perl_autorebase/perl_autorebase-5.44.0-1-x86_64.tar.zst", "bytes": 175, "sha512": "55cd94604cfa3e2491df45e5a3715f32b2dee8298a656ca2da8de2eba4096329c595228a8c950760e9641b2c6097309571350c0ffe1c8d13759eb76ec841a4f8"}, - {"name": "perl_base", "version": "5.44.0-1", "file": "x86_64/release/perl/perl_base/perl_base-5.44.0-1-x86_64.tar.zst", "bytes": 3772189, "sha512": "3039e7a60c950cd682d8372f948ec83f7ebea27e9b425ab7406ed2eff0bebb80f7622423cf82b9ab07e34deb183bdf1b56fe129c8306bd2cfb04e7cd96beb992"}, - {"name": "rebase", "version": "4.6.6-1", "file": "x86_64/release/rebase/rebase-4.6.6-1.tar.xz", "bytes": 248832, "sha512": "9f3751c4687b09f3c286cf5c4522a0d976fce2d79ab471ab37560b15f14af84f7d13162b6102c02d0d60784448ff0586e76e9291675af4fa0c9320a3713633da"}, - {"name": "run", "version": "1.3.4-2", "file": "x86_64/release/run/run-1.3.4-2.tar.xz", "bytes": 34492, "sha512": "7e3156bbddc5f934fde3530879aa5186c9fdccb757ba848fc958e79e96534b336975f2882e413d5c18174628033a422157d25c48f8b5e90f0f1555ff2fa6343f"}, - {"name": "sed", "version": "4.10-1", "file": "x86_64/release/sed/sed-4.10-1-x86_64.tar.xz", "bytes": 359252, "sha512": "da5475344a1693f90fb560773ccca48eaf13af0e6bbcada9dcea658862bf7f46043b2d7365de0e2e235fb9a874fe784ad83bc29eb2fdbf3207cd8ad5e127b8b9"}, - {"name": "tar", "version": "1.35-2", "file": "x86_64/release/tar/tar-1.35-2.tar.zst", "bytes": 997616, "sha512": "007c7df12bc27ca14862a925680e2b2ff616a5149262b153889e6f580f3db492f98da49b5f34a8c4234194ee25021b67e9a84c987c96c5d6baa7ee0b3ea02425"}, - {"name": "terminfo", "version": "6.5+20240427-1", "file": "x86_64/release/ncurses/terminfo/terminfo-6.5+20240427-1.tar.xz", "bytes": 94760, "sha512": "128fb04f188bbf2af3060416193c9879a9cbbf7e5486febf851f35c3d9d00b9d61a0e2bf4be575d2308fd665a224ce5674485dcfd071125c3a8d199a4b88a042"}, - {"name": "texinfo", "version": "7.3-1", "file": "x86_64/release/texinfo/texinfo-7.3-1-x86_64.tar.zst", "bytes": 1853455, "sha512": "a7a0da042d05bbf2978857fcad1887552db9d77bf745fb8a17e156a2616500cf711adce107610f008ddff5556d02823f148d2bf146bd7eaa8a9466f9300cf2e6"}, - {"name": "tzcode", "version": "2026c-1", "file": "x86_64/release/tzcode/tzcode-2026c-1-x86_64.tar.xz", "bytes": 185512, "sha512": "85ab0f5d8d7c02e38dbd945c99ee6841774d84c486f857cd8484605068441b2028eea1f42a7e36c8fd6801c454f8f786a16f9caeb422afb30e5fcf324434878b"}, - {"name": "tzdata", "version": "2026c-1", "file": "noarch/release/tzdata/tzdata-2026c-1-noarch.tar.xz", "bytes": 184092, "sha512": "567adb6da01050a84b3785a1cb518e62a9c838cfe55e8ab33610c6ee64355677486329de5781361d08f03cd355acd64f94c64ec2a2686d48538813cc405b638c"}, - {"name": "util-linux", "version": "2.40.2-2", "file": "x86_64/release/util-linux/util-linux-2.40.2-2.tar.xz", "bytes": 2053568, "sha512": "4f3473472e32bff586401ec31f1423237c9cb112ae1140cdd8b2797040c5c182632f49f5354eaaa409d2dacba7767d5baa8b8926d7638e2725ad80065b46c10b"}, - {"name": "vim-minimal", "version": "9.1.1825-1", "file": "x86_64/release/vim/vim-minimal/vim-minimal-9.1.1825-1-x86_64.tar.xz", "bytes": 794064, "sha512": "6a252210e2ef08a7038d6e5bc8e5312e0c25d8328ab0aefd7f292eb79b7a32dd699f15f3f293cfbb83687e87cb3f68a335e969b117f55e6ff99b34ebdfbc8119"}, - {"name": "which", "version": "2.23-1", "file": "x86_64/release/which/which-2.23-1-x86_64.tar.xz", "bytes": 31108, "sha512": "98dffe802e1137d7b54359314797fd10080e6c261f37668e32e46aa7b1587b4148a1647b4f4a00cd0d23a9e90f153d5c2081d0ffa4ccea657b73aaa31b538d6e"}, - {"name": "xz", "version": "5.8.3-1", "file": "x86_64/release/xz/xz-5.8.3-1-x86_64.tar.zst", "bytes": 767298, "sha512": "8918389508ade8237226170b6dd02104938ec53b2bb15b310f5005dd64f954dfd67a5391757ba8602afe2a423f901894204771d6ae335402095c074d098daa76"}, - {"name": "zlib0", "version": "1.3.2-1", "file": "x86_64/release/zlib/zlib0/zlib0-1.3.2-1-x86_64.tar.zst", "bytes": 46254, "sha512": "d79ba6098cadf6bf2f32f35d9cd54729293c64b3c9daabb9d080f52861a19db71544d5710fdbd61ff45e7c2ae4eecb3f2e3b8a1e3bc05695b8cfe01c7639c53a"}, - {"name": "zstd", "version": "1.5.7-1", "file": "x86_64/release/zstd/zstd-1.5.7-1.tar.zst", "bytes": 394600, "sha512": "5de9a2fdee75345a35592444d467a1b70504f09f3b2ee5aaf8af8a9d9fda1a4e77d37c5c4c4fee9b96995ef78f9708e6c02adea7a70d9f80f1238e507b2bc0fc"} - ] -} diff --git a/.github/scripts/voice_windows_tools.py b/.github/scripts/voice_windows_tools.py deleted file mode 100644 index 7dc26ee3fc..0000000000 --- a/.github/scripts/voice_windows_tools.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Expose verified Windows build-tool installations as local Bazel inputs. - -This declares the installed support trees; the caller authenticates their -inputs and verifies the installed package inventory first. -""" - -import argparse -import itertools -import json -from pathlib import Path -import stat - - -def export_repository(root: Path, target: str, pkg_config: Path): - if target not in ("x86_64-pc-windows-msvc", "aarch64-pc-windows-msvc"): - raise ValueError("unsupported Windows target") - root = root.resolve(strict=True) - pkg_config = pkg_config.resolve(strict=True) - names = { - "shell": "cygwin/bin/bash.exe", - "make": "cygwin/bin/make.exe", - "cygpath": "cygwin/bin/cygpath.exe", - "automake": "cygwin/bin/automake-1.18", - "pkg_config": pkg_config.relative_to(root).as_posix(), - } - if not names["pkg_config"].startswith("pkgconf-image/"): - raise ValueError("pkg-config must belong to the extracted image") - outputs = ("BUILD.bazel", "MODULE.bazel", "voice-tools.json") - if any((root / name).exists() for name in outputs): - raise ValueError("Bazel tool repository outputs must be fresh") - # A nested package boundary would silently remove files from Bazel's glob. - # Reparse points could escape the installation or hide support directories. - for directory in ("cygwin", "pkgconf-image"): - tree = root / directory - if not tree.is_dir(): - raise ValueError(f"missing tool tree: {directory}") - for path in itertools.chain((tree,), tree.rglob("*")): - info = path.lstat() - if ( - stat.S_ISLNK(info.st_mode) - or getattr(info, "st_file_attributes", 0) - & stat.FILE_ATTRIBUTE_REPARSE_POINT - or not (stat.S_ISDIR(info.st_mode) or stat.S_ISREG(info.st_mode)) - or path.name.casefold() in ("build", "build.bazel") - ): - raise ValueError(f"unsupported tool-tree entry: {path}") - if any(not (root / name).is_file() for name in names.values()): - raise ValueError("required Windows build tool missing") - definitions = [ - 'package(default_visibility = ["//visibility:public"])', - 'filegroup(name = "cygwin", srcs = glob(["cygwin/**"], allow_empty = False))', - 'filegroup(name = "pkgconf", srcs = glob(["pkgconf-image/**"], allow_empty = False))', - 'filegroup(name = "tools", srcs = [":cygwin", ":pkgconf", "voice-tools.json"])', - ] - definitions.extend( - f"filegroup(name = {json.dumps(name)}, srcs = [{json.dumps(path)}])" - for name, path in names.items() - ) - metadata = { - "schemaVersion": 1, - "target": target, - "cygwinArchitecture": "x86_64", - "tools": names, - } - for name, contents in ( - ("BUILD.bazel", "\n".join(definitions) + "\n"), - ("MODULE.bazel", 'module(name = "voice_windows_tools")\n'), - ("voice-tools.json", json.dumps(metadata, indent=2) + "\n"), - ): - with (root / name).open("x", encoding="utf-8") as output: - output.write(contents) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("--root", type=Path, required=True) - parser.add_argument("--target", required=True) - parser.add_argument("--pkg-config", type=Path, required=True) - args = parser.parse_args() - export_repository(args.root, args.target, args.pkg_config) diff --git a/.github/workflows/rust-release-windows.yml b/.github/workflows/rust-release-windows.yml index ceb6075287..234abf9284 100644 --- a/.github/workflows/rust-release-windows.yml +++ b/.github/workflows/rust-release-windows.yml @@ -146,131 +146,6 @@ jobs: path: | ${{ env.CARGO_TARGET_DIR }}/${{ matrix.target }}/release/staged-${{ matrix.bundle }}/* - build-windows-voice: - name: Build Windows voice - ${{ matrix.target }} - runs-on: ${{ matrix.runs_on }} - timeout-minutes: 120 - permissions: - contents: read - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-pc-windows-msvc - arch: x86_64 - python_arch: x64 - runs_on: - group: ${{ github.event.repository.name }}-runners - labels: ${{ github.event.repository.name }}-windows-x64 - - target: aarch64-pc-windows-msvc - arch: aarch64 - python_arch: arm64 - runs_on: - group: ${{ github.event.repository.name }}-runners - labels: ${{ github.event.repository.name }}-windows-arm64 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "3.12" - architecture: ${{ matrix.python_arch }} - - name: Prepare Bazel CI - uses: ./.github/actions/prepare-bazel-ci - with: - target: ${{ matrix.target }} - cache-scope: release-voice-windows - - uses: ./.github/actions/setup-msvc-env - with: - target: ${{ matrix.target }} - - name: Refresh Bazel PATH for the selected MSVC target - shell: pwsh - run: ./.github/scripts/compute-bazel-windows-path.ps1 - - name: Download pinned Windows build inputs - shell: pwsh - env: - GH_TOKEN: ${{ github.token }} - run: | - $manifest = Get-Content -Raw .github/scripts/voice-cygwin-snapshot.json | ConvertFrom-Json - $pin = $manifest.archive - $source = $manifest.sourceArchive - $directory = Join-Path $env:RUNNER_TEMP "voice-cygwin-snapshot" - New-Item -ItemType Directory -Path $directory | Out-Null - gh release download $pin.tag --repo "${{ github.repository }}" --pattern $pin.name --pattern $source.name --dir $directory - if ($LASTEXITCODE -ne 0) { throw "Cannot obtain the public Cygwin inputs and source" } - $sourceFile = Join-Path $directory $source.name - if ((Get-Item $sourceFile).Length -ne $source.bytes -or - (Get-FileHash $sourceFile -Algorithm SHA256).Hash.ToLowerInvariant() -ne $source.sha256) { - throw "Public Cygwin source archive mismatch" - } - "VOICE_CYGWIN_ARCHIVE=$(Join-Path $directory $pin.name)" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append - - name: Verify and install pinned public build tools - shell: pwsh - run: | - & ./.github/scripts/setup-voice-windows.ps1 -Target "${{ matrix.target }}" -SnapshotArchive $env:VOICE_CYGWIN_ARCHIVE - if (-not $env:SystemRoot) { throw "Windows SystemRoot is required for native audio actions" } - "VOICE_WINDOWS_SYSTEM_ROOT=$env:SystemRoot" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append - $hostArch = $env:PROCESSOR_ARCHITEW6432 - if (-not $hostArch) { $hostArch = $env:PROCESSOR_ARCHITECTURE } - if (-not $hostArch) { throw "Windows host architecture is required" } - "VOICE_WINDOWS_HOST_ARCH=$hostArch" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append - - name: Build same-commit native runtime and helper - shell: bash - env: - ARCH: ${{ matrix.arch }} - BUILDBUDDY_API_KEY: "" - run: | - (cd codex-rs && cargo update --workspace) - ./.github/scripts/run-bazel-ci.sh \ - --remote-download-toplevel \ - --print-failed-action-summary \ - --windows-msvc-host-platform \ - -- \ - test -c opt \ - --platforms=//:local_windows_msvc \ - --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows,@local_config_cc//:cc-toolchain-arm64_windows,//third_party/voice:windows_pkg_config_toolchain,//third_party/voice:windows_cmake_toolchain \ - --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=0 \ - --repo_env=BAZEL_MSVC_RUNTIME_VISUAL_STUDIO_EULA=1 \ - --inject_repository="voice_windows_tools=$VOICE_WINDOWS_BAZEL_REPOSITORY" \ - --//third_party/voice:windows_installed_tools=@voice_windows_tools//:tools \ - --action_env="SystemRoot=$VOICE_WINDOWS_SYSTEM_ROOT" \ - --host_action_env="SystemRoot=$VOICE_WINDOWS_SYSTEM_ROOT" \ - --action_env="PROCESSOR_ARCHITECTURE=$VOICE_WINDOWS_HOST_ARCH" \ - --host_action_env="PROCESSOR_ARCHITECTURE=$VOICE_WINDOWS_HOST_ARCH" \ - --output_groups=default,receipt,sdk \ - --workspace_status_command=./scripts/workspace-status.cmd \ - --build_metadata=COMMIT_SHA="$GITHUB_SHA" \ - -- \ - "//third_party/voice:native_runtime_windows_$ARCH" \ - @rules_rust//cargo/private/cargo_build_script_runner:test \ - //codex-rs/voice-host:codex-voice-host - - name: Stage verified voice build output - shell: bash - env: - TARGET: ${{ matrix.target }} - ARCH: ${{ matrix.arch }} - run: | - set -euo pipefail - runtime="bazel-bin/third_party/voice/native_runtime_windows_${ARCH}" - PYTHONPATH=third_party/voice python - "$runtime" "$TARGET" <<'PY' - from pathlib import Path - import sys - from package_runtime import runtime_files - runtime_files(Path(sys.argv[1]).resolve(strict=True), sys.argv[2]) - PY - output="voice-unsigned/${TARGET}" - mkdir -p "$output" - cp -R "$runtime" "$output/runtime" - cp bazel-bin/codex-rs/voice-host/codex-voice-host.exe "$output/codex-voice-host.exe" - chmod -R u+w "$output" - tar -C "$output" -czf "voice-unsigned-${TARGET}.tar.gz" runtime codex-voice-host.exe - - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 - with: - name: voice-${{ matrix.target }}-unsigned - path: voice-unsigned-${{ matrix.target }}.tar.gz - if-no-files-found: error - build-windows-symbols: needs: - build-windows-binaries @@ -318,13 +193,12 @@ jobs: build-windows: needs: - build-windows-binaries - - build-windows-voice name: Build - ${{ matrix.runner }} - ${{ matrix.target }} runs-on: ${{ matrix.runs_on }} environment: name: azure-artifact-signing deployment: false - timeout-minutes: 120 + timeout-minutes: 90 permissions: contents: read id-token: write @@ -391,76 +265,6 @@ jobs: account-name: ${{ secrets.AZURE_ARTIFACT_SIGNING_ACCOUNT_NAME }} certificate-profile-name: ${{ secrets.AZURE_ARTIFACT_SIGNING_CERTIFICATE_PROFILE_NAME }} - - name: Download matching native voice build - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: voice-${{ matrix.target }}-unsigned - path: ${{ runner.temp }}/unsigned-voice - - - name: Stage voice files for signing - id: voice_files - shell: bash - run: | - set -euo pipefail - target="${{ matrix.target }}" - unsigned="${RUNNER_TEMP}/unsigned-voice/extracted" - signed="${GITHUB_WORKSPACE}/signed-voice/${target}" - mkdir -p "$unsigned" "$signed" - tar -xzf "${RUNNER_TEMP}/unsigned-voice/voice-unsigned-${target}.tar.gz" -C "$unsigned" - python "${GITHUB_WORKSPACE}/third_party/voice/release_runtime.py" stage \ - --source "$unsigned/runtime" --target "$target" --output "$signed/runtime" - cp "$unsigned/codex-voice-host.exe" "$signed/codex-voice-host.exe" - chmod -R u+w "$signed" - { - echo 'files<> "$GITHUB_OUTPUT" - - - name: Sign Windows voice helper and native DLLs - uses: azure/trusted-signing-action@1d365fec12862c4aa68fcac418143d73f0cea293 # v0.5.11 - with: - endpoint: ${{ secrets.AZURE_ARTIFACT_SIGNING_ENDPOINT }} - trusted-signing-account-name: ${{ secrets.AZURE_ARTIFACT_SIGNING_ACCOUNT_NAME }} - certificate-profile-name: ${{ secrets.AZURE_ARTIFACT_SIGNING_CERTIFICATE_PROFILE_NAME }} - exclude-environment-credential: true - exclude-workload-identity-credential: true - exclude-managed-identity-credential: true - exclude-shared-token-cache-credential: true - exclude-visual-studio-credential: true - exclude-visual-studio-code-credential: true - exclude-azure-cli-credential: false - exclude-azure-powershell-credential: true - exclude-azure-developer-cli-credential: true - exclude-interactive-browser-credential: true - cache-dependencies: false - files: ${{ steps.voice_files.outputs.files }} - - - uses: ./.github/actions/setup-msvc-env - with: - target: ${{ matrix.target }} - - - name: Seal and verify signed voice output - shell: pwsh - run: | - $target = "${{ matrix.target }}" - $signed = Join-Path $env:GITHUB_WORKSPACE "signed-voice/$target" - python (Join-Path $env:GITHUB_WORKSPACE 'third_party/voice/windows_crt.py') --root (Join-Path $signed 'runtime') --target $target --helper (Join-Path $signed 'codex-voice-host.exe') - if ($LASTEXITCODE -ne 0) { throw 'Cannot stage verified Microsoft CRT' } - $files = @(Join-Path $signed "codex-voice-host.exe") + @( - Get-ChildItem (Join-Path $signed "runtime/bin") -Filter *.dll -File | - ForEach-Object FullName - ) - if ($files.Count -lt 8) { throw "Voice DLL closure is incomplete" } - foreach ($file in $files) { - $signature = Get-AuthenticodeSignature $file - if ($signature.Status -ne 'Valid') { throw "Unsigned voice file: $file ($($signature.Status))" } - } - python (Join-Path $env:GITHUB_WORKSPACE 'third_party/voice/release_runtime.py') seal --target $target --output (Join-Path $signed 'runtime') - if ($LASTEXITCODE -ne 0) { throw 'Cannot seal signed voice runtime' } - "VOICE_RELEASE_DIR=$signed" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append - - name: Stage artifacts shell: bash run: | @@ -478,34 +282,22 @@ jobs: set -euo pipefail target="${{ matrix.target }}" archive_script="${GITHUB_WORKSPACE}/.github/scripts/build-codex-package-archive.sh" - voice_args=(--voice-release-dir "$VOICE_RELEASE_DIR") - voice_args+=(--release-version "${GITHUB_REF_NAME#rust-v}") - bash "$archive_script" \ - --target "$target" --bundle primary \ - --entrypoint-dir "$CARGO_TARGET_DIR/$target/release" \ - --archive-dir "dist/$target" "${voice_args[@]}" - bash "$archive_script" \ - --target "$target" --bundle app-server \ - --entrypoint-dir "$CARGO_TARGET_DIR/$target/release" \ - --archive-dir "dist/$target" + temp_root="${RUNNER_TEMP}/codex-package-archives" - - name: Verify packaged Windows voice closure - shell: pwsh - run: | - $target = "${{ matrix.target }}" - $package = Join-Path $env:RUNNER_TEMP "verify-voice-archive-$target" - New-Item -ItemType Directory -Path $package | Out-Null - tar -xzf "dist/$target/codex-package-$target.tar.gz" -C $package - if ($LASTEXITCODE -ne 0) { throw "Cannot extract the final Windows package" } - $voice = Join-Path $package 'codex-resources/voice' - $helper = Join-Path $voice 'bin/codex-voice-host.exe' - if (-not (Test-Path $helper) -or -not (Test-Path (Join-Path $voice 'bin/gstreamer-1.0-0.dll'))) { - throw 'Signed Windows voice files are missing from the canonical package' - } - $signature = Get-AuthenticodeSignature $helper - if ($signature.Status -ne 'Valid') { throw "Packaged helper signature: $($signature.Status)" } - python -c 'import sys; from pathlib import Path; sys.path.insert(0, sys.argv[3]); from package_runtime import runtime_files; runtime_files(Path(sys.argv[1]), sys.argv[2], public_release=True)' $voice $target (Join-Path $env:GITHUB_WORKSPACE 'third_party/voice') - if ($LASTEXITCODE -ne 0) { throw 'Packaged runtime receipt verification failed' } + # The package helper rewrites cached DotSlash executables. Keep the + # concurrent processes in separate temp roots because Windows cannot + # replace an executable while another process is using it. + mkdir -p "$temp_root/primary" "$temp_root/app-server" + printf '%s\0' primary app-server | + xargs -0 -P0 -I{} env \ + TMPDIR="$temp_root/{}" \ + TMP="$temp_root/{}" \ + TEMP="$temp_root/{}" \ + bash "$archive_script" \ + --target "$target" \ + --bundle "{}" \ + --entrypoint-dir "$CARGO_TARGET_DIR/$target/release" \ + --archive-dir "dist/$target" - name: Build Python runtime wheel shell: bash @@ -528,25 +320,12 @@ jobs: python -m venv "${RUNNER_TEMP}/python-runtime-build-venv" "${RUNNER_TEMP}/python-runtime-build-venv/Scripts/python.exe" -m pip install build - # The wheel's Windows support floor predates the native voice - # runtime's verified device/VC++ prerequisites. Keep it voice-free. - wheel_archives="${RUNNER_TEMP}/voice-free-wheel/${{ matrix.target }}" - bash "${GITHUB_WORKSPACE}/.github/scripts/build-codex-package-archive.sh" \ - --target "${{ matrix.target }}" --bundle primary \ - --entrypoint-dir "$CARGO_TARGET_DIR/${{ matrix.target }}/release" \ - --archive-dir "$wheel_archives" - python - "$wheel_archives/codex-package-${{ matrix.target }}.tar.gz" <<'PY' - import sys - import tarfile - with tarfile.open(sys.argv[1]) as archive: - assert not any("codex-resources/voice/" in member.name for member in archive) - PY stage_dir="${RUNNER_TEMP}/openai-codex-cli-bin-${{ matrix.target }}" wheel_dir="${GITHUB_WORKSPACE}/python-runtime-dist/${{ matrix.target }}" python "${GITHUB_WORKSPACE}/sdk/python/scripts/update_sdk_artifacts.py" \ stage-runtime \ "$stage_dir" \ - "$wheel_archives/codex-package-${{ matrix.target }}.tar.gz" \ + "dist/${{ matrix.target }}/codex-package-${{ matrix.target }}.tar.gz" \ --codex-version "${GITHUB_REF_NAME}" \ --platform-tag "$platform_tag" "${RUNNER_TEMP}/python-runtime-build-venv/Scripts/python.exe" -m build --wheel --outdir "$wheel_dir" "$stage_dir" diff --git a/MODULE.bazel b/MODULE.bazel index 7854947538..e014c6d32c 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -165,7 +165,6 @@ single_version_override( patches = [ "//patches:rules_foreign_cc_make_cppflags.patch", "//patches:rules_foreign_cc_make_xcompile.patch", - "//patches:rules_foreign_cc_make_msvc_stdint.patch", ], version = "0.15.1", ) @@ -209,7 +208,6 @@ rules_rust.patch( "//patches:rules_rust_windows_process_wrapper_skip_temp_outputs.patch", # Group build-script argument files to avoid Windows command-line limits. "//patches:rules_rust_group_build_script_arg_files.patch", - "//patches:rules_rust_windows_execroot_separators.patch", ], strip = 1, ) diff --git a/patches/BUILD.bazel b/patches/BUILD.bazel index 7b58251d8a..2afcf05d1e 100644 --- a/patches/BUILD.bazel +++ b/patches/BUILD.bazel @@ -6,13 +6,11 @@ exports_files([ "llvm_windows_mingw_compat.patch", "rules_rust_build_script_tools_transition.patch", "rules_rust_group_build_script_arg_files.patch", - "rules_rust_windows_execroot_separators.patch", "rules_rust_windows_msvc_direct_link_args.patch", "rules_rust_windows_process_wrapper_skip_temp_outputs.patch", "rules_cc_rusty_v8_custom_libcxx.patch", "rules_foreign_cc_make_cppflags.patch", "rules_foreign_cc_make_xcompile.patch", - "rules_foreign_cc_make_msvc_stdint.patch", "rules_rs_build_script_deps_annotation.patch", "rules_rs_windows_msvc_linker.patch", "rules_rs_zlib_snapshot_urls.patch", diff --git a/patches/ring_windows_msvc_include_dirs.patch b/patches/ring_windows_msvc_include_dirs.patch index 7bb49cbc2c..06f944ad34 100644 --- a/patches/ring_windows_msvc_include_dirs.patch +++ b/patches/ring_windows_msvc_include_dirs.patch @@ -1,7 +1,8 @@ diff --git a/build.rs b/build.rs +index 9843ad8aa..573075489 100644 --- a/build.rs +++ b/build.rs -@@ -346,7 +346,27 @@ +@@ -346,7 +346,28 @@ fn ring_build_rs_main(c_root_dir: &Path, core_name_and_version: &str) { // we want to optimize for minimizing the build tools required: No Perl, // no nasm, etc. let generated_dir = if !is_git { @@ -30,22 +31,7 @@ diff --git a/build.rs b/build.rs } else { generate_sources_and_preassemble( &out_dir, -@@ -561,7 +581,13 @@ - let compiler = c.get_compiler(); - // FIXME: On Windows AArch64 we currently must use Clang to compile C code - let compiler = if target.os == WINDOWS && target.arch == AARCH64 && !compiler.is_like_clang() { -- let _ = c.compiler("clang"); -+ // Keep inherited MSVC flags compatible with the selected Clang driver. -+ let clang = if compiler.is_like_msvc() { -+ "clang-cl" -+ } else { -+ "clang" -+ }; -+ let _ = c.compiler(clang); - c.get_compiler() - } else { - compiler -@@ -569,6 +595,15 @@ +@@ -569,6 +591,15 @@ fn configure_cc(c: &mut cc::Build, target: &Target, c_root_dir: &Path, include_d let _ = c.include(c_root_dir.join("include")); let _ = c.include(include_dir); diff --git a/patches/rules_foreign_cc_make_msvc_stdint.patch b/patches/rules_foreign_cc_make_msvc_stdint.patch deleted file mode 100644 index f3af72841a..0000000000 --- a/patches/rules_foreign_cc_make_msvc_stdint.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/foreign_cc/built_tools/make_build.bzl b/foreign_cc/built_tools/make_build.bzl ---- a/foreign_cc/built_tools/make_build.bzl -+++ b/foreign_cc/built_tools/make_build.bzl -@@ -35,6 +35,9 @@ - build_str += " gcc" - dist_dir = "GccRel" - else: -+ # Modern MSVC provides stdint.h, including the intmax_t types that -+ # Make's legacy Windows config otherwise replaces with macros. -+ build_str = 'export CL="$${CL:-}$$ /DHAVE_STDINT_H=1"\n' + build_str - dist_dir = "WinRel" - - script = [ diff --git a/patches/rules_rs_windows_msvc_linker.patch b/patches/rules_rs_windows_msvc_linker.patch index 5056ade96b..66feb78569 100644 --- a/patches/rules_rs_windows_msvc_linker.patch +++ b/patches/rules_rs_windows_msvc_linker.patch @@ -1,14 +1,13 @@ -# What: use Rust's bundled direct linker for Windows x86_64 and ARM64 MSVC toolchains. -# Scope: standard and bootstrap rules_rs Rust toolchains targeting x86_64 and ARM64 MSVC. +# What: use Rust's bundled direct linker for Windows x86_64 MSVC toolchains. +# Scope: standard and bootstrap rules_rs Rust toolchains targeting x86_64 MSVC. diff --git a/rs/toolchains/declare_rustc_toolchains.bzl b/rs/toolchains/declare_rustc_toolchains.bzl --- a/rs/toolchains/declare_rustc_toolchains.bzl +++ b/rs/toolchains/declare_rustc_toolchains.bzl -@@ -88,6 +88,8 @@ def declare_rustc_toolchains( +@@ -88,6 +88,7 @@ def declare_rustc_toolchains( llvm_cov = "@llvm//tools:llvm-cov", llvm_profdata = "@llvm//tools:llvm-profdata", linker = select({ -+ "@rules_rs//rs/platforms/config:aarch64-pc-windows-msvc": "{}rust-lld".format(rustc_repo_label), + "@rules_rs//rs/platforms/config:x86_64-pc-windows-msvc": "{}rust-lld".format(rustc_repo_label), "@platforms//cpu:wasm32": "{}rust-lld".format(rustc_repo_label), "@platforms//cpu:wasm64": "{}rust-lld".format(rustc_repo_label), diff --git a/patches/rules_rust_windows_execroot_separators.patch b/patches/rules_rust_windows_execroot_separators.patch deleted file mode 100644 index 187b37f48c..0000000000 --- a/patches/rules_rust_windows_execroot_separators.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- a/cargo/private/cargo_build_script_runner/lib.rs -+++ b/cargo/private/cargo_build_script_runner/lib.rs -@@ -337,9 +337,18 @@ - return "${pwd}".to_owned(); - } - -- value -+ let redacted = value - .replace(&format!("{exec_root}/"), "${pwd}/") -- .replace(&format!("{exec_root}\\"), "${pwd}\\") -+ .replace(&format!("{exec_root}\\"), "${pwd}\\"); -+ #[cfg(windows)] -+ let redacted = { -+ // pkg-config can emit forward slashes for the same Windows root. -+ let root = exec_root.replace('\\', "/"); -+ redacted -+ .replace(&format!("{root}/"), "${pwd}/") -+ .replace(&format!("{root}\\"), "${pwd}\\") -+ }; -+ redacted - } - - /// Redact for env vars: uses the generic `${out_dir}` token, resolved -@@ -630,6 +639,28 @@ - link_search_paths: - "-L${pwd}/${bazel-out/cfg/bin/pkg/_bs.out_dir}\n-L${pwd}/other/path".to_owned(), - } -+ ); -+ } -+ -+ #[cfg(windows)] -+ #[test] -+ fn windows_include_metadata_redacts_both_root_spellings() { -+ let root = r"D:\o\execroot\_main"; -+ let forward = root.replace('\\', "/"); -+ let outputs = vec![BuildScriptOutput::DepEnv(format!( -+ "INCLUDE={forward}/include;{root}\\lib;{forward}-other/include" -+ ))]; -+ assert_eq!( -+ BuildScriptOutput::outputs_to_dep_env(&outputs, "glib", root), -+ format!("DEP_GLIB_INCLUDE=${{pwd}}/include;${{pwd}}\\lib;{forward}-other/include") -+ ); -+ let directory = std::env::current_dir().unwrap(); -+ let directory = directory.to_str().unwrap(); -+ let forward = directory.replace('\\', "/"); -+ let outputs = vec![BuildScriptOutput::DepEnv(format!("INCLUDE={forward}/."))]; -+ assert_eq!( -+ BuildScriptOutput::nonhermetic_absolute_paths(&outputs, directory, ""), -+ Vec::::new() - ); - } - diff --git a/patches/rules_rust_windows_msvc_direct_link_args.patch b/patches/rules_rust_windows_msvc_direct_link_args.patch index a8eba2ba6e..aa5fb274e1 100644 --- a/patches/rules_rust_windows_msvc_direct_link_args.patch +++ b/patches/rules_rust_windows_msvc_direct_link_args.patch @@ -4,7 +4,7 @@ use_bpf_linker = toolchain.target_arch in ("bpfeb", "bpfel") and toolchain.linker - if not ld or toolchain.linker_preference == "rust" or use_bpf_linker: + use_windows_msvc_linker = ( -+ toolchain.target_arch in ("x86_64", "aarch64") and ++ toolchain.target_arch == "x86_64" and + toolchain.target_os == "windows" and + toolchain.target_abi == "msvc" and + toolchain.linker != None and diff --git a/third_party/voice/BUILD.bazel b/third_party/voice/BUILD.bazel index 6de7a373d4..b3c5f0930e 100644 --- a/third_party/voice/BUILD.bazel +++ b/third_party/voice/BUILD.bazel @@ -133,7 +133,7 @@ alias( visibility = ["//visibility:public"], ) -# Windows voice jobs opt into the pkgconf already declared with their build tools. +# Explicitly select the installed pkgconf and pinned CMake in Windows voice CI. native_tool_toolchain( name = "windows_pkg_config_tool", env = {"PKG_CONFIG": "$(execpath :pkg_config)"}, @@ -149,7 +149,6 @@ toolchain( visibility = ["//visibility:public"], ) -# The native Windows build already uses this pinned CMake, including on ARM64. toolchain( name = "windows_cmake_toolchain", exec_compatible_with = ["@platforms//os:windows"], diff --git a/third_party/voice/NOTICE.md b/third_party/voice/NOTICE.md index 3de0cff39b..c5b79744a8 100644 --- a/third_party/voice/NOTICE.md +++ b/third_party/voice/NOTICE.md @@ -15,13 +15,3 @@ projection and package scripts are in the public Codex source tree under platform-specific runtime directories. Replacements must be compatible with the package and, on macOS, have valid code signatures. Build tools listed in `sources.json` are build inputs, not bundled runtime libraries. - -Windows packages also contain an unmodified Microsoft Visual C++ runtime DLL, -copyright Microsoft Corporation, under Microsoft's applicable software license -terms, separately from the open-source audio libraries. `windows-crt.json` -records its version, official download, hashes, and redistribution references. -The Apache and LGPL licenses for other components do not license this DLL. -Microsoft's runtime terms and separate developer redistribution terms apply -to the Microsoft component; the runtime terms alone do not grant redistribution. -Only retail redistributable files are included; Microsoft signatures are retained. -App-local runtime security updates must be delivered with Codex updates. diff --git a/third_party/voice/README.md b/third_party/voice/README.md index 84039f3d56..48ea1fa46c 100644 --- a/third_party/voice/README.md +++ b/third_party/voice/README.md @@ -249,19 +249,7 @@ runtime inspection and SDK export. These targets are MSVC-only. They require native Windows execution of the matching architecture; they are not cross builds. The generic Rust-consumer aliases are connected separately, after these inputs. -Provide the complete installed Cygwin/pkgconf repository explicitly. For a public -Windows build, `.github/scripts/setup-voice-windows.ps1 -Target -x86_64-pc-windows-msvc -SnapshotArchive ` (under `public/` in -codex-internal) verifies the pinned archive and every input size and SHA-512 -digest, then runs the offline installer against its signed metadata. ARM64 uses -`aarch64-pc-windows-msvc` and the same Cygwin x64 tools under emulation. The -installed tool tree stays in the CI temporary directory and is never added to -a Codex package. The upstream mirror's signed metadata changes over time, so -the archived snapshot must be supplied separately. Private CI validates this -public bootstrap against its existing pinned archive; a public release job -requires an approved way to access the same archive. - -The default +Provide the complete installed Cygwin/pkgconf repository explicitly. The default `windows_installed_tools` label setting is empty and fails if a Windows action needs it. This keeps ordinary public dependency queries independent of private provisioning; it does not silently omit tools from a requested Windows build. diff --git a/third_party/voice/assemble_package.py b/third_party/voice/assemble_package.py index a8077d4c5f..af6cc8ca00 100644 --- a/third_party/voice/assemble_package.py +++ b/third_party/voice/assemble_package.py @@ -114,7 +114,6 @@ def assemble( for relative in ( "NOTICE.md", "sources.json", - *(("windows-crt.json",) if suffix else ()), "licenses/LGPL-2.1.txt", "licenses/Opus.txt", "licenses/PCRE2.md", diff --git a/third_party/voice/release_runtime.py b/third_party/voice/release_runtime.py index a02cce3448..6b705ca314 100644 --- a/third_party/voice/release_runtime.py +++ b/third_party/voice/release_runtime.py @@ -15,8 +15,6 @@ def stage(source: Path, destination: Path, target: str) -> None: "x86_64-apple-darwin", "aarch64-unknown-linux-gnu", "x86_64-unknown-linux-gnu", - "aarch64-pc-windows-msvc", - "x86_64-pc-windows-msvc", }: raise ValueError("unsupported public release voice runtime target") source = source.resolve(strict=True) diff --git a/third_party/voice/test_assemble_package.py b/third_party/voice/test_assemble_package.py index a9ac9a3588..7758bd4b12 100644 --- a/third_party/voice/test_assemble_package.py +++ b/third_party/voice/test_assemble_package.py @@ -308,47 +308,6 @@ class AssembleTests(unittest.TestCase): digest(staged / "runtime.json"), ) - def test_windows_release_packages_signed_receipt_and_exe_helper(self): - self.commit = "b" * 40 - for target in ("x86_64-pc-windows-msvc", "aarch64-pc-windows-msvc"): - with self.subTest(target=target): - runtime, _ = self.make_runtime(target, "bin/gst{}.dll") - staged = self.root / f"signed-{target}" - stage(runtime, staged, target) - library = staged / "bin/gio-2.0-0.dll" - library.write_bytes(library.read_bytes() + b"signed") - seal(staged, target) - self.metadata.update( - target=target, - entrypoint="bin/codex.exe", - version="0.154.0-beta.2", - ) - (self.package / "bin/codex.exe").write_bytes(b"unchanged app") - (self.package / "codex-package.json").write_text( - json.dumps(self.metadata) - ) - output = self.root / f"windows-{target}" - assemble( - self.package, - self.helper, - target, - self.commit, - output, - runtime=staged, - release_version="0.154.0-beta.2", - ) - voice = output / "codex-resources/voice" - self.assertEqual( - (voice / "bin/codex-voice-host.exe").read_bytes(), - self.helper.read_bytes(), - ) - self.assertEqual( - (voice / "bin/gio-2.0-0.dll").read_bytes(), library.read_bytes() - ) - self.assertTrue( - runtime_files(voice.resolve(), target, public_release=True) - ) - def test_rejects_invalid_runtime_receipts_before_creating_package(self): runtime, original = self.make_runtime() changes = [ diff --git a/third_party/voice/windows-crt.json b/third_party/voice/windows-crt.json deleted file mode 100644 index c198cb9ea4..0000000000 --- a/third_party/voice/windows-crt.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": "14.50.35719", - "license": "https://visualstudio.microsoft.com/license-terms/vs2026-ga-visualcpp-v14-redist-runtime/", - "developerLicense": "https://visualstudio.microsoft.com/license-terms/vs2026-ga-community/", - "redistribution": "https://learn.microsoft.com/en-us/visualstudio/releases/2026/redistribution", - "x86_64-pc-windows-msvc": { - "url": "https://download.visualstudio.microsoft.com/download/pr/a424e95b-20f6-4af6-844f-9d9a806080a7/a4ab48822362df6e478eb4ed33bf825a07a6faacd6879c1e3d59929cd38b984b/Microsoft.VC.14.50.18.0.CRT.Redist.X64.base.vsix", - "sha256": "a4ab48822362df6e478eb4ed33bf825a07a6faacd6879c1e3d59929cd38b984b", - "member": "Contents/VC/Redist/MSVC/14.50.35710/x64/Microsoft.VC145.CRT/vcruntime140.dll", - "dllSha256": "184146852727a9db4eea06178716bec3cdbb1015c911f6b0f915b184ad7775b2" - }, - "aarch64-pc-windows-msvc": { - "url": "https://download.visualstudio.microsoft.com/download/pr/a424e95b-20f6-4af6-844f-9d9a806080a7/3544badcbcf09e77c6ec32ed866aae59471a39d8a84611d9ae016861ff60a42f/Microsoft.VC.14.50.18.0.CRT.Redist.ARM64.base.vsix", - "sha256": "3544badcbcf09e77c6ec32ed866aae59471a39d8a84611d9ae016861ff60a42f", - "member": "Contents/VC/Redist/MSVC/14.50.35710/arm64/Microsoft.VC145.CRT/vcruntime140.dll", - "dllSha256": "6d987d8cb2a47cff9c29c1fcbb853e7ef273c545f7d822728f7d2d448ca18758" - } -} diff --git a/third_party/voice/windows_crt.py b/third_party/voice/windows_crt.py deleted file mode 100644 index a927c1b19e..0000000000 --- a/third_party/voice/windows_crt.py +++ /dev/null @@ -1,83 +0,0 @@ -"""Add pinned, unmodified Microsoft retail CRT files to Windows release staging.""" - -import argparse -import hashlib -import io -import json -from pathlib import Path -import re -import subprocess -import urllib.request -import zipfile - -from windows_runtime import EXTERNAL_IMPORTS, inspect - - -def stage(root: Path, target: str, helper: Path): - pin = json.loads(Path(__file__).with_name("windows-crt.json").read_text())[target] - with urllib.request.urlopen(pin["url"], timeout=90) as response: - archive = response.read(6 * 1024 * 1024 + 1) - if hashlib.sha256(archive).hexdigest() != pin["sha256"]: - raise ValueError("Microsoft CRT archive digest mismatch") - with zipfile.ZipFile(io.BytesIO(archive)) as source: - member = source.getinfo(pin["member"]) - if member.file_size > 1024 * 1024: - raise ValueError("CRT member exceeds size limit") - data = source.read(member) - if hashlib.sha256(data).hexdigest() != pin["dllSha256"]: - raise ValueError("Microsoft CRT DLL digest mismatch") - # Extract exactly one retail member, never debug_nonredist or installer files. - with (root / "bin/vcruntime140.dll").open("xb") as output: - output.write(data) - files = list((root / "bin").glob("*.dll")) - bundled = {path.name.lower() for path in files} - imports = set() - for path in files: - if path.name.lower() != "vcruntime140.dll": - imports.update(inspect(path, target).imports) - # Only Microsoft's hash-pinned CRT may use ARM64X rather than plain ARM64. - for path in (helper, root / "bin/vcruntime140.dll"): - result = subprocess.run( - ["dumpbin", "/nologo", "/dependents", str(path)], - check=True, - capture_output=True, - timeout=30, - ) - imports.update( - re.findall( - r"(?mi)^ +([a-z0-9_+.-]+\.dll)\s*$", result.stdout.decode("ascii") - ) - ) - # Additional Windows OS imports used by the Rust helper, not bundled CRTs. - system = (EXTERNAL_IMPORTS - {"vcruntime140.dll"}) | { - "api-ms-win-core-synch-l1-2-0.dll", - "api-ms-win-core-winrt-error-l1-1-0.dll", - "bcrypt.dll", - "bcryptprimitives.dll", - "combase.dll", - "mmdevapi.dll", - "oleaut32.dll", - "ntdll.dll", - "userenv.dll", - "dbghelp.dll", - } - missing = {name.lower() for name in imports} - bundled - system - if missing: - raise ValueError(f"Unbundled Windows imports: {sorted(missing)}") - manifest_path = root / "runtime.json" - manifest = json.loads(manifest_path.read_text()) - if manifest.get("target") != target or manifest.get("developmentOnly") is not True: - raise ValueError("expected staged development runtime") - manifest["libraries"].append( - {"path": "bin/vcruntime140.dll", "sha256": pin["dllSha256"]} - ) - manifest_path.write_text(json.dumps(manifest, indent=2) + "\n") - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("--root", type=Path, required=True) - parser.add_argument("--target", required=True) - parser.add_argument("--helper", type=Path, required=True) - args = parser.parse_args() - stage(args.root, args.target, args.helper)