通过cmake编译链接动态库后,会有一个问题,那就是需要的.so文件不能更改目录,一旦.so文件目录变了,整个程序就没法运行了,这肯定是不行的。

原因

后来我查一下一下,linux系统中,程序加载运行需要的.so文件是有顺序的

  1. 环境变量LD_LIBRARY_PATH指定的路径
  2. gcc 编译时指定的运行时库路径-rpath
  3. ldconfig 配置文件ld.so.conf指定的路径
  4. 系统默认库位置 /lib, /usr/lib

如果没有指定so的位置,gcc会自动把当前so所在的目录作为so的连接目录。知道原因了,问题就好解决了

解决办法

先看一下现在的 CMakeLists.txt文件

cmake_minimum_required(VERSION 3.13.3)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_library(shared SHARED library.h library.c)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

add_executable(project1 main.c)

target_link_libraries(project1 shared)

我实验了两种办法,一是把.so 文件放到/lib 或者 /usr/lib中,这也是在安装很多软件时的做法,当使用包管理器安装软件时,需要的.so文件大多是安装到这两个目录下。在一种就是在编译时指定 rpath的目录,使用相对目录,这样在复制文件的时候,把.so一起复制就可以了。

先用最简单的办法,把so目录放到系统目录下
 

 

现在的目录结构如下,程序依赖的libshared.solib 目录下,现在把 libshared.so 复制到 /lib 目录下。这里有个要注意的地方,复制完后要执行 ldconfig 命令,重新生成缓存,要不然程序依然找不到对应的.so文件
命令如下

  1. sudo mv lib/libshared.so /lib
  2. sudo ldconfig

这时候在运行 project1 不会报错

编译时指定 rpath目录

设置 rpaht 有两种方式

方式1

set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH $ORIGIN)

通过修改编译后的 install 路径, 让程序在运行时通过程序的相对目录加载.so文件,其中 $ORIGIN 变量是程序的当前目录

方式2

set_target_properties(project1 PROPERTIES LINK_FLAGS "-Wl,-rpath,./")

方式2更粗暴,直接设置gcc的编译参数,指定rpaht 是当前目录

修改 CMakeLists.txt文件

cmake_minimum_required(VERSION 3.13.3)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_library(shared SHARED library.h library.c)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

#方式1
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH $ORIGIN)

add_executable(project1 main.c)

#方式2
#set_target_properties(project1 PROPERTIES LINK_FLAGS "-Wl,-rpath,./")
target_link_libraries(project1 shared)

重新生成 MakeFile 文件, 然后编译

编译生成的 libshared.so 还是在 lib目录下,先移动到可执行文件的同级目录下

 

 

 

最终目录如图,现在无论怎么复制文件,只要可执行文件和动态库在一个目录下,都以运行了

总结

解决linux下 动态编译的程序找不到动态库的问题,有多种解决办法,这次用了两种

  1. 把需要的.so文件放到 /lib 或者 /usr/lib 下, 然后执行 ldconfig命令
  2. 通过指定 rpath 来决定加载 .so的目录

ref:https://www.jianshu.com/p/9b086881c423

原文地址:http://www.cnblogs.com/lidabo/p/16916183.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性