为什么 FindBacktrace 没有链接 libbacktrace?
结论
Backtrace_LIBRARY 为空,通常是因为 CMake 检测到系统默认库已经提供 backtrace(3),不需要额外链接库。FindBacktrace 检查的是 backtrace(3) 接口,不会因此找到或链接提供 backtrace_create_state 和 backtrace_pcinfo 的 GCC libbacktrace。两者属于不同的接口,使用的头文件也不同。CMake 文档将 Backtrace_LIBRARY 定义为提供 backtrace(3) 的外部库,并说明该变量可能为空。CMake FindBacktrace 文档
为什么缓存变量是空的
问题中的缓存内容是:
//Library providing backtrace(3), empty for default set of libraries
Backtrace_LIBRARY:FILEPATH=
在这台机器上,CMake 检测到默认链接库已提供 backtrace(3),因此没有把外部库路径写入 Backtrace_LIBRARY。GNU libc 提供 execinfo.h 中声明的 backtrace 等接口。在这种情况下,链接时没有额外库可填是正常的。GNU libc 调试支持文档
libbacktrace 提供另一套 API,声明在 backtrace.h 中,例如 backtrace_create_state 和 backtrace_pcinfo。GCC libbacktrace 头文件 因此,find_package(Backtrace) 的结果无法说明 libbacktrace 是否已安装,也不会自动添加 -lbacktrace。
如何链接 libbacktrace
如果项目调用了 libbacktrace 的接口,可以单独查找它的头文件和库,再将它们添加到目标上:
find_path(LIBBACKTRACE_INCLUDE_DIR
NAMES backtrace.h
)
find_library(LIBBACKTRACE_LIBRARY
NAMES backtrace
)
if(NOT LIBBACKTRACE_INCLUDE_DIR OR NOT LIBBACKTRACE_LIBRARY)
message(FATAL_ERROR "libbacktrace headers or library were not found")
endif()
target_include_directories(app PRIVATE "${LIBBACKTRACE_INCLUDE_DIR}")
target_link_libraries(app PRIVATE "${LIBBACKTRACE_LIBRARY}")
将 app 替换为项目中的实际目标名。如果库或头文件安装在非标准位置,可以通过 LIBBACKTRACE_INCLUDE_DIR 和 LIBBACKTRACE_LIBRARY 指定路径。还需确认找到的 backtrace.h 是目标平台提供的 libbacktrace 头文件,而不是其他同名文件。
不要为了得到 -lbacktrace 就把 libbacktrace 填入 Backtrace_LIBRARY。FindBacktrace 使用该变量检测 backtrace(3),填入它不能确保 libbacktrace 的 API 和头文件配置正确。
如果项目使用 Boost.Stacktrace
先确认所选 Boost.Stacktrace 后端需要哪些接口,再按后端要求配置依赖。FindBacktrace 的检测结果只说明 backtrace(3) 是否可用,无法单独证明 Boost.Stacktrace 已启用或已链接 libbacktrace。
备注:内容仅供参考。
