• 动态库的麻烦之处


    动态库的麻烦之处在于 - 如果你的程序使用了成百上千个动态库,你的程序在运行时如何找到这些动态库? 

    一般有三个方法:

    一、设置LD_LIBRARY_PATH

    export LD_LIBRARY_PATH="/path/to/lib"

    直接手工设是不可能完成的任务,因为你也知道有很多path (多不是问题,问题时你得知道这些path),所以一般需要在由编译系统来自动产生这些path,并放到一个runscript中:

    #set path
    export LD_LIBRARY_PATH=/path/to/lib1
    export LD_LIBRARY_PATH=/path/to/lib2:$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH=/path/to/lib3:$LD_LIBRARY_PATH
    # ...
    export LD_LIBRARY_PATH=/path/to/lib100:$LD_LIBRARY_PATH
    
    # run app
    /path/to/myapp

    二、设置rpath

    rpath设置可以在编译时:

    g++ -Wl,-rpath,/path/to/lib ...
    or
    ld -rpath /path/to/lib ...

    rpath应该可以是-L一致,所以可以在编译系统中做些工作自动产生rpath,premake目前(4.4beta)还不支持,但可以比较简单的做个扩展支持:(同时也展现了premake的灵活性)

    origin_libdirs = libdirs
    function libdirs(dirs) 
        origin_libdirs(dirs)
        if type(dirs) == 'string' then
            dirs = { dirs }
        end
        for _, dir in ipairs(dirs) do
            linkoptions('-Wl,-rpath,' .. dir)
        end
    end

    将libdirs都作为rpath编译到binary中去。

    可以通过readelf查看

    readelf -d binary

    而cmake则提供了比较好内建支持,有选项可以选择是否加入rpath。

    但是,你编译时的rpath并不代表就是你最终生产环境中的rpath,考虑一下continuous delivery中的一个情况:

    该项目有一个shared library和一个binary,在CI的build agent上编译产生,所以指向shared library的rpath是一个指向build agent上local的path,这些artifacts会被上传到artifact repository,然后在发布时被部署到生产环境中,此时该rpath必定是错误 --- 运行失败。

    此时需要postprocess来修改rpath,有个叫做patchelf的工具:

    patchelf --set-rpath /path/to/production/lib

    同样,怎么改rpath不是重点,重点是有哪些rpath,改成什么样 - 这些需要在build system在编译过程中收集。

    还可以去掉不需要的rpath:

    patchelf --shrink-rpath program

    三、拷贝或者symbolic link

    Windows下一般直接把所有dll打包放一起 - 与app同一目录,连PATH都不用设。

    Linux下我们可以把所有的library都symblic link到同一目录下,PATH只要设一个即可 - 这个在网络环境下尤其有用,之前这篇文章也讲到过。

  • 相关阅读:
    百度地图API显示多个标注点带百度样式信息检索窗口的代码
    百度地图API显示多个标注点并添加百度样式检索窗口
    百度地图API显示多个标注点并添加百度样式检索窗口
    生了一场闷气
    追求效率还是追求真理
    在VC++应用程序中读取文本数据
    一种创建子视图窗口的办法
    学会从已知推出未知
    unresolved external symbol __beginthreadex错误的解决——谈谈在Win32 Consle Application如何使用MFC类
    为何能在视图类能更新界面
  • 原文地址:https://www.cnblogs.com/baiyanhuang/p/3307926.html
Copyright © 2020-2023  润新知