From d8cfdc904a954c98df61be627e6cee14f26735f8 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Fri, 28 Aug 2026 14:50:30 +0000 Subject: [PATCH] Warn when JSON_TestSimdutf cannot reach the simdutf backend simdutf needs C++17: without it the dependency does not even compile, and with a C++17 compiler but no C++17-or-later standard under test it builds and then goes unused. Either way the option silently did nothing useful, or broke the configure step outright. Resolve the tested standards first, then check them: when none of them can reach simdutf, skip the dependency and say so, naming which of the two reasons applies and how to fix it. The tests then run against the scalar validator, which is what would have happened anyway. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01MXDi7NTMKAmoArUZSKMc4T Signed-off-by: Niels Lohmann --- tests/CMakeLists.txt | 102 +++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 37 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2b873936a..48a4fd8b0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -91,43 +91,6 @@ target_include_directories(test_main PUBLIC ${PROJECT_BINARY_DIR}/include) target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME}) -############################################################################# -# optionally validate UTF-8 with simdutf (JSON_USE_SIMDUTF) -############################################################################# - -# The simdutf backend is opt-in and not vendored, so it is fetched here rather -# than being a checked-in dependency. Everything below hangs off test_main, -# whose usage requirements every test target inherits; the library target and -# the installed CMake package are deliberately left untouched. -if (JSON_TestSimdutf) - if (CMAKE_VERSION VERSION_LESS 3.18) - message(FATAL_ERROR "JSON_TestSimdutf requires CMake 3.18 or later (simdutf's minimum).") - endif() - - include(FetchContent) - - # simdutf builds its tests and tools by default, and its tests pull further - # dependencies of their own; only the library itself is needed here - set(SIMDUTF_TESTS OFF CACHE BOOL "" FORCE) - set(SIMDUTF_TOOLS OFF CACHE BOOL "" FORCE) - set(SIMDUTF_BENCHMARKS OFF CACHE BOOL "" FORCE) - set(SIMDUTF_ICONV OFF CACHE BOOL "" FORCE) - - FetchContent_Declare(simdutf - URL https://github.com/simdutf/simdutf/archive/refs/tags/v${JSON_SIMDUTF_VERSION}.tar.gz - DOWNLOAD_EXTRACT_TIMESTAMP TRUE - ) - FetchContent_MakeAvailable(simdutf) - - target_compile_definitions(test_main PUBLIC JSON_USE_SIMDUTF) - target_link_libraries(test_main PUBLIC simdutf::simdutf) - - # simdutf.h requires C++17; below that the library keeps its scalar - # validator, so the C++11/14 test targets exercise the fallback and the - # C++17-and-later ones exercise simdutf. Both must agree. - message(STATUS "UTF-8 validation delegated to simdutf ${JSON_SIMDUTF_VERSION} for C++17 and later (JSON_USE_SIMDUTF)") -endif() - ############################################################################# # define test- and standard-specific build settings ############################################################################# @@ -189,6 +152,71 @@ if(test_force) endif() message(STATUS "${msg}") +############################################################################# +# optionally validate UTF-8 with simdutf (JSON_USE_SIMDUTF) +############################################################################# + +# The simdutf backend is opt-in and not vendored, so it is fetched here rather +# than being a checked-in dependency. Everything below hangs off test_main, +# whose usage requirements every test target inherits; the library target and +# the installed CMake package are deliberately left untouched. +if (JSON_TestSimdutf) + # simdutf requires C++17, both to compile itself and to be reachable from + # the library, which keeps its scalar validator below that. Find a tested + # standard that satisfies it. + set(simdutf_standard "") + foreach(cxx_standard ${test_cxx_standards}) + if(NOT cxx_standard LESS 17 AND compiler_supports_cpp_${cxx_standard}) + set(simdutf_standard ${cxx_standard}) + break() + endif() + endforeach() + + if("${simdutf_standard}" STREQUAL "") + # Building simdutf would fail outright without a C++17 compiler, and + # even with one it would go unused if no C++17-or-later standard is + # tested. Say so and fall back to the scalar validator rather than + # failing the build. + if(NOT compiler_supports_cpp_17) + set(simdutf_reason "the compiler does not support C++17") + else() + set(simdutf_reason "no tested standard is C++17 or later (testing ${msg_standards})") + endif() + message(WARNING + "JSON_TestSimdutf is enabled, but ${simdutf_reason}. simdutf requires C++17, so it " + "is not fetched and JSON_USE_SIMDUTF is not defined: the tests run against the " + "built-in scalar UTF-8 validator instead. Set JSON_TestStandards to include 17 or " + "later, or build with a compiler that supports C++17.") + else() + if (CMAKE_VERSION VERSION_LESS 3.18) + message(FATAL_ERROR "JSON_TestSimdutf requires CMake 3.18 or later (simdutf's minimum).") + endif() + + include(FetchContent) + + # simdutf builds its tests and tools by default, and its tests pull + # further dependencies of their own; only the library is needed here + set(SIMDUTF_TESTS OFF CACHE BOOL "" FORCE) + set(SIMDUTF_TOOLS OFF CACHE BOOL "" FORCE) + set(SIMDUTF_BENCHMARKS OFF CACHE BOOL "" FORCE) + set(SIMDUTF_ICONV OFF CACHE BOOL "" FORCE) + + FetchContent_Declare(simdutf + URL https://github.com/simdutf/simdutf/archive/refs/tags/v${JSON_SIMDUTF_VERSION}.tar.gz + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + FetchContent_MakeAvailable(simdutf) + + target_compile_definitions(test_main PUBLIC JSON_USE_SIMDUTF) + target_link_libraries(test_main PUBLIC simdutf::simdutf) + + # simdutf.h requires C++17; below that the library keeps its scalar + # validator, so any C++11/14 test targets exercise the fallback and the + # C++17-and-later ones exercise simdutf. Both must agree. + message(STATUS "UTF-8 validation delegated to simdutf ${JSON_SIMDUTF_VERSION} for C++17 and later (JSON_USE_SIMDUTF)") + endif() +endif() + # *DO* use json_test_set_test_options() above this line json_test_should_build_32bit_test(json_32bit_test json_32bit_test_only "${JSON_32bitTest}")