如何链接CMake add_subdirectory生成的so文件?编译报错求助
CMake链接子目录动态库失败的解决方案
项目结构
├── CMakeLists.txt ├── main.cpp └── plugins ├── CMakeLists.txt ├── plugin.cpp └── plugin.h
现有配置与代码
顶层CMakeLists.txt
# top-level CMakeLists.txt CMAKE_MINIMUM_REQUIRED(VERSION 3.22) PROJECT(example) add_subdirectory(./plugins/) add_executable(main main.cpp) target_include_directories(main PUBLIC ./plugins/) target_link_libraries(main -lplugin)
plugins/CMakeLists.txt
add_library(plugin SHARED plugin.cpp)
代码实现
// main.cpp #include <iostream> #include "plugin.h" int call() { using namespace std; cout << "call\n"; func(); } int main() { call(); return 0; } // plugins/plugin.cpp #include <iostream> void func() { using namespace std; cout << "plugin\n"; } // plugins/plugin.h void func();
编译错误
make[2]: *** No rule to make target 'plugins/libplugin.so', needed by 'main'. Stop. make[1]: *** [CMakeFiles/Makefile2:100: CMakeFiles/main.dir/all] Error 2 make: *** [Makefile:91: all] Error 2
问题根源
你用-lplugin手动指定链接库的方式是错误的:
- CMake在子目录生成的库文件默认会输出到构建目录(比如
build/plugins/),而非源码目录的plugins/下,因此找不到plugins/libplugin.so。 - CMake通过目标名称管理依赖,不需要手动加
-l前缀,直接引用子目录中add_library定义的plugin目标即可,CMake会自动处理库的路径、链接顺序等细节。
修复方案
修改顶层CMakeLists.txt中的target_link_libraries行,将-lplugin替换为plugin:
# 修改后的顶层CMakeLists.txt CMAKE_MINIMUM_REQUIRED(VERSION 3.22) PROJECT(example) add_subdirectory(./plugins/) add_executable(main main.cpp) target_include_directories(main PUBLIC ./plugins/) # 直接引用CMake目标名称,无需-l前缀 target_link_libraries(main plugin)
可选优化(按需添加)
如果希望动态库输出到源码目录的plugins/下,可在plugins/CMakeLists.txt中添加以下配置:
add_library(plugin SHARED plugin.cpp) # 指定库输出目录 set_target_properties(plugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/plugins )
验证步骤
- 删除原有构建目录(若存在):
rm -rf build/ - 重新构建:
mkdir build && cd build cmake .. make
此时可执行文件main会正常编译链接,运行后输出:
call plugin
内容的提问来源于stack exchange,提问作者coin cheung
相关产品推荐
相关产品推荐

