• linux指定动态运行库的位置


      动态运行库在windows、linux下均广泛使用。windows下通常为dll文件,linux下为so文件。不过,对于部署程序,这两个系统查找依赖的运行库文件时却不一样。对于windows而言,优先查找当前目录下,然后再到系统库文件C:windowssystem32(记不太清楚,好像是这个位置)下查找。这个特性极大的方便了程序的部署,程序员只需要把相关的dll打包就OK,这也让很多程序可以制作成绿色版。而在linux下,默认只到/lib、/usr/lib和/usr/local/lib查找,找不到程序将无法启动。

      对于windows的方式,好处显而易见,就是方便部署。缺点也有,安全性不高。想想有那么多dll是通用的,我随便写个同名的扔到程序当前目录下,不就把程序劫持了么。不过,这个缺点在日常应用中显得不是很重要。大部分人下软件安装时根本不会注意软件安装了什么文件,只要杀毒软件不报就OK。而相对于程序员而言,这种部署也极大的方便了调试。我不太方便去改/usr/lib里的东西。

      要想linux下的程序在当前目录下查找动态运行库文件,如果是固定路径,则可以通过修改系统变量的方式,如LD_LIBRARY_PATH,LD_PRELOAD。而要实现程序copy到任何地方,都在当前目录下查找,则在编译程序时需要指定rpath。先编译一个动态运行库文件:

    root@debian:/home/xzc/cpp/libtest# cat say.cpp
    #include <iostream>
    #include "say.h"
    
    void CSay::say_yes()
    {
        std::cout << "yes yes yes" << std::endl;
    }
    
    root@debian:/home/xzc/cpp/libtest# cat say.h
    
    class CSay
    {
    public:
        void say_yes();
    };
    
    root@debian:/home/xzc/cpp/libtest# g++ -fPIC -shared say.cpp -o libsay.so

    然后再写一个程序:

    root@debian:/home/xzc/cpp/libtest# cat main.cpp
    #include <iostream>
    
    #include "say.h"
    
    int main()
    {
        CSay s;
        s.say_yes();
    }
    
    root@debian:/home/xzc/cpp/libtest# g++ main.cpp -lsay -L . -o main.o
    root@debian:/home/xzc/cpp/libtest# ./main.o 
    ./main.o: error while loading shared libraries: libsay.so: cannot open shared object file: No such file or directory

    可见这个程序没有找到当前路径下的libsay.so文件。下面我们在编译时指定rpath:

    root@debian:/home/xzc/cpp/libtest# g++ main.cpp -lsay -L . -Wl,--rpath=. -o main.o
    root@debian:/home/xzc/cpp/libtest# ./main.o 
    yes yes yes
    root@debian:/home/xzc/cpp/libtest# readelf -d main.o 
    
    Dynamic section at offset 0x860 contains 26 entries:
      Tag        Type                         Name/Value
     0x00000001 (NEEDED)                     Shared library: [libsay.so]
     0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
     0x00000001 (NEEDED)                     Shared library: [libm.so.6]
     0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
     0x00000001 (NEEDED)                     Shared library: [libc.so.6]
     0x0000000f (RPATH)                      Library rpath: [.]
     0x0000000c (INIT)                       0x8048508
     0x0000000d (FINI)                       0x804878c
     0x00000004 (HASH)                       0x804818c
     0x6ffffef5 (GNU_HASH)                   0x80481dc
     0x00000005 (STRTAB)                     0x8048310
     0x00000006 (SYMTAB)                     0x8048220
     0x0000000a (STRSZ)                      312 (bytes)
     0x0000000b (SYMENT)                     16 (bytes)
     0x00000015 (DEBUG)                      0x0
     0x00000003 (PLTGOT)                     0x804995c
     0x00000002 (PLTRELSZ)                   56 (bytes)
     0x00000014 (PLTREL)                     REL
     0x00000017 (JMPREL)                     0x80484d0
     0x00000011 (REL)                        0x80484c8
     0x00000012 (RELSZ)                      8 (bytes)
     0x00000013 (RELENT)                     8 (bytes)
     0x6ffffffe (VERNEED)                    0x8048468
     0x6fffffff (VERNEEDNUM)                 2
     0x6ffffff0 (VERSYM)                     0x8048448
     0x00000000 (NULL)                       0x0

    可见程序已运行成功。readelf也可以看到其中的rpath为当前目录,如果没有指定,则在系统默认中找。现在,这个程序也可以随意copy到其他地方运行了,只要你连libsay.so一同拷贝。

  • 相关阅读:
    谁把天才变成了魔兽
    NetBeans 时事通讯(刊号 # 35 Nov 20, 2008)
    Java Annotation 手册
    《程序设计实践》读书笔记一
    5分钟让你明白金融危机爆发原因
    NetBeans 6.5 正式版可以下载了!
    Java Annotation 入门
    有关睡觉的学问
    oracle sql日期比较:
    C++编写安全OCX,IE不弹出安全提示
  • 原文地址:https://www.cnblogs.com/coding-my-life/p/4084973.html
Copyright © 2020-2023  润新知