如何使用CMake链接自定义.so动态库 解决未定义引用链接报错
错误原因分析
你遇到的链接错误主要由两个问题导致:
- C/C++混编符号不匹配:
libbasic.so是C语言编译的动态库,函数符号是C风格的无修饰格式;而Google Test用例是C代码,直接引用basic.h时,C编译器会对函数名做名字修饰(包含参数类型信息),导致最终查找的符号和动态库中实际的符号不匹配。 - CMake配置错误:根目录CMakeLists中先引入test子目录、后定义Example静态库,导致test目标无法正确继承Example的链接配置;同时
link_directories使用了相对路径,可能找不到动态库位置。
修复步骤
1. 修复basic.h的C/C++兼容配置
修改basic.h,添加extern "C"条件编译块,保证C++编译时生成C风格的符号引用:
#ifndef BASIC_H #define BASIC_H #ifdef __cplusplus extern "C" { #endif int add(int a, int b); int sub(int a, int b); #ifdef __cplusplus } #endif #endif
2. 调整根目录CMakeLists.txt配置
调整子目录引入顺序,修正路径错误,同时给Example库的链接配置添加PUBLIC属性,让依赖Example的目标可以继承链接参数:
cmake_minimum_required(VERSION 3.8) set(This Example) # 合并project声明,指定编译语言 project(${This} C CXX) set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 11) set(CMAKE_POSITION_INDEPENDENT_CODE ON) enable_testing() add_subdirectory(googletest) set(Headers Example.hpp ) set(Sources Example.cpp ) # 先定义Example静态库 add_library(${This} STATIC ${Sources} ${Headers}) # 修正为绝对路径 link_directories(/home/eylon/) # 添加PUBLIC属性,让依赖Example的目标自动继承libbasic的链接配置 target_link_libraries(${This} PUBLIC basic) # 库定义完成后再引入test子目录 add_subdirectory(test)
3. 可选:验证运行时库路径
编译通过后如果运行测试时提示找不到libbasic.so,执行测试命令前添加库路径前缀即可:
LD_LIBRARY_PATH=/home/eylon ./build/test/ExampleTests
内容的提问来源于stack exchange,提问作者Eylon Ben Simon
相关产品推荐
相关产品推荐

