linux指定动态运行库的位置

  动态运行库在windows、linux下均广泛使用。windows下通常为dll文件,linux下为so文件。不过,对于部署程序,这两个系统查找依赖的运行库文件时却不一样。对于windows而言,优先查找当前目录下,然后再到系统库文件C:\windows\system32(记不太清楚,好像是这个位置)下查找。这个特性极大的方便了程序的部署,程序员只需要把相关的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一同拷贝。

转载于:https://www.cnblogs.com/coding-my-life/p/4084973.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值