使用CMake链接外部C++库报错:库未找到或未定义引用问题求助
问题核心原因
你的错误分为CMake语法错误、逻辑配置错误、链接缺失三类,具体如下:
- CMake语法错误:变量定义错误使用
${}包裹硬编码路径、$ENV{}是用来读取系统环境变量的,你直接写绝对路径不需要加这个关键字、导入库的IMPORTED_LOCATION属性只写了目录没指定具体.a库文件、configure和lifu两个库错误把.cpp源文件当成库文件导入。 - 逻辑配置错误:可执行文件对应的
Delta_wrap_test.cpp里没有main函数、已经有预编译好的静态库还额外抓poslib的源文件编译属于冗余操作、所有pos相关的导入库都没有加到链接列表里。 - 冗余配置:重复添加了多次头文件目录和链接目录,还错误用
${}包裹导入库目标名。
修复方案
1. 修正变量定义
把原有变量定义部分替换为以下内容,去掉多余的语法错误:
# 统一设置pos库根路径,后续修改更方便 set(POS_ROOT /mnt/d/pos/positioner) set(POSLIB_DIR ${POS_ROOT}/poslib) set(DATA_DIR ${POS_ROOT}/data) set(PLATE_GEN_DIR ${POS_ROOT}/plate_gen) set(CONFIGURE_DIR ${POS_ROOT}/configure) set(LIFU_DIR ${POS_ROOT}/lifu_configure) set(POS_BUILD_DIR ${POS_ROOT}/build) # 修正Boost配置,去掉错误的$ENV set(BOOST_INCLUDEDIR /home/name/boost_1_77_0) set(BOOST_LIBRARYDIR /usr/lib/x86_64-linux-gnu)
2. 移除冗余错误代码
- 删掉
file(GLOB poslib_Sources ...)和file(GLOB poslib_h_Sources ...)两行,你用预编译静态库不需要编译库的源文件。 - 删掉
configure、lifu两个错误的导入库配置,如果确实需要这两个库,先去${POS_BUILD_DIR}下找到对应的.a静态库文件,再按照下方正确的导入库写法配置。
3. 正确配置导入静态库
add_library(poslib STATIC IMPORTED GLOBAL) set_target_properties(poslib PROPERTIES IMPORTED_LOCATION ${POS_BUILD_DIR}/poslib/libposlib.a) add_library(data STATIC IMPORTED GLOBAL) set_target_properties(data PROPERTIES IMPORTED_LOCATION ${POS_BUILD_DIR}/data/libconfig_files_resource.a) add_library(plate_gen STATIC IMPORTED GLOBAL) set_target_properties(plate_gen PROPERTIES IMPORTED_LOCATION ${POS_BUILD_DIR}/plate_gen/libplate_files_resource.a) add_library(sofa STATIC IMPORTED GLOBAL) set_target_properties(sofa PROPERTIES IMPORTED_LOCATION /home/name/sofa/20210512/c/src/libsofa.a)
4. 修正可执行文件配置
首先确认Delta_wrap_test.cpp里存在main函数,没有的话补充:
int main(int argc, char* argv[]) { // 你的测试逻辑 return 0; }
然后修正可执行文件定义:
add_executable(delta_wrap_test Delta_wrap_test.cpp)
5. 补充缺失的链接库
把所有pos相关库加到target_link_libraries中:
target_link_libraries(delta_wrap_test poslib data plate_gen sofa ${Boost_LIBRARIES} Qt5::Core Qt5::Widgets Qt5::Xml Qt5::PrintSupport Qt5::Gui Threads::Threads )
6. 重新构建
删除原Build目录下所有缓存文件,重新执行构建命令:
cd Build rm -rf ./* cmake .. make -j$(nproc)
补充排查建议
- 如果还是报pos命名空间符号未定义,先确认定制库的编译C标准和你项目的一致,比如库是用C11编译的,你把
CMAKE_CXX_STANDARD改成11再试,避免ABI不兼容问题。 - 用
ls命令确认所有.a静态库的路径真实存在,比如ls ${POS_BUILD_DIR}/poslib/libposlib.a可以正常输出文件信息。 - 如果出现符号未定义顺序相关的错误,调整
target_link_libraries里的库顺序,依赖其他库的库放在前面,被依赖的库放在后面。
内容的提问来源于stack exchange,提问作者S.H
相关产品推荐
相关产品推荐

