Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion .github/workflows/ci-pull.yml
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,30 @@ jobs:
- name: Build
run: cmake --build build --config Debug -j
- name: Test (unit)
run: ctest --test-dir build -C Debug --output-on-failure
# The trait_compile_* fixtures invoke cl.exe DIRECTLY from a
# generated cmake -P script (execute_process), outside the VS
# generator's toolchain setup, so — unlike every other test in
# this job — they need the MSVC environment (INCLUDE/LIB/PATH)
# to find the CRT/STL headers; the plain runner shell lacks it
# and cl fails with C1083 on <cstdint> etc. This step imports
# the VS development environment into the current PowerShell
# process: vswhere locates the installation, VsDevCmd.bat (the
# canonical vcvars, present in every VS 2017+ install under
# Common7\Tools — called by relative name from that directory,
# so no path quoting is involved) sets it, and its `set` dump
# is imported variable by variable. ctest, cmake -P, and cl all
# inherit it. Everything else in this step is unchanged.
run: |
$vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationPath
Push-Location (Join-Path $vs "Common7\Tools")
$envDump = cmd /c "call VsDevCmd.bat -arch=amd64 -host_arch=amd64 >nul && set"
Pop-Location
foreach ($line in $envDump) {
if ($line -match '^([A-Za-z_][A-Za-z0-9_]*)=(.*)$') {
Set-Item -Path "env:$($matches[1])" -Value $matches[2]
}
}
ctest --test-dir build -C Debug --output-on-failure

macos-arm64:
name: macOS arm64 (AppleClang)
Expand Down
33 changes: 31 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@
# would build every configuration from the canonical `cmake --build build
# -j`. The Windows job therefore pins the canonical Debug configuration
# explicitly on the build and test steps (--config Debug / -C Debug); the
# single-config platforms run the canonical commands verbatim.
# single-config platforms run the canonical commands verbatim. The
# Windows Test step additionally imports the VS 2022 development
# environment (vswhere + VsDevCmd.bat, same step, before ctest) because
# the trait_compile_* fixtures invoke cl.exe directly from a generated
# cmake -P script — outside the VS generator's toolchain setup — and
# need the MSVC environment (INCLUDE/LIB/PATH) to find the CRT/STL
# headers.
#
# AC-6.1 (same source tree, same feature set, no per-OS feature flags): no
# build job passes feature flags; every build job builds the identical
Expand Down Expand Up @@ -221,7 +227,30 @@ jobs:
- name: Build
run: cmake --build build --config Debug -j
- name: Test (unit)
run: ctest --test-dir build -C Debug --output-on-failure
# The trait_compile_* fixtures invoke cl.exe DIRECTLY from a
# generated cmake -P script (execute_process), outside the VS
# generator's toolchain setup, so — unlike every other test in
# this job — they need the MSVC environment (INCLUDE/LIB/PATH)
# to find the CRT/STL headers; the plain runner shell lacks it
# and cl fails with C1083 on <cstdint> etc. This step imports
# the VS development environment into the current PowerShell
# process: vswhere locates the installation, VsDevCmd.bat (the
# canonical vcvars, present in every VS 2017+ install under
# Common7\Tools — called by relative name from that directory,
# so no path quoting is involved) sets it, and its `set` dump
# is imported variable by variable. ctest, cmake -P, and cl all
# inherit it. Everything else in this step is unchanged.
run: |
$vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationPath
Push-Location (Join-Path $vs "Common7\Tools")
$envDump = cmd /c "call VsDevCmd.bat -arch=amd64 -host_arch=amd64 >nul && set"
Pop-Location
foreach ($line in $envDump) {
if ($line -match '^([A-Za-z_][A-Za-z0-9_]*)=(.*)$') {
Set-Item -Path "env:$($matches[1])" -Value $matches[2]
}
}
ctest --test-dir build -C Debug --output-on-failure

macos-arm64:
name: macOS arm64 (AppleClang)
Expand Down
9 changes: 9 additions & 0 deletions docs/getting-started/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ Notes:
`TSAN_OPTIONS=halt_on_error=1` (wired in `tests/<module>/CMakeLists.txt`
when `LAIGE_TSAN=ON`), so a data race makes `ctest` fail with a non-zero
exit — no extra environment setup needed.
- G-R8 trait compile checks (`trait_compile_*`, `tests/laige-sim`): four
CTest fixtures that compile (not link, not run) one translation unit
each with the engine policy flags and assert both the exit code and —
for the negative fixtures — the actionable G-R8 message in the compiler
output. On Windows they invoke `cl.exe` directly from a generated
`cmake -P` script, outside the VS generator's toolchain setup, so run
them from a VS Developer shell (or any shell with the MSVC environment
loaded: `INCLUDE`/`LIB`/`PATH` set); CI's Windows Test step imports it
via `VsDevCmd.bat` (see `.github/workflows/ci.yml`).

## Build trees and artifacts

