Skip to content

[BUG]ENABLE_ASAN 开启但本机缺少 libasan 时,CMake 会误报找不到 Threads #640

@123kaze

Description

@123kaze

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 参数而失败。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions