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。先编译一个动态运行库文件:

[email protected]:/home/xzc/cpp/libtest# cat say.cpp
#include <iostream>
#include "say.h"

void CSay::say_yes()
{
    std::cout << "yes yes yes" << std::endl;
}

[email protected]:/home/xzc/cpp/libtest# cat say.h

class CSay
{
public:
    void say_yes();
};

[email protected]:/home/xzc/cpp/libtest# g++ -fPIC -shared say.cpp -o libsay.so

然后再写一个程序:

[email protected]:/home/xzc/cpp/libtest# cat main.cpp
#include <iostream>

#include "say.h"

int main()
{
    CSay s;
    s.say_yes();
}

[email protected]:/home/xzc/cpp/libtest# g++ main.cpp -lsay -L . -o main.o
[email protected]:/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:

[email protected]:/home/xzc/cpp/libtest# g++ main.cpp -lsay -L . -Wl,--rpath=. -o main.o
[email protected]:/home/xzc/cpp/libtest# ./main.o
yes yes yes
[email protected]:/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一同拷贝。

时间: 2024-08-26 10:50:28

linux指定动态运行库的位置的相关文章

linux C 动态共享库编译链接

  1.1.1         linux编写so文件的方式 1首先gcc编译的时候要加-fPIC选项,-fPIC是告诉gcc生成一个与位置无关的代码 2gcc链接的时候要加-shared选项,意思是生成一个so共享库. 对于linux或者unix,一个so文件,文件扩展名必须是so,文件名的前三个字母必须是lib 1.1.2         linux使用so gcc链接的时候需要加-L.代表从当前目录下找相关的so文件,-l文件名(但不包括文件名开头的lib和扩展名so) 例如编译一个mai

通过memcache动态运行库操作memcached服务,进行CURD

具体学习参考php参考手册: 操作memcached的几种方式: bool Memcache::add ( string $key , mixed $var [, int $flag [, int $expire ]] ) 如果报 expire 设为0 表示,永不过期.(只要memcache不重新启动,就永远在mem中) exprie 直接给的是秒数,则最大 30*3600*24 如果你希望保持时间超过30  time()+天数*3600*24 即可 mem1.php <?php //创建一个m

Linux指定用户运行程序

可以参考文章: https://www.cnblogs.com/jmliao/p/11823209.html 具体事例: #在root用户下,直接用以下命令来执行程序,程序执行后,程序隶属于用户git su - git -c "nohup /home/git/gogs/gogs web >/dev/null 2>&1 &" 原文地址:https://www.cnblogs.com/faberbeta/p/linux-shell024.html

静态函数库和动态函数库

静态函数库是在编译链接时,把库文件代码全部加入到可执行文件中,因此生成的文件比较大,而运行时也就不需要库文件了.Linux中静态函数库的后缀名一般为".a",windows中为".Lib": 动态函数库是在编译链接时没有把库文件代码加入到可执行文件中,而是将要调用的函数所在文件的和该函数在文件中的位置等信息链接进目标程序.Linux中动态函数库的后缀名一般为".so",windows中为".dll".

linux 添加动态库路径

众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库,并且该 动 态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函数,以及 该动态库的其它资源了.在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定. 方法一:在配置文件/etc/ld.so.conf中指定动态库搜索路径. 可以通过编辑配置文件/

Linux 如何生成静态库和动态库

1.引言 1.linux下的库 静态库和共享库(动态库),二者的不同点在于代码被载入的时刻不同. 静态库的代码在编译过程中已经被载入可执行程序,因此体积较大. 共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小. 2.库存在的意义 库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议. 现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 共享库的好处是,不同的应用程序如果调用相同的库,那么

Linux下的动态连接库及其实现机制

Linux与Windows的动态连接库概念相似,但是实现机制不同.它引入了GOT表和PLT表的概念,综合使用了多种重定位项,实现了"浮动代码",达到了更好的共享性能.本文对这些技术逐一进行了详细讨论. 本文着重讨论x86体系结构,这是因为 (1)运行Linux的各种体系结构中,以x86最为普及: (2)该体系结构上的Windows操作系统广为人知,由此可以较容易的理解Linux的类似概念: 下表列出了Windows与Linux的近义词,文中将不加以区分: Windows Linux 动

在Linux中创建静态库.a和动态库.so

转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用函数制作成函数库,供其它程序使用. 函数库分为静态库和动态库两种. 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译

Linux 静态链接库和动态连接库

(0)文件夹 VMware 下安装Ubuntu的吐血经历 零基础学习Shell编程 Linux下的makefile的妙用 Linux调试神器 -- gdb 十分钟学会Python的基本类型 Linux 静态链接库和动态连接库 一:静态链接库的应用  三步走~~~ ##g++ -c StaticMath.cpp ##ar -crv libstaticmath.a StaticMath.o ##g++ -o run test_a.cpp -L. -lstaticmath #[@sjs_37_33 l