diff --git a/CMakeLists.txt b/CMakeLists.txt index c314d66..0c6339c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,27 +29,43 @@ if(PROJECT_IS_TOP_LEVEL) libavr_format_test() # The behavioral tests drive the real wire protocols over a simavr pty - # (as the host tools do) and actually flash the device. The runners are - # host programs built at configure time against libsimavr (C++23 - what - # the distribution's compiler speaks in full); if they or Python are - # missing, only the size tests run. + # (as the host tools do) and actually flash the device. The runner is a + # host program built at configure time against libsimavr (C++23 - what the + # distribution's compiler speaks in full). + # + # **A host that cannot build it registers those tests anyway and skips + # them.** They used to be left out, which makes the suite a different size + # on a different machine - and a suite whose size is a property of the + # machine is one nothing can be compared against. + set(TSB_DEVICE ${CMAKE_BINARY_DIR}/tsb_device) find_program(_host_cxx NAMES c++ g++) - find_package(Python3 COMPONENTS Interpreter) - if(_host_cxx AND Python3_FOUND) - if(LIBAVR_MCU STREQUAL "atmega328p") - set(TSB_DEVICE ${CMAKE_BINARY_DIR}/tsb_device) - execute_process( - COMMAND ${_host_cxx} -std=c++23 -Wall -Wextra -O2 - -I/usr/include/simavr -I/usr/include/simavr/parts - -o ${TSB_DEVICE} ${CMAKE_CURRENT_SOURCE_DIR}/test/device.cpp - -lsimavr -lsimavrparts -lelf - RESULT_VARIABLE _dev_res ERROR_VARIABLE _dev_err) - if(NOT _dev_res EQUAL 0) - message(STATUS "tsb_device not built (${_dev_err}) - protocol tests skipped") - unset(TSB_DEVICE) + set(_tsb_absent "${LIBAVR_NO_PYTHON}") + if(NOT _host_cxx) + set(_tsb_absent "no host C++ compiler on PATH, and the simavr device is a host program") + elseif(NOT _tsb_absent) + execute_process( + COMMAND ${_host_cxx} -std=c++23 -Wall -Wextra -O2 + -I/usr/include/simavr -I/usr/include/simavr/parts + -o ${TSB_DEVICE} ${CMAKE_CURRENT_SOURCE_DIR}/test/device.cpp + -lsimavr -lsimavrparts -lelf + RESULT_VARIABLE _dev_res ERROR_VARIABLE _dev_err) + if(NOT _dev_res EQUAL 0) + # One bounded line of it: this becomes a single argument on a + # command line, and the reading has to say what stopped the build + # rather than that something did. + string(REGEX REPLACE "[\r\n\t]+" " " _dev_err "${_dev_err}") + string(REPLACE ";" "," _dev_err "${_dev_err}") + string(LENGTH "${_dev_err}" _dev_len) + if(_dev_len GREATER 240) + string(SUBSTRING "${_dev_err}" 0 240 _dev_err) endif() + set(_tsb_absent "test/device.cpp does not build here: ${_dev_err}") endif() endif() + libavr_launcher(_tsb_python "${_tsb_absent}" ${Python3_EXECUTABLE}) + if(_tsb_absent) + message(STATUS "the protocol tests skip here - ${_tsb_absent}") + endif() endif() # The ELF is only a container (symbols, section headers) and is never flashed - @@ -114,11 +130,9 @@ function(add_tsb_variant name bytes) add_test(NAME ${name}.size COMMAND ${CMAKE_COMMAND} -DSIZE_TOOL=${CMAKE_SIZE} -DELF=$ -DLIMIT=${bytes} -P ${CMAKE_CURRENT_SOURCE_DIR}/test/check_size.cmake) - if(DEFINED TSB_DEVICE) - add_test(NAME ${name}.protocol - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/tsbtest.py - ${TSB_DEVICE} $ ${base_hex}) - endif() + add_test(NAME ${name}.protocol + COMMAND ${_tsb_python} ${CMAKE_CURRENT_SOURCE_DIR}/test/tsbtest.py + ${TSB_DEVICE} $ ${base_hex}) endif() endfunction() @@ -135,3 +149,9 @@ if(LIBAVR_MCU STREQUAL "atmega328p") # floors were measured with - none. target_compile_options(tsb_policy PRIVATE -fno-move-loop-invariants -fno-tree-ter) endif() + +# Every test registered above carries the marker a stubbed launcher prints, so +# a check this host cannot run reads as Skipped rather than Failed. +if(PROJECT_IS_TOP_LEVEL) + libavr_skip_unverified() +endif() diff --git a/libavr b/libavr index b62d6b5..8521f48 160000 --- a/libavr +++ b/libavr @@ -1 +1 @@ -Subproject commit b62d6b5b30b1122128b1d277c715f92aeb2abcff +Subproject commit 8521f48a3361100c5f3e3c5004a5ff415e2d1484