Skip to content

v3: make -cc msvc work again #23237

v3: make -cc msvc work again

v3: make -cc msvc work again #23237

Workflow file for this run

name: CI macOS
on:
workflow_dispatch:
push:
branches:
- master
paths-ignore:
# vlib/v/** is intentionally NOT ignored: V3 is the default compiler on
# macOS, so changes to it must run this suite; the canary below stays strict.
- '**.md'
- '**.yml'
- '!**/macos_ci.yml'
- 'cmd/tools/**'
- '!cmd/tools/builders/**.v'
pull_request:
paths-ignore:
# vlib/v/** is intentionally NOT ignored: V3 is the default compiler on
# macOS, so changes to it must run this suite; the canary below stays strict.
- '**.md'
- '**.yml'
- '!**/macos_ci.yml'
- 'cmd/tools/**'
- '!cmd/tools/builders/**.v'
concurrency:
group: macos-${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.sha || github.ref }}
cancel-in-progress: true
jobs:
clang-macos:
strategy:
matrix:
# V3 (vlib/v, `-new-compiler`) is the default compiler on macOS, so
# exercise it on every arm64 (Apple-silicon) runner image, not just one.
os: [macos-14, macos-15, macos-26]
fail-fast: false
runs-on: ${{ matrix.os }}
timeout-minutes: 151
env:
VFLAGS: -cc clang
VTEST_SHOW_LONGEST_BY_RUNTIME: 3
VTEST_SHOW_LONGEST_BY_COMPTIME: 3
VTEST_SHOW_LONGEST_BY_TOTALTIME: 3
# Keep every command on V3; the canary below also proves which compiler ran.
V_MACOS_V3_NO_FALLBACK: 1
# Temporarily disable x.multiwindow coverage while it is brought up on V3.
V_MACOS_MULTIWINDOW_TESTS: '0'
steps:
- uses: actions/checkout@v7
- name: Cache Homebrew downloads
uses: actions/cache@v6
with:
path: ~/Library/Caches/Homebrew
key: brew-${{ matrix.os }}-${{ hashFiles('.github/workflows/macos_ci.yml', 'ci/macos_ci.vsh') }}
restore-keys: |
brew-${{ matrix.os }}-
- name: Build V
# Bootstrap helpers must also compile with V3 once the fresh compiler exists.
env:
V_MACOS_V3_NO_FALLBACK: 1
run: make -j4 && ./v symlink
- name: Assert V is the default compiler (fail if V1 is silently used)
run: |
set -uo pipefail
printf 'fn main() { println(6 * 7) }\n' > "$RUNNER_TEMP/v3_canary.v"
V_MACOS_V3_NO_FALLBACK=1 ./v -v run "$RUNNER_TEMP/v3_canary.v" > "$RUNNER_TEMP/v3_canary.out" 2>&1 || true
cat "$RUNNER_TEMP/v3_canary.out"
grep -q '=== V compiler benchmark ===' "$RUNNER_TEMP/v3_canary.out" || { echo '::error::the default compiler was not dispatched on macOS'; exit 1; }
grep -qx '42' "$RUNNER_TEMP/v3_canary.out" || { echo '::error::the V-compiled canary did not build/run correctly'; exit 1; }
if grep -qiE 'retrying with .-old-compiler|compatibility fallback|used the stable compiler' "$RUNNER_TEMP/v3_canary.out"; then echo '::error::the default compiler silently fell back to V1'; exit 1; fi
echo 'OK: V compiled and ran this program in-process on macOS, with the fallback disabled'
- name: Legacy gg import multiwindow isolation
if: env.V_MACOS_MULTIWINDOW_TESTS == '1'
run: ./v test vlib/gg/legacy_import_multiwindow_isolation_test.v
- name: Prepare multiwindow process-tree watchdog
if: env.V_MACOS_MULTIWINDOW_TESTS == '1'
run: |
set -euo pipefail
cat > "$RUNNER_TEMP/multiwindow_ci_watchdog.v" <<'EOF'
module main
import gg.testdata.multiwindow_probe_watchdog
import os
import time
fn main() {
run_ci_watchdog() or {
eprintln(err.msg())
exit(1)
}
}
fn run_ci_watchdog() ! {
if os.args.len < 4 {
return error('usage: multiwindow_ci_watchdog timeout-seconds expected-final-line executable [args...]')
}
timeout_seconds := os.args[1].int()
if timeout_seconds <= 0 {
return error('multiwindow CI watchdog timeout must be positive')
}
expected_final_line := os.args[2]
gate_path := os.join_path(os.temp_dir(), 'multiwindow_ci_gate_${os.getpid()}_${time.now().unix_nano()}')
defer {
os.rm(gate_path) or {}
}
result := multiwindow_probe_watchdog.run(
executable: os.args[3]
args: os.args[4..]
timeout: timeout_seconds * time.second
start_file: gate_path
)!
if result.stdout != '' {
print(result.stdout)
}
if result.stderr != '' {
eprint(result.stderr)
}
if result.timed_out {
return error('multiwindow CI child timed out after ${timeout_seconds} seconds')
}
if !result.reaped {
return error('multiwindow CI child leader was not reaped')
}
if !result.confinement_empty {
return error('multiwindow CI child process confinement is not empty')
}
if result.forced_cleanup {
return error('multiwindow CI child required forced cleanup')
}
if result.exit_code != 0 {
return error('multiwindow CI child exited with ${result.exit_code}')
}
if expected_final_line == '-' {
return
}
mut actual_final_line := ''
for line in result.stdout.split_into_lines() {
if line.trim_space() != '' {
actual_final_line = line.trim_space()
}
}
if actual_final_line != expected_final_line {
return error('multiwindow CI final record mismatch: expected `${expected_final_line}`, got `${actual_final_line}`')
}
}
EOF
./v -cc clang -o "$RUNNER_TEMP/multiwindow_ci_watchdog" "$RUNNER_TEMP/multiwindow_ci_watchdog.v"
- name: Native operation proof (strict default-compiler gate)
if: env.V_MACOS_MULTIWINDOW_TESTS == '1'
env:
V_MACOS_V3_NO_FALLBACK: '1'
VGG_MULTIWINDOW_RUNTIME_PROBES: '1'
VGG_MULTIWINDOW_RUNTIME_BACKEND: appkit
VGG_MULTIWINDOW_EXAMPLE_UNATTENDED: appkit
V_MULTIWINDOW_PROBE_BACKEND: appkit
run: |
set -euo pipefail
source='vlib/x/multiwindow/native_operation_proof_test.v'
expected_source_sha256='e483121f01365b178f93d1c8e8f5f0fd181479a18193b0438be5bcde81cae1b8'
if [[ "${VFLAGS:-}" != '-cc clang' ]]; then
echo "native operation default-compiler gate VFLAGS mismatch" >&2
exit 1
fi
if [[ ! -s "$source" ]]; then
echo "native operation default-compiler gate source is missing or empty" >&2
exit 1
fi
actual_source_sha256="$(shasum -a 256 "$source" | awk '{print $1}')"
if [[ "$actual_source_sha256" != "$expected_source_sha256" ]]; then
echo "native operation default-compiler gate source hash mismatch" >&2
exit 1
fi
source_test_count="$(grep -Ec '^fn test_[A-Za-z0-9_]+\(\) \{$' "$source")"
if [[ "$source_test_count" != '53' ]]; then
echo "native operation default-compiler gate source test count mismatch" >&2
exit 1
fi
if [[ -n "${V_MACOS_V3_RETRY:-}" \
|| -n "${V_MACOS_V3_FALLBACK_FILE:-}" \
|| -n "${V_MACOS_V3_C_ERROR_DIR:-}" \
|| -n "${VTEST_ONLY:-}" \
|| -n "${VTEST_ONLY_FN:-}" \
|| -n "${VTEST_RUNNER:-}" \
|| -n "${V_MULTIWINDOW_NATIVE_PROOF_EGL_BAD_DISPLAY_CHILD:-}" \
|| -n "${V_MULTIWINDOW_NATIVE_PROOF_APPKIT_ORDINAL_EXHAUSTION_CHILD:-}" ]]; then
echo "native operation default-compiler gate inherited selector mismatch" >&2
exit 1
fi
"$RUNNER_TEMP/multiwindow_ci_watchdog" 300 - \
./v -no-retry-compilation -cc clang \
-d gg_multiwindow -d sokol_metal test "$source"
printf 'MULTIWINDOW_MACOS_NATIVE_OPERATION_PROOF status=PASS route=V3 sha256=%s tests=%s\n' \
"$actual_source_sha256" "$source_test_count"
- name: Multiwindow Metal regressions and runtime probes
if: env.V_MACOS_MULTIWINDOW_TESTS == '1'
# Keep the multiwindow runtime probes on V3 too.
env:
V_MACOS_V3_NO_FALLBACK: 1
VGG_MULTIWINDOW_RUNTIME_PROBES: '1'
VGG_MULTIWINDOW_RUNTIME_BACKEND: appkit
VGG_MULTIWINDOW_EXAMPLE_UNATTENDED: appkit
V_MULTIWINDOW_PROBE_BACKEND: appkit
run: |
set -euo pipefail
./v -cc clang -d gg_multiwindow -d sokol_metal \
-o /tmp/gg_multiwindow_metal examples/gg/multiwindow.v
./v -cc clang -d gg_multiwindow -d sokol_metal \
-o /tmp/gg_multiwindow_render_runtime_metal examples/gg/multiwindow_render_runtime.v
tests=(
vlib/x/multiwindow/event_sequence_exhaustion_test.v
vlib/x/multiwindow/event_terminal_delivery_test.v
vlib/x/multiwindow/internal_fault_matrix_test.v
vlib/x/multiwindow/multiwindow_test.v
vlib/x/multiwindow/render_scheduler_test.v
vlib/x/multiwindow/render_target_lease_test.v
vlib/x/multiwindow/service_mock_test.v
vlib/x/multiwindow/service_native_appkit_contract_red_test.v
vlib/x/multiwindow/service_native_appkit_final_nonreadback_red_test.v
vlib/x/multiwindow/service_native_appkit_nonreadback_test.v
vlib/x/multiwindow/service_native_appkit_readback_metal_red_test.v
vlib/x/multiwindow/teardown_contract_test.v
vlib/sokol/gfx/metal_private_hook_contract_test.v
vlib/gg/multiwindow_api_d_gg_multiwindow_test.v
vlib/gg/multiwindow_appkit_readback_d_gg_multiwindow_test.v
vlib/gg/multiwindow_buffer_cleanup_d_gg_multiwindow_test.v
vlib/gg/multiwindow_render_fault_matrix_d_gg_multiwindow_test.v
vlib/gg/multiwindow_render_runtime_contract_test.v
vlib/gg/frame_pacing_test.v
vlib/gg/draw_fns_api_test.v
vlib/gg/draw_rect_empty_test.v
)
native_operation_proof='vlib/x/multiwindow/native_operation_proof_test.v'
if [[ "${#tests[@]}" -ne 21 ]]; then
echo "multiwindow Metal test inventory cardinality mismatch" >&2
exit 1
fi
for test in "${tests[@]}"; do
if [[ "$test" == "$native_operation_proof" ]]; then
echo "native operation proof leaked into the strict V3 Metal inventory" >&2
exit 1
fi
done
for test in "${tests[@]}"; do
"$RUNNER_TEMP/multiwindow_ci_watchdog" 300 - \
./v -cc clang -d gg_multiwindow -d sokol_metal test "$test"
done
"$RUNNER_TEMP/multiwindow_ci_watchdog" 300 - \
./v -cc clang test vlib/gg/multiwindow_services_contract_test.v
"$RUNNER_TEMP/multiwindow_ci_watchdog" 120 \
'{"example":"multiwindow_render_runtime","status":"PASS","cleanup":"complete"}' \
/tmp/gg_multiwindow_render_runtime_metal
"$RUNNER_TEMP/multiwindow_ci_watchdog" 120 \
'{"example":"multiwindow","status":"PASS","cleanup":"complete"}' \
/tmp/gg_multiwindow_metal
- name: Test AppKit GLCore rejection guard
if: env.V_MACOS_MULTIWINDOW_TESTS == '1'
run: ./v -d gg_multiwindow -d darwin_sokol_glcore33 test vlib/x/multiwindow/multiwindow_test.v
- name: Test symlink
run: v run ci/macos_ci.vsh test_symlink
- name: v doctor
run: v run ci/macos_ci.vsh v_doctor
- name: Build v with -prealloc
run: v run ci/macos_ci.vsh build_v_with_prealloc
- name: Test cross compilation to Linux
run: v run ci/macos_ci.vsh test_cross_compilation
- name: Test inline assembly on macos
run: v run ci/macos_ci.vsh test_inline_assembly
- name: Build V with -cstrict
run: v run ci/macos_ci.vsh build_with_cstrict
- name: All code is formatted
run: v run ci/macos_ci.vsh all_code_is_formatted
- name: Run sanitizers
run: v run ci/macos_ci.vsh run_sanitizers
- name: Build V using V
run: v run ci/macos_ci.vsh build_using_v
- name: Verify `v test` works
run: v run ci/macos_ci.vsh verify_v_test_works
- name: Install iconv for encoding.iconv
run: v run ci/macos_ci.vsh install_iconv
- name: Test pure V math module
run: v run ci/macos_ci.vsh test_pure_v_math_module
- name: Self tests
run: v run ci/macos_ci.vsh self_tests
- name: Build examples
run: v run ci/macos_ci.vsh build_examples
- name: Build hello_world with -autofree
if: ${{ false }} # Ownership/autofree coverage is temporarily disabled on GitHub CI.
run: v run ci/macos_ci.vsh build_hello_world_autofree
- name: Build tetris with -autofree
if: ${{ false }} # Ownership/autofree coverage is temporarily disabled on GitHub CI.
run: v run ci/macos_ci.vsh build_tetris_autofree
- name: Build blog tutorial with -autofree
if: ${{ false }} # Ownership/autofree coverage is temporarily disabled on GitHub CI.
run: v run ci/macos_ci.vsh build_blog_autofree
- name: Build examples with -prod
run: v run ci/macos_ci.vsh build_examples_prod
- name: Build examples with V build with tcc
run: v run ci/macos_ci.vsh build_examples_v_compiled_with_tcc
## - name: V self compilation with -usecache
## run: v run ci/macos_ci.vsh v_self_compilation_usecache
- name: V self compilation with -parallel-cc
run: v run ci/macos_ci.vsh v_self_compilation_parallel_cc
- name: Test password input
run: v run ci/macos_ci.vsh test_password_input
- name: Test readline
run: v run ci/macos_ci.vsh test_readline