[BUG]ENABLE_ASAN 开启但本机缺少 libasan 时,CMake 会误报找不到 Threads
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 4.4k
- Forks
- 1.6k
- PR merge metrics
- No merged PRs in 30d
Description
ENABLE_ASAN 开启但本机缺少 libasan 时,CMake 会误报找不到 Threads
问题概述
在 Fedora + GCC 15 环境下执行:
bash build.sh
CMake 配置阶段可能会失败,并报错:
Could NOT find Threads (missing: Threads_FOUND)
但实际问题并不是系统缺少 pthread。查看
build_debug/CMakeFiles/CMakeConfigureLog.yaml 后可以发现,真正的链接错误是
AddressSanitizer 运行库不可用:
/usr/bin/ld: 找不到 /usr/lib64/libasan.so.8.0.0: 没有那个文件或目录
collect2: 错误:ld 返回 1
MiniOB 默认开启 ENABLE_ASAN,并且在调用
find_package(Threads REQUIRED) 之前,就把 -fsanitize=address 添加到了
CMAKE_C_FLAGS / CMAKE_CXX_FLAGS 中。因此 CMake 内部用于检测 Threads 的
try-compile 也会带上 ASAN 参数。
如果当前系统的 GCC/ASAN 运行库不匹配,或者缺少对应的 libasan 文件,
Threads 检测就会因为 ASAN 链接失败而失败,最终给用户展示成一个比较误导的
Threads_FOUND 错误。
环境信息
操作系统:Fedora Linux
CMake:3.31.11
GCC/G++:15.2.1
构建命令:bash build.sh
构建类型:debug
ENABLE_ASAN:ON
复现步骤
直接执行:
bash build.sh
观察到的输出:
-- Instrumenting with Address Sanitizer
-- CMAKE_CXX_FLAGS is -Wall -Werror -Wno-error=sign-compare -DDEBUG -g -O0 -fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope
-- Using replxx for line reading
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:233 (message):
Could NOT find Threads (missing: Threads_FOUND)
Call Stack (most recent call first):
/usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:603 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake/Modules/FindThreads.cmake:226 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:178 (FIND_PACKAGE)
而 build_debug/CMakeFiles/CMakeConfigureLog.yaml 中的真实错误是:
/usr/bin/ld: 找不到 /usr/lib64/libasan.so.8.0.0: 没有那个文件或目录
期望行为
如果当前编译器环境无法正常链接 AddressSanitizer,CMake 应该给出更直接的
ASAN 相关提示,而不是误报 Could NOT find Threads。
例如可以提示:
Address Sanitizer is not available with the current compiler setup.
Please install the matching libasan package or configure with -DENABLE_ASAN=OFF.
或者在检测到 ASAN 不可用时,自动关闭 ENABLE_ASAN 并继续配置。
可能的修复方式
可以在真正把 -fsanitize=address 追加到全局编译参数之前,先用一个最小程序
检测当前编译器是否能够正常编译并链接 ASAN:
IF (ENABLE_ASAN)
INCLUDE(CheckCXXSourceCompiles)
SET(CMAKE_REQUIRED_FLAGS_SAVED "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fsanitize=address")
CHECK_CXX_SOURCE_COMPILES("int main() { return 0; }" COMPILER_SUPPORTS_ASAN)
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS_SAVED}")
ENDIF()
IF (ENABLE_ASAN AND NOT COMPILER_SUPPORTS_ASAN)
MESSAGE(WARNING "Address Sanitizer is not available with the current compiler setup. Disable ENABLE_ASAN or install the matching libasan package.")
SET(ENABLE_ASAN OFF CACHE BOOL "Enable build with address sanitizer" FORCE)
ENDIF()
这样当 ASAN 不可用时,用户可以看到明确的 ASAN 提示;同时
find_package(Threads REQUIRED) 不会因为继承了不可用的 ASAN 参数而失败。
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read CMakeLists.txt around the find_package(Threads REQUIRED) call and the ENABLE_ASAN setup, then reproduce with bash build.sh using ASAN enabled. Check the configure output and build_debug/CMakeFiles/CMakeConfigureLog.yaml when libasan is unavailable. Done means the configuration reports the ASAN problem directly or disables ASAN, without misreporting a Threads failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cmake, cpp
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100