Files
libakgl/examples/sidescroller/CMakeLists.txt
Andrew Kesterson d8458d1e68
Some checks failed
libakgl CI Build / cmake_build (push) Failing after 8m56s
libakgl CI Build / memory_check (push) Has been cancelled
libakgl CI Build / mutation_test (push) Has been cancelled
libakgl CI Build / performance (push) Has been cancelled
Stop set_tests_properties from eating the test environment lists
The example games failed on the CI runner with "ALSA: Couldn't open audio
device" despite SDL_AUDIODRIVER=dummy sitting right there in their CMake --
because it never reached the process. set_tests_properties parses its
PROPERTIES arguments as name/value pairs, so a semicolon-separated value
list is split and every element after the first is consumed as a bogus
property name: ENVIRONMENT kept only SDL_VIDEODRIVER=dummy, and the
LD_LIBRARY_PATH prepend list kept only its first directory. ctest
--show-only=json-v1 shows the truncation plainly.

Nobody could see it. Video survived because SDL3 falls through its driver
list to dummy on a headless machine with no hint at all; audio survived on
every developer machine because the real device works there; the library
paths survived because RPATH covered them. A runner with no sound card was
the first environment where any of it mattered.

Every list-valued test property now goes through set_property(TEST ...),
which takes real list arguments -- the examples' ENVIRONMENT triplets and
vendored-path modifications, the suites' LD_LIBRARY_PATH prepends, and the
docs harness's driver variables. Verified by property dump (3 environment
entries and all 7 prepends present) and by running the example tests with
ALSA_CONFIG_PATH=/dev/null, which now pass where a real ALSA open would
fail: the dummy driver is finally the one being asked.

Co-Authored-By: Claude Code (Claude Fable 5, claude-fable-5) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
2026-08-02 14:19:05 -04:00

56 lines
2.6 KiB
CMake

# The sidescroller tutorial game.
#
# A real target, built by default, so docs/19-tutorial-sidescroller.md cannot
# quote a program that does not compile -- and registered as a headless smoke
# test, so it cannot quote one that does not run.
get_filename_component(SS_ASSET_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/../../docs/tutorials/assets/sidescroller" ABSOLUTE)
add_executable(sidescroller
main.c
player.c
actors.c
)
target_include_directories(sidescroller PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
target_compile_options(sidescroller PRIVATE ${AKGL_WARNING_FLAGS})
# Baked in rather than looked up at runtime, so the smoke test can be launched
# from any working directory. `--assets DIR` overrides it for a reader who has
# moved the art somewhere else.
target_compile_definitions(sidescroller PRIVATE "SS_ASSET_DIR=\"${SS_ASSET_DIR}\"")
target_link_libraries(sidescroller
PRIVATE akstdlib::akstdlib akerror::akerror akgl SDL3::SDL3 SDL3_ttf::SDL3_ttf
SDL3_image::SDL3_image SDL3_mixer::SDL3_mixer jansson::jansson -lm)
# A vendored build leaves the SDL satellite libraries in per-project
# subdirectories that are not on the loader's default search path, which is the
# same problem AKGL_VENDORED_RPATH solves for the test executables.
if(AKGL_VENDORED_DEPENDENCIES)
set_target_properties(sidescroller PROPERTIES BUILD_RPATH "${AKGL_VENDORED_RPATH}")
endif()
# Four seconds of scripted play under the headless drivers: the level loads, the
# player walks and jumps, the swept collision runs against real terrain, and the
# program tears down and exits 0. A tutorial that stops working fails here rather
# than in front of a reader.
#
# add_test() rather than _add_test(): the root CMakeLists.txt shadows it only
# while this project is top-level, and by the time examples/ is added the
# suppression has already been lifted. An embedded build gets the builtin.
add_test(NAME example_sidescroller COMMAND sidescroller --frames 240 --autoplay)
set_tests_properties(example_sidescroller PROPERTIES TIMEOUT 120)
# set_property, not set_tests_properties: the latter parses its PROPERTIES
# arguments as name/value *pairs*, so a semicolon-separated value is split and
# every element after the first is consumed as a bogus property name. The
# audio and render entries of this very list were silently lost that way for
# as long as the list existed -- invisible on any machine whose real audio
# device works, and found the first time CI ran on a runner without one.
set_property(TEST example_sidescroller PROPERTY ENVIRONMENT
"SDL_VIDEODRIVER=dummy"
"SDL_RENDER_DRIVER=software"
"SDL_AUDIODRIVER=dummy"
)