Expand Down
35 changes: 24 additions & 11 deletions tests/laige-sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -215,23 +215,36 @@ add_test(NAME determinism_mode
# expect-compile-result.cmake.in for the rationale.
function(laige_add_compile_check name source expect_ok fragment)
if(CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
set(_flags "-std=c++20 -Wall -Werror -fno-exceptions -fno-rtti"
" -ffp-contract=off -fno-associative-math")
set(_includes "-I${CMAKE_SOURCE_DIR}/src/laige-sim/include"
"-I${CMAKE_SOURCE_DIR}/src/laige-core/include")
set(_flags -std=c++20 -Wall -Werror -fno-exceptions -fno-rtti
-ffp-contract=off -fno-associative-math)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(_flags "/std:c++20 /W4 /WX /EHs- /EHc- /GR-"
" /fp:precise /D _HAS_EXCEPTIONS=0")
set(_includes "/I${CMAKE_SOURCE_DIR}/src/laige-sim/include"
"/I${CMAKE_SOURCE_DIR}/src/laige-core/include")
set(_flags /std:c++20 /W4 /WX /EHs- /EHc- /GR-
/fp:precise /D _HAS_EXCEPTIONS=0)
else()
message(FATAL_ERROR
"no compile-check flags for '${CMAKE_CXX_COMPILER_ID}'")
endif()
set(CXX "${CMAKE_CXX_COMPILER}")
set(CXXFLAGS "${_flags} ${_includes}")
set(_includes "-I${CMAKE_SOURCE_DIR}/src/laige-sim/include"
"-I${CMAKE_SOURCE_DIR}/src/laige-core/include")
# The compiler invocation is a CMake list: exactly one process
# argument per element. The generated script quotes each element
# (CMD_TEXT below) because configure_file substitutes plain text and
# unquoted text in the generated execute_process call would be
# re-split on whitespace — which breaks any argument containing
# spaces. The MSVC compiler path on Windows
# ("C:/Program Files/Microsoft Visual Studio/.../cl.exe") is the
# canonical case: split at the first space it becomes the argument
# "C:/Program", a failed process launch that CMake reports as the
# result "no such file or directory" with no compiler output.
set(_cmd "${CMAKE_CXX_COMPILER}" ${_flags} ${_includes}
"-c" "${CMAKE_CURRENT_SOURCE_DIR}/compile_fail/${source}"
"-o" "${CMAKE_CURRENT_BINARY_DIR}/compile_check_${name}.o")
set(CMD_TEXT "")
foreach(_arg IN LISTS _cmd)
string(REPLACE "\"" "\\\"" _arg_quoted "${_arg}")
string(APPEND CMD_TEXT "\"${_arg_quoted}\" ")
endforeach()
set(SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/compile_fail/${source}")
set(OBJ "${CMAKE_CURRENT_BINARY_DIR}/compile_check_${name}.o")
set(EXPECT_OK "${expect_ok}")
set(FRAGMENT "${fragment}")
configure_file(
Expand Down
19 changes: 18 additions & 1 deletion tests/laige-sim/expect-compile-result.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,26 @@
#
# The script exits non-zero (failing the CTest test) on any mismatch
# and prints the full compiler output for diagnosis.
#
# _cmd is a quoted CMake list — one element per process argument.
# Quoting is load-bearing: configure_file substitutes plain text, and
# unquoted text in an execute_process call is re-split on whitespace,
# which would break any argument containing spaces (the MSVC compiler
# path "C:/Program Files/Microsoft Visual Studio/.../cl.exe" on
# Windows). The list expansion below passes each element as exactly
# one argument regardless of its content.
#
# MSVC note: cl launched this way runs outside the VS generator's
# toolchain setup, so the surrounding environment MUST already carry
# the MSVC INCLUDE/LIB/PATH (or cl fails with C1083 on <cstdint> etc.).
# The CI Windows Test step imports the VS development environment into
# the step before ctest (vswhere + VsDevCmd.bat — see
# .github/workflows/ci.yml); a local Windows run needs the same
# (e.g. a VS Developer PowerShell).

set(_cmd @CMD_TEXT@)
execute_process(
COMMAND @CXX@ @CXXFLAGS@ -c "@SOURCE@" -o "@OBJ@"
COMMAND ${_cmd}
RESULT_VARIABLE _rc
OUTPUT_VARIABLE _out
ERROR_VARIABLE _err
Expand Down
7 changes: 6 additions & 1 deletion tests/tools/expect-det-lint-result.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
# prints the full lint output for diagnosis.

execute_process(
COMMAND @PYTHON@ "@LINT@" --root "@ROOT@"
# "@PYTHON@" is quoted like every other generated-script command (the
# rationale is in expect-lint-result.cmake.in): unquoted text in an
# execute_process call is re-split on whitespace, which would break a
# python interpreter path containing spaces on a local Windows
# checkout.
COMMAND "@PYTHON@" "@LINT@" --root "@ROOT@"
RESULT_VARIABLE _rc
OUTPUT_VARIABLE _out
ERROR_VARIABLE _err
Expand Down
8 changes: 7 additions & 1 deletion tests/tools/expect-lint-result.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
# prints the full lint output for diagnosis.

execute_process(
COMMAND @PYTHON@ "@LINT@" --root "@ROOT@"
# "@PYTHON@" is quoted like every other generated-script command:
# configure_file substitutes plain text, and unquoted text in an
# execute_process call is re-split on whitespace, which would break a
# python interpreter path containing spaces (e.g. "C:/Program
# Files/Python3xx/python.exe" on a local Windows checkout; the CI
# runner's hostedtoolcache path has none, so this only bites locally).
COMMAND "@PYTHON@" "@LINT@" --root "@ROOT@"
RESULT_VARIABLE _rc
OUTPUT_VARIABLE _out
ERROR_VARIABLE _err
Expand Down
Loading