Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions