Repository navigation
measure: print vcpkg's compiler-detection logs on failure [vs-only] #2
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: measure 734 | |
| # Readings for the design of #734 (.agents/docs/2026-09-28-build-cost-foreign- | |
| # toolsets-and-library-surface-design.md). Every leg prints `READING <id>: ...` | |
| # lines and never fails the job on the value it reads; a job fails only when the | |
| # harness itself cannot run. | |
| # | |
| # M1 vcpkg on a Visual Studio machine: does selecting the instance through the | |
| # environment (VCPKG_VISUAL_STUDIO_PATH) keep the ABI hash of a port? | |
| # M2 vcpkg on a Visual Studio machine: a chain-loaded triplet (toolset | |
| # "external") against an MSBuild port (libusb), a CMake port (zlib) as the | |
| # control of the chain-loaded setup, and the hybrid with vcvars loaded. | |
| # M3 vcpkg with Visual Studio masked and the managed msvc@14.44.35207 named by a | |
| # chain-loaded triplet: zlib (CMake) and icu (make under msys). | |
| # P3 the same toolset copied to another path: is the port restored from the | |
| # binary cache (same ABI hash)? | |
| # E2b mcpp 2026.9.28.2 + mcpp:plugins 0.16.0 + fmt: cxx_runtime x triplet. | |
| # E4 the time of 1270 deploy edges on a first build. | |
| on: | |
| push: | |
| branches: [ 'measure/734-readings' ] | |
| workflow_dispatch: | |
| env: | |
| XLINGS_NON_INTERACTIVE: '1' | |
| BASELINE: ee6a47dac031930715bea2e6dfb9ad60caaa5d83 | |
| jobs: | |
| vcpkg-vs: | |
| name: M1 M2 (Visual Studio) | |
| runs-on: windows-2025 | |
| timeout-minutes: 90 | |
| defaults: { run: { shell: bash } } | |
| steps: | |
| - name: Locate Visual Studio and load its developer environment | |
| shell: pwsh | |
| run: | | |
| $vsp = & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath | |
| Write-Host "VS: $vsp" | |
| $bat = Join-Path $vsp "VC\Auxiliary\Build\vcvars64.bat" | |
| $lines = cmd /d /s /c "`"$bat`" >nul && set" | |
| foreach ($l in $lines) { | |
| $k, $v = $l -split '=', 2 | |
| if ($k -in 'INCLUDE', 'LIB', 'LIBPATH', 'Path') { Set-Item "env:$k" $v } | |
| } | |
| $out = @( | |
| "VSP=$vsp", | |
| "INCLUDE=$env:INCLUDE", "LIB=$env:LIB", "LIBPATH=$env:LIBPATH", | |
| "MEASURE_CL=$((Get-Command cl.exe).Source)", | |
| "MEASURE_RC=$((Get-Command rc.exe).Source)", | |
| "MEASURE_MT=$((Get-Command mt.exe).Source)", | |
| "MEASURE_VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | |
| ) | |
| $out | ForEach-Object { Write-Host $_ } | |
| $out | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 | |
| - name: Locate vcpkg | |
| run: | | |
| V="$(cygpath -u "$VCPKG_INSTALLATION_ROOT")/vcpkg.exe" | |
| test -x "$V" || { echo "::error::no vcpkg at $VCPKG_INSTALLATION_ROOT"; exit 1; } | |
| "$V" version | head -1 | |
| echo "V=$V" >> "$GITHUB_ENV" | |
| mkdir -p "$RUNNER_TEMP/bincache" | |
| echo "VCPKG_BINARY_SOURCES=clear;files,$(cygpath -w "$RUNNER_TEMP/bincache"),readwrite" >> "$GITHUB_ENV" | |
| - name: Write the manifests and the chain-loaded triplets | |
| run: | | |
| set -e | |
| T="$RUNNER_TEMP/triplets"; mkdir -p "$T" | |
| base="set(VCPKG_TARGET_ARCHITECTURE x64) | |
| set(VCPKG_CRT_LINKAGE dynamic) | |
| set(VCPKG_LIBRARY_LINKAGE dynamic)" | |
| chain='set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/chain.cmake") | |
| set(VCPKG_ENV_PASSTHROUGH_UNTRACKED INCLUDE LIB LIBPATH MEASURE_CL MEASURE_RC MEASURE_MT MEASURE_VCPKG_ROOT)' | |
| printf '%s\n%s\n' "$base" "$chain" | sed 's/^ *//' > "$T/x64-windows-chain.cmake" | |
| printf '%s\n%s\nset(VCPKG_LOAD_VCVARS_ENV ON)\n' "$base" "$chain" | sed 's/^ *//' > "$T/x64-windows-chainvc.cmake" | |
| cat > "$T/chain.cmake" <<'EOF' | |
| set(CMAKE_C_COMPILER "$ENV{MEASURE_CL}") | |
| set(CMAKE_CXX_COMPILER "$ENV{MEASURE_CL}") | |
| set(CMAKE_RC_COMPILER "$ENV{MEASURE_RC}") | |
| set(CMAKE_MT "$ENV{MEASURE_MT}") | |
| include("$ENV{MEASURE_VCPKG_ROOT}/scripts/toolchains/windows.cmake") | |
| EOF | |
| sed -i 's/^ *//' "$T/chain.cmake" | |
| cat "$T"/*.cmake | |
| for p in zlib libusb; do | |
| for leg in a b; do | |
| d="$RUNNER_TEMP/m-$p-$leg"; mkdir -p "$d" | |
| printf '{ "name": "m%s", "version": "0.1.0", "dependencies": ["%s"] }\n' "$leg" "$p" > "$d/vcpkg.json" | |
| done | |
| done | |
| - name: M1 the instance named through the environment | |
| continue-on-error: true | |
| run: | | |
| set +e +o pipefail | |
| abi() { cat "$1"/vcpkg_installed/x64-windows/share/zlib/vcpkg_abi_info.txt 2>/dev/null | sha256sum | cut -c1-16; } | |
| ( cd "$RUNNER_TEMP/m-zlib-a" && "$V" install --triplet x64-windows ) > m1a.log 2>&1; echo "READING M1a: default instance, exit $?" | |
| ( cd "$RUNNER_TEMP/m-zlib-b" && VCPKG_VISUAL_STUDIO_PATH="$VSP" "$V" install --triplet x64-windows ) > m1b.log 2>&1; echo "READING M1b: VCPKG_VISUAL_STUDIO_PATH, exit $?" | |
| echo "READING M1: abi_info a=$(abi "$RUNNER_TEMP/m-zlib-a") b=$(abi "$RUNNER_TEMP/m-zlib-b")" | |
| echo "READING M1: leg b $(grep -iE 'Restored [0-9]+ package|Building zlib' m1b.log | head -2 | tr '\n' ' ')" | |
| ls -R "$RUNNER_TEMP/bincache" | grep -i '\.zip' | head | |
| - name: M2 chain-loaded triplets against CMake and MSBuild ports | |
| continue-on-error: true | |
| run: | | |
| set +e +o pipefail | |
| T=$(cygpath -w "$RUNNER_TEMP/triplets") | |
| run() { # $1 port, $2 triplet, $3 label | |
| d="$RUNNER_TEMP/m2-$1-$2"; rm -rf "$d"; mkdir -p "$d" | |
| cp "$RUNNER_TEMP/m-$1-a/vcpkg.json" "$d/" | |
| ( cd "$d" && "$V" install --triplet "$2" --overlay-triplets="$T" ) > "m2-$1-$2.log" 2>&1 | |
| rc=$? | |
| echo "READING M2 $3: $1 under $2 exit $rc" | |
| [ $rc = 0 ] || { grep -iE 'error|PlatformToolset|external' "m2-$1-$2.log" | head -8; tail -5 "m2-$1-$2.log"; } | |
| if [ $rc != 0 ]; then | |
| for f in "$(cygpath -u "$VCPKG_INSTALLATION_ROOT")"/buildtrees/detect_compiler/*"$2"*.log \ | |
| "$(cygpath -u "$VCPKG_INSTALLATION_ROOT")"/buildtrees/"$1"/*"$2"*.log; do | |
| [ -f "$f" ] || continue | |
| echo "----- $f"; tail -40 "$f"; cp "$f" "m2-detail-$1-$2-$(basename "$f")" 2>/dev/null | |
| done | |
| rm -rf "$(cygpath -u "$VCPKG_INSTALLATION_ROOT")"/buildtrees/detect_compiler | |
| fi | |
| } | |
| run libusb x64-windows "control" | |
| run zlib x64-windows-chain "chain-loaded, CMake port" | |
| run libusb x64-windows-chain "chain-loaded, MSBuild port" | |
| run libusb x64-windows-chainvc "chain-loaded with vcvars, MSBuild port" | |
| run zlib x64-windows-chainvc "chain-loaded with vcvars, CMake port" | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: { name: m1-m2-logs, path: '*.log' } | |
| vcpkg-managed: | |
| name: M3 P3 (Visual Studio masked, managed msvc) | |
| if: "!contains(github.event.head_commit.message, '[vs-only]')" | |
| runs-on: windows-2025 | |
| timeout-minutes: 150 | |
| defaults: { run: { shell: bash } } | |
| steps: | |
| - name: Mask Visual Studio | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Continue' | |
| $vswhere = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" | |
| if (Test-Path $vswhere) { Rename-Item $vswhere "vswhere.exe.masked" } | |
| Resolve-Path "C:\Program Files*\Microsoft Visual Studio\*\*\VC" -ErrorAction SilentlyContinue | ForEach-Object { | |
| try { Rename-Item -LiteralPath $_.Path -NewName "VC.masked" -ErrorAction Stop } | |
| catch { Write-Host " rename failed: $($_.Exception.Message)" } | |
| } | |
| foreach ($v in @('VSINSTALLDIR','VCINSTALLDIR','VCToolsInstallDir','VS170COMNTOOLS','VS160COMNTOOLS','VS150COMNTOOLS')) { | |
| "$v=" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 | |
| } | |
| $left = Get-ChildItem "C:\Program Files*\Microsoft Visual Studio\*\*\VC\Tools\MSVC" -Directory -ErrorAction SilentlyContinue | |
| if ($left) { Write-Host "FAIL: VC tools still present after masking"; exit 1 } | |
| - name: Install xlings | |
| shell: pwsh | |
| run: | | |
| irm https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.ps1 | iex | |
| "$env:USERPROFILE\.xlings\subos\current\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| "$env:USERPROFILE\.xlings\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| - name: Install msvc@14.44.35207 and derive its environment | |
| run: | | |
| set -e | |
| ( cd "$RUNNER_TEMP" && xlings install msvc@14.44.35207 -y ) > msvc-install.log 2>&1 || { tail -30 msvc-install.log; exit 1; } | |
| X="$(cygpath -u "$USERPROFILE")/.xlings/data/xpkgs" | |
| CL=$(find "$X"/xim-x-msvc -path '*Hostx64/x64/cl.exe' | head -1) | |
| test -n "$CL" || { echo "::error::no cl.exe under $X/xim-x-msvc"; exit 1; } | |
| TOOLS=${CL%/bin/Hostx64/x64/cl.exe} | |
| WH=$(find "$X"/xim-x-windows-sdk -name windows.h -path '*/um/*' | head -1) | |
| INCV=$(dirname "$(dirname "$WH")"); VER=$(basename "$INCV"); SDK=$(dirname "$(dirname "$INCV")") | |
| RC=$(find "$SDK" -path "*$VER*x64/rc.exe" | head -1); MT=$(find "$SDK" -path "*$VER*x64/mt.exe" | head -1) | |
| echo "tools=$TOOLS sdk=$SDK ver=$VER rc=$RC mt=$MT" | |
| w() { cygpath -w "$1"; } | |
| echo "TOOLS=$TOOLS" >> "$GITHUB_ENV"; echo "SDK=$SDK" >> "$GITHUB_ENV"; echo "SDKVER=$VER" >> "$GITHUB_ENV" | |
| echo "MEASURE_RC=$(w "$RC")" >> "$GITHUB_ENV"; echo "MEASURE_MT=$(w "$MT")" >> "$GITHUB_ENV" | |
| echo "MEASURE_VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> "$GITHUB_ENV" | |
| mkdir -p "$RUNNER_TEMP/bincache" | |
| echo "VCPKG_BINARY_SOURCES=clear;files,$(cygpath -w "$RUNNER_TEMP/bincache"),readwrite" >> "$GITHUB_ENV" | |
| echo "V=$(cygpath -u "$VCPKG_INSTALLATION_ROOT")/vcpkg.exe" >> "$GITHUB_ENV" | |
| - name: M3 and P3 chain-loaded managed toolset | |
| continue-on-error: true | |
| run: | | |
| set +e +o pipefail | |
| T="$RUNNER_TEMP/triplets"; mkdir -p "$T" | |
| printf '%s\n' 'set(VCPKG_TARGET_ARCHITECTURE x64)' 'set(VCPKG_CRT_LINKAGE dynamic)' 'set(VCPKG_LIBRARY_LINKAGE dynamic)' \ | |
| 'set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/chain.cmake")' \ | |
| 'set(VCPKG_ENV_PASSTHROUGH_UNTRACKED INCLUDE LIB LIBPATH MEASURE_CL MEASURE_RC MEASURE_MT MEASURE_VCPKG_ROOT)' \ | |
| > "$T/x64-windows-chain.cmake" | |
| printf '%s\n' 'set(CMAKE_C_COMPILER "$ENV{MEASURE_CL}")' 'set(CMAKE_CXX_COMPILER "$ENV{MEASURE_CL}")' \ | |
| 'set(CMAKE_RC_COMPILER "$ENV{MEASURE_RC}")' 'set(CMAKE_MT "$ENV{MEASURE_MT}")' \ | |
| 'include("$ENV{MEASURE_VCPKG_ROOT}/scripts/toolchains/windows.cmake")' > "$T/chain.cmake" | |
| setenv() { # $1 = the toolset directory | |
| w() { cygpath -w "$1"; } | |
| export MEASURE_CL="$(w "$1/bin/Hostx64/x64/cl.exe")" | |
| I="$SDK/Include/$SDKVER"; L="$SDK/Lib/$SDKVER" | |
| export INCLUDE="$(w "$1/include");$(w "$I/ucrt");$(w "$I/um");$(w "$I/shared");$(w "$I/winrt");$(w "$I/cppwinrt")" | |
| export LIB="$(w "$1/lib/x64");$(w "$L/ucrt/x64");$(w "$L/um/x64")" | |
| export LIBPATH="$(w "$1/lib/x64")" | |
| } | |
| run() { # $1 port, $2 label, $3 dir suffix | |
| d="$RUNNER_TEMP/m3-$1-$3"; rm -rf "$d"; mkdir -p "$d" | |
| printf '{ "name": "m", "version": "0.1.0", "dependencies": ["%s"] }\n' "$1" > "$d/vcpkg.json" | |
| ( cd "$d" && "$V" install --triplet x64-windows-chain --overlay-triplets="$(cygpath -w "$T")" ) > "m3-$1-$3.log" 2>&1 | |
| rc=$? | |
| echo "READING $2: $1 exit $rc; $(grep -iE 'Restored [0-9]+ package' "m3-$1-$3.log" | head -1)" | |
| [ $rc = 0 ] || { grep -iE 'error' "m3-$1-$3.log" | head -8; tail -5 "m3-$1-$3.log"; } | |
| } | |
| setenv "$TOOLS" | |
| run zlib "M3 managed, CMake port" a | |
| run icu "M3 managed, make port" a | |
| # P3: the same toolset at another path; a restore means the same ABI hash. | |
| cp -r "$TOOLS" "$RUNNER_TEMP/tc2" | |
| setenv "$RUNNER_TEMP/tc2" | |
| run zlib "P3 same toolset, other path" b | |
| ls -R "$RUNNER_TEMP/bincache" | grep -ic '\.zip' | sed 's/^/READING P3: archives in the cache: /' | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: { name: m3-p3-logs, path: '*.log' } | |
| mcpp-legs: | |
| name: E2b E4 (mcpp 2026.9.28.2) | |
| if: "!contains(github.event.head_commit.message, '[vs-only]')" | |
| runs-on: windows-2025 | |
| timeout-minutes: 120 | |
| defaults: { run: { shell: bash } } | |
| steps: | |
| - name: Install xlings | |
| shell: pwsh | |
| run: | | |
| irm https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.ps1 | iex | |
| "$env:USERPROFILE\.xlings\subos\current\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| "$env:USERPROFILE\.xlings\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| - name: Install mcpp 2026.9.28.2 | |
| run: | | |
| set -e | |
| ( cd "$RUNNER_TEMP" && xlings install mcpp@2026.9.28.2 -y ) > mcpp-install.log 2>&1 || { tail -30 mcpp-install.log; exit 1; } | |
| M="$(cygpath -u "$USERPROFILE")/.xlings/data/xpkgs/xim-x-mcpp/2026.9.28.2/bin/mcpp.exe" | |
| "$M" --version | |
| "$M" self config --mirror GLOBAL | |
| echo "M=$M" >> "$GITHUB_ENV" | |
| - name: E2b the C++ runtime contract against vcpkg's CRT linkage | |
| continue-on-error: true | |
| run: | | |
| set +e +o pipefail | |
| for crt in toolchain-coupled self-contained; do | |
| for trip in x64-windows x64-windows-static-md; do | |
| d="$RUNNER_TEMP/e2b-$crt-$trip"; mkdir -p "$d/src" | |
| printf '[package]\nname = "crtprobe"\nversion = "0.1.0"\nstandard = "c++23"\n\n[toolchain]\nwindows = "llvm@22.1.8"\n\n[build]\ncxx_runtime = "%s"\n\n[build-dependencies]\nmcpp.plugins = { version = "0.16.0", features = ["deps-vcpkg"], host-module = true }\n' "$crt" > "$d/mcpp.toml" | |
| printf '{ "name": "crtprobe", "version": "0.1.0", "dependencies": ["fmt"], "builtin-baseline": "%s" }\n' "$BASELINE" > "$d/vcpkg.json" | |
| cat > "$d/build.mcpp" <<EOF | |
| import std; | |
| import mcpp; | |
| import mcpp.deps.vcpkg; | |
| int main() { | |
| mcpp::deps::vcpkg::options o; | |
| o.triplet = "$trip"; | |
| o.libraries = {"fmt"}; | |
| return mcpp::deps::vcpkg::use(o) ? 0 : 1; | |
| } | |
| EOF | |
| sed -i 's/^ //' "$d/build.mcpp" | |
| printf '#include <fmt/format.h>\n#include <string>\nint main() { std::string s = fmt::format("{}-{}", 4, 2); return s == "4-2" ? 0 : 3; }\n' > "$d/src/main.cpp" | |
| ( cd "$d" && "$M" build ) > "e2b-$crt-$trip.log" 2>&1; b=$? | |
| r=skip | |
| if [ $b = 0 ]; then ( cd "$d" && "$M" run ) >> "e2b-$crt-$trip.log" 2>&1; r=$?; fi | |
| echo "READING E2b: cxx_runtime=$crt triplet=$trip build exit $b, run exit $r" | |
| grep -iE 'LNK2038|mismatch|FAILIFMISMATCH|RuntimeLibrary|error' "e2b-$crt-$trip.log" | head -6 | |
| done | |
| done | |
| - name: E4 the time of deploy edges on a first build | |
| continue-on-error: true | |
| run: | | |
| set +e +o pipefail | |
| for n in 0 1270; do | |
| d="$RUNNER_TEMP/e4-$n"; mkdir -p "$d/src" "$d/data" | |
| for i in $(seq 1 $n); do echo "$i" > "$d/data/f$i.txt"; done | |
| printf '[package]\nname = "e4"\nversion = "0.1.0"\nstandard = "c++23"\n' > "$d/mcpp.toml" | |
| printf 'int main() { return 0; }\n' > "$d/src/main.cpp" | |
| cat > "$d/build.mcpp" <<EOF | |
| import std; | |
| import mcpp; | |
| int main() { | |
| for (int i = 1; i <= $n; ++i) { | |
| const std::string f = "data/f" + std::to_string(i) + ".txt"; | |
| mcpp::deploy(f.c_str(), "data"); | |
| } | |
| return 0; | |
| } | |
| EOF | |
| sed -i 's/^ //' "$d/build.mcpp" | |
| for run in 1 2; do | |
| rm -rf "$d/target" | |
| s=$(date +%s.%N); ( cd "$d" && "$M" build ) > "e4-$n-$run.log" 2>&1; rc=$?; e=$(date +%s.%N) | |
| log=$(find "$d/target" -name .ninja_log | head -1) | |
| stats=$(awk -F'\t' 'NR>1 && $4 ~ /data[\\\/]f[0-9]+\.txt$/ {n++; s+=$2-$1; if(min==""||$1<min)min=$1; if($2>max)max=$2} END {printf "edges=%d sum=%.1fs span=%.1fs", n, s/1000, (max-min)/1000}' "$log" 2>/dev/null) | |
| echo "READING E4: n=$n run=$run exit $rc wall=$(awk "BEGIN { printf \"%.1f\", $e - $s }")s $stats" | |
| done | |
| done | |
| d="$RUNNER_TEMP/e4-1270"; rm -rf "$RUNNER_TEMP/e4-copy" | |
| s=$(date +%s.%N); cp -r "$d/data" "$RUNNER_TEMP/e4-copy"; e=$(date +%s.%N) | |
| echo "READING E4: one process copying the same 1270 files: $(awk "BEGIN { printf \"%.1f\", $e - $s }")s" | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: { name: e2b-e4-logs, path: '*.log' } |