From d9386a2f8ec3c4bd5ababc4eeb96ecd3e522b77c Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Fri, 27 Feb 2026 04:08:06 +0100 Subject: [PATCH] cmake: fix system include directory position for clang-tidy in tests To avoid a system include masking a custom directory, and e.g. picking up system OpenSSL headers from `/usr/include` on Linux, instead of the correct ones from a custom header directory, move system include directories to the back of the header path list. Also to match what CMake seems to be doing for the C compiler command-lines it generates. CMake seems to use `-I`, while for these invocations we stick with `-isystem` just in case. This area remains fragile and likely not the final issue. Fixing (seen in GHA/linux H3 c-ares): ``` Error while processing bld/tests/libtest/lib1521.c. /usr/include/openssl/macros.h:147:4: error: "OPENSSL_API_COMPAT expresses an impossible API compatibility level" [clang-diagnostic-error] Found compiler error(s). 147 | # error "OPENSSL_API_COMPAT expresses an impossible API compatibility level" | ^ FAILED: [code=1] tests/libtest/CMakeFiles/libtests-clang-tidy ``` Ref: https://github.com/curl/curl/actions/runs/22468472670/job/65079885471?pr=20751 Bug: https://github.com/curl/curl/pull/20751#issuecomment-3970180687 Cherry-picked from #20751 Closes #20759 --- CMake/Macros.cmake | 21 +++++++++++++++++++++ scripts/cmakelint.sh | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CMake/Macros.cmake b/CMake/Macros.cmake index 8d3458c06e..bf0ca1297f 100644 --- a/CMake/Macros.cmake +++ b/CMake/Macros.cmake @@ -139,6 +139,18 @@ macro(curl_add_clang_tidy_test_target _target_clang_tidy _target) set(_incsys "") set(_options "") + # Make a list of known system include directories + set(_sys_incdirs "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + foreach(_inc IN LISTS CMAKE_SYSTEM_PREFIX_PATH) + if(NOT _inc MATCHES "/$") + string(APPEND _inc "/") + endif() + string(APPEND _inc "include") + if(NOT _inc IN_LIST _sys_incdirs AND IS_DIRECTORY "${_inc}") + list(APPEND _sys_incdirs "${_inc}") + endif() + endforeach() + # Collect macro definitions and header directories applying to the directory get_directory_property(_val COMPILE_DEFINITIONS) if(_val) @@ -169,7 +181,12 @@ macro(curl_add_clang_tidy_test_target _target_clang_tidy _target) set(_incsys_tmp ${_incsys}) list(REMOVE_DUPLICATES _incsys_tmp) set(_incsys "") + set(_incsystop "") foreach(_inc IN LISTS _incsys_tmp) + if(_inc IN_LIST _sys_incdirs) + list(APPEND _incsystop "${_inc}") # Save system prefixes to re-add them later to the end of list + continue() + endif() # Avoid empty and '$' items. The latter # evaluates to an empty path in this context. Also skip # '$', as already present in '_includes'. @@ -179,6 +196,9 @@ macro(curl_add_clang_tidy_test_target _target_clang_tidy _target) list(APPEND _incsys "-isystem" "${_inc}") endif() endforeach() + foreach(_inc IN LISTS _incsystop) + list(APPEND _incsys "-isystem" "${_inc}") + endforeach() if(CMAKE_C_COMPILER_ID MATCHES "Clang") list(REMOVE_DUPLICATES _options) # Keep the first of duplicates to imitate CMake @@ -214,6 +234,7 @@ macro(curl_add_clang_tidy_test_target _target_clang_tidy _target) DEPENDS ${_sources}) add_dependencies(tests-clang-tidy ${_target_clang_tidy}) + unset(_sys_incdirs) unset(_cc) unset(_definitions) unset(_includes) diff --git a/scripts/cmakelint.sh b/scripts/cmakelint.sh index adf128556d..0927603375 100755 --- a/scripts/cmakelint.sh +++ b/scripts/cmakelint.sh @@ -72,8 +72,8 @@ cd "$(dirname "$0")"/.. --min-statement-spacing 1 \ --max-statement-spacing 2 \ --max-returns 6 \ - --max-branches 12 \ + --max-branches 15 \ --max-arguments 5 \ --max-localvars 15 \ - --max-statements 65 \ + --max-statements 85 \ --