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 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libsay.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so.]
0x00000001 (NEEDED) Shared library: [libm.so.]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.]
0x00000001 (NEEDED) Shared library: [libc.so.]
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) (bytes)
0x0000000b (SYMENT) (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x804995c
0x00000002 (PLTRELSZ) (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x80484d0
0x00000011 (REL) 0x80484c8
0x00000012 (RELSZ) (bytes)
0x00000013 (RELENT) (bytes)
0x6ffffffe (VERNEED) 0x8048468
0x6fffffff (VERNEEDNUM)
0x6ffffff0 (VERSYM) 0x8048448
0x00000000 (NULL) 0x0
可见程序已运行成功。readelf也可以看到其中的rpath为当前目录,如果没有指定,则在系统默认中找。现在,这个程序也可以随意copy到其他地方运行了,只要你连libsay.so一同拷贝。
linux指定动态运行库的位置的更多相关文章
- 【转载】Linux下动态共享库加载时的搜索路径详解
转载自:http://www.eefocus.com/article/09-04/71617s.html 对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while loading ...
- Linux下动态共享库加载及使用详解【转】
原文地址:http://blog.chinaunix.net/uid-29025972-id-3855500.html 对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while l ...
- Linux下动态共享库加载时的搜索路径详解
对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while loading shared libraries”这样的错误,这是典型的因为需要的动态库不在动态链接器ld.so的搜索路径 ...
- Linux下动态共享库加载及使用详解
转载;http://blog.chinaunix.net/uid-29025972-id-3855500.html 对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while loa ...
- <摘录>Linux下动态共享库加载时的搜索路径详解
对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while loading shared libraries”这样的错误,这是典型的因为需要的动态库不在动态链接器ld.so的搜索路径 ...
- linux addr2line 定位so库崩溃位置
在Linux下写C/C++程序的程序员,时常与Core Dump相见.在内存越界访问,收到不能处理的信号,除零等错误出现时,我们精心或不精心写就的程序就直接一命呜呼了,Core Dump是Linux仁 ...
- linux 缺少动态连接库.so--cannot open shared object file: No such file or directory
error while loading shared libraries的解決方法 执行行程式時,如此遇到像下列這種錯誤: ./tests: error while loading shared l ...
- Linux指定用户运行程序
参考:http://blog.useasp.net/archive/2015/07/29/run-command-as-different-user-on-linux.aspx 在实际中,我们有时候想 ...
- Linux缺少动态连接库.so--cannot open shared object file: No such file or directory
1 Liunx安装报错时,缺少动态链接库时,形式如下: /usr/local/libexec/gcc/x86_64-unknown-liunx-gnu/4.8.2/cc1: error while l ...
随机推荐
- Spring 小示例
通过一个简单的示例来初步理解Spring框架 1.创建java工程,导入相应Spring包,放在lib文件夹中 2.接口 IHelloMessage package com.jike.spring. ...
- PHP的错误处理方式
错误类型 PHP 主要有两种错误:触发错误和异常.其中触发错误大概可以分为:编译错误.引擎错误和运行时错误,其中前两个是无法捕获的:异常都是可以捕获的,当没有尝试捕获时则会中断代码. 触发错误可以通过 ...
- (转)Building MariaDB on Mac OS X using Homebrew
https://kb.askmonty.org/en/building-mariadb-on-mac-os-x-using-homebrew/ Work has been done to provid ...
- 通过BulkLoad的方式快速导入海量数据
摘要 加载数据到HBase的方式有多种,通过HBase API导入或命令行导入或使用第三方(如sqoop)来导入或使用MR来批量导入(耗费磁盘I/O,容易在导入的过程使节点宕机),但是这些方式不是慢就 ...
- jQuery的ajax jsonp跨域请求
了解:ajax.json.jsonp.“跨域”的关系 要弄清楚以上ajax.json.jsonp概念的关系,我觉得弄清楚ajax是“干什么的”,“怎么实现的”,“有什么问题”,“如果解决存在的问题”等 ...
- 解决如何让AsyncTask终止操作
受到这个的启发终于结局了如何在AsyncTask运行中终止其操作. 单纯的onCancelled(true)是不行的 下面把代码贴出来~实现了登陆功能. AsyncTask简介,它使创建需要与用户界面 ...
- WebApi2官网学习记录---Configuring
Configuration Settings WebAPI中的configuration settings定义在HttpConfiguration中.有一下成员: DependencyResolver ...
- oracle得到拼音函数
CREATE OR REPLACE FUNCTION fgetpy (v_str VARCHAR2) RETURN VARCHAR2AS v_strlen INT; v_return ...
- 工程与科学数值方法的Matlab实现
%stats.m function [mean,stdev]=stats(x) n=length(x);mean=sum(x)/n;stdev=sqrt(sum((x-mean).^2/(n-1))) ...
- c#中serialPort1_DataReceived串口接收事件处理
1.缓冲区不定字节读取(波特率很高也没问题) //Thread.sleep(1000);//处理事件这块可以加上延时确保不定数的数据可以全部收到缓冲后,才去读缓冲内容--单位:毫秒 byte[] da ...