[ubuntu]环境变量+动态库链接+多版本切换

[ubuntu]环境变量+动态库链接+多版本切换

  • 1. 基础知识
  • 2.Makefile下指定库版本(以Opencv为例)
  • 3. CMake下指定库版本(以OpenCV为例)
  • 4. 总结(以OpenCV为例)

1. 基础知识

  • 环境变量配置文件
    /etc/profile
    用于设置系统级的环境变量和启动程序,在这个文件下配置会对所有用户生效。当用户登录(login)时,文件会被执行,并从/etc/profile.d目录的配置文件中查找shell设置。如果对/etc/profile修改的话必须重启才会生效
    /etc/bash.bashrc
    每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取。如果想对所有使用bash的用户修改某个配置并在以后打开的bash都生效的话可以修改这个文件,修改之后不用重启,重新打开一个bash即可生效。
    ~/.profile
    每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件.
    ~/.bashrc
    该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取.
    ~/.bash_logout
    当每次退出系统(退出bash shell)时,执行该文件,通常存放清理工作的命令。
    执行顺序
    登陆shell
      登陆shell时,首先执行/etc/profile,之后执行用户目录下的~/.profile,在~/.profile中会执行~/.bashrc。
    交互式非登陆shell
      首先执行/etc/bash.bashrc,之后执行~/.bashrc

  • 动态库搜索路径优先顺序
    1. 编译目标代码时指定的动态库搜索路径;
    2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
    (但是,有不少声音主张要避免使用 LD_LIBRARY_PATH 变量,尤其是作为全局变量);
    3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径;//配置后要运行 ldconfig命令才能生效
    4. 默认的动态库搜索路径/lib和/usr/lib;

  • /etc/ld.so.conf 文件
      记录了编译时使用的动态库的路径,也就是加载so库的路径。
      /etc/ld.so.conf文件中有一句include ld.so.conf.d/*.conf,它把ld.so.conf.d 文件夹下所有conf文件中路径加载到 ld.so.conf 中。

  • 默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件。因此若在用源码安装时,未使用--prefix指定安装路径为/usr/lib,就会报找不到相关的.so库的错误。

  • ldconfig 程序
      动态链接库的管理命令,位于/sbin下,其作用是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用。在默认搜寻目录/lib和/usr/lib以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件,缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。
      linux下的共享库机制采用了类似高速缓存机制,将库信息保存在/etc/ld.so.cache,程序连接的时候首先从这个文件里查找,然后再到ld.so.conf的路径中查找
       因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新的搜索路径,为了让动态链接库为系统所共享,需要运行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,可能会找不到刚安装的库。

  • LIBRARY_PATH环境变量用于在程序编译期间查找动态链接库时指定查找共享库的路径
    LD_LIBRARY_PATH环境变量用于在程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径

  • pkg-config 是一个linux下的命令,用于获得某一个库/模块的所有编译相关的信息。其信息来源:
      1. 取系统的/usr/lib下的所有*.pc文件。
      2. PKG_CONFIG_PATH环境变量所指向的路径下的所有*.pc文件。

    1. 查看 opencv 依赖的头文件路径:
      pkg-config --cflags opencv
      
    2. 查看 opencv 依赖的库文件路径:
      pkg-config --libs opencv
      
    3. 查看 opencv 版本:
      pkg-config --modversion  opencv
      

2.Makefile下指定库版本(以Opencv为例)

当安装一个库时(例如从 RPM,deb 或其他二进制包管理系统),会包括一个后缀名为 pc 的文件,它会放入某个文件夹下(依赖于你的系统设置)。

  1. 对未指定–prefix目录的情况,此时默认安装位置为/usr/local目录,
    —> 直接将路径/usr/local/lib路径加入到文件/etc/ld.so.conf文件的中,在其末尾直接添加:/usr/local/lib
  2. 对指定–prefix为其他目录的情况(非/usr/local或/usr)时,将其生成的.pc文件中libdir变量值加入对应的/etc/ld.so.conf.d/*.conf文件中(对多版本安装的库,要将所有版本库的libdir变量值都加入进去)。
    /etc/ld.so.conf/etc/ld.so.conf.d/opencv.conf如下所示:
    [ubuntu]环境变量+动态库链接+多版本切换_第1张图片[ubuntu]环境变量+动态库链接+多版本切换_第2张图片
  3. 将要选择版本的库的.pc文件所在目录添加到PKG_CONFIG_PATH变量
    # 在.bashrc文件中添加
    # opencv3.4.3
    export PKG_CONFIG_PATH=/usr/local/cv/cv3_4_3/lib/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
    
    或 通过更改.pc文件(更改内容或备份)实现版本选择。
  4. 执行sudo ldconfig

3. CMake下指定库版本(以OpenCV为例)

在opencv编译好后,所在目录中一般会有一个叫OpenCVConfig.cmake的文件,这个文件中指定了CMake要去哪里找OpenCV,指定了Opencv的所有路径。
因此设置OpenCV_DIR为包含OpenCVConfig.cmake的目录即可切换opencv版本:

  • 法1> 在CMakeLists.txt中设置OpenCV_DIR
    在CMakeLists.txt中,将set(OpenCV_DIR "/home/ubuntu/src/opencv-3.1.0/build")添加在project(MyProjectName)之前:
    set(OpenCV_DIR "/usr/local/cv/cv3_4_3/share/OpenCV")
    project(MyProjectName)
    find_package( OpenCV REQUIRED )
    
  • 法2>
  1. .bashrc中设置OpenCV_DIR
    # 在.bashrc中添加
    export OpenCV_DIR=/usr/local/cv/cv3_4_3/share/OpenCV
    # 其中路径为对应版本中`OpenCVConfig.cmake`文件所在目录
    
  2. 此时CMakeLists.txt中就不必设置OpenCV_DIR了:
    project(MyProjectName)
    find_package( OpenCV REQUIRED )
    

4. 总结(以OpenCV为例)

对于多版本管理:

  • 安装时设置:2.2,2.3,2.4,3.法2.1
  • 系统环境设置:2.3,3.法2.1
  • cmake工程设置:3.法1,3.法2.2

参考:
Ubuntu下多个版本OpenCV管理(Multiple Opencv version)
/etc/ld.so.conf详解
pkg-config 查询已安装库的相关信息
关于/etc/ld.so.conf.d/和环境变量设置
Linux环境变量LD_LIBRARY_PATH
linux下LD_LIBRARY_PATH介绍

你可能感兴趣的:(ubuntu,linux)