使用CMake引入.so动态库编译通过但运行找不到库文件问题求助
问题根因
你遇到的是Linux运行时动态库查找失败问题,并非CMake构建链接阶段的错误:构建时你已经通过find_library找到了mylib.so的路径,所以链接过程可以正常完成,但Linux动态链接器默认不会扫描项目内的自定义lib目录,因此运行时无法定位到该库。
现有CMake配置的错误点
src/CMakeLists.txt中target_link_libraries直接写了mylib,没有使用find_library得到的${MYLIB_LIBRARIES}变量,导致链接时仅能通过默认路径和link_directories指定路径搜索库,无法匹配你自定义查找的结果link_directories使用相对路径./lib,子目录嵌套时容易出现路径解析错误,建议替换为绝对路径${PROJECT_SOURCE_DIR}/libtarget_include_directories引用了未定义的${DEP_INCLUDE_DIR}变量,没有正确引入你查找的三个依赖的头文件路径find_path和find_library没有指定优先搜索项目内路径,可能和系统中安装的同名库产生冲突
修复步骤
1. 修正构建配置
首先修改根目录CMakeLists.txt中mylib的查找逻辑,指定优先搜索项目内路径:
find_path(MYLIB_INCLUDE_DIR mylib/mylib.h PATHS ${PROJECT_SOURCE_DIR}/include NO_DEFAULT_PATH) find_library(MYLIB_LIBRARY NAMES mylib.so PATHS ${PROJECT_SOURCE_DIR}/lib NO_DEFAULT_PATH)
同时把link_directories的参数替换为绝对路径:
link_directories(${PROJECT_SOURCE_DIR}/lib)
然后修改src/CMakeLists.txt的配置:
add_executable(hello hello.cpp) target_link_libraries(hello lib1 lib2 ${CMAKE_THREAD_LIBS_INIT} ${JANSSON_LIBRARIES} ${CURL_LIBRARIES} ${MYLIB_LIBRARIES} ) target_include_directories(hello PUBLIC ${JANSSON_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${MYLIB_INCLUDE_DIRS} )
2. 解决运行时动态库查找问题
根据使用场景选择以下任意一种方案即可:
- 方案1:临时测试使用,运行前设置
LD_LIBRARY_PATH环境变量指向项目lib目录export LD_LIBRARY_PATH=/你的项目绝对路径/lib:$LD_LIBRARY_PATH ./hello - 方案2:本地开发推荐,CMake构建时给二进制文件嵌入运行时库搜索路径(RPATH)
在根目录CMakeLists.txt的add_subdirectory(src)之前添加以下配置:
配置完成后重新构建生成的二进制文件,可以直接运行无需额外设置。# 构建和安装时均保留项目lib目录的搜索路径 set(CMAKE_BUILD_RPATH "${PROJECT_SOURCE_DIR}/lib") set(CMAKE_INSTALL_RPATH "${PROJECT_SOURCE_DIR}/lib") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - 方案3:全局生效使用,将项目lib目录加入系统动态链接器配置
- 编辑
/etc/ld.so.conf.d/myproject-libs.conf,写入项目lib目录的绝对路径 - 执行
sudo ldconfig刷新动态链接缓存
- 编辑
验证方法
重新构建完成后执行ldd hello,即可看到mylib.so已经显示正确的路径,执行readelf -d hello | grep RPATH可以查看二进制文件嵌入的运行时搜索路径是否生效。
内容的提问来源于stack exchange,提问作者user2752148
相关产品推荐
相关产品推荐

