库文件的使用

背景:

初学者经常搞不清楚,一个main.cpp文件,调用了某库(可能静态也可动态)中的函数,如何将它跑起来。

编译:

g++ -c main.cpp
main.cpp:3:26: fatal error: leveldb/db.h: No such file or directory
 #include "leveldb/db.h"
                          ^
compilation terminated.

缺少头文件,加上再编译(编译只与头文件有关,不需要关注库):

g++ -c main.cpp -I/home/ww/2.src/leveldb/include

OK,生成main.o

链接:

  • 先考虑链接静态库的情况(同时存在动态和静态库的情况下,默认使用静态库)。
g++ -o main main.o -L/home/ww/2.src/leveldb/out-static -lleveldb -lpthread

OK,执行正常。

  • 如果是动态库的链接,链接方法是一样:
g++ -o main main.o -L/home/ww/2.src/leveldb/out-shared -lleveldb -lpthread

但这个可执行文件是跑不了的:

ldd main
        linux-vdso.so.1 (0x00007fffd58f2000)
        libleveldb.so.1 => not found
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fbb4a509000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fbb4a1fe000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbb49efd000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fbb49ce7000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbb4993c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fbb4a726000)

./main
./main: error while loading shared libraries: libleveldb.so.1: cannot open shared object file: No such file or directory

因为动态库不仅在编译(具体来看是链接)时要被搜索,在二进制文件加载和执行时也要搜索。上面的例子仅指定了链接时的搜索。

看下文档对于动态库的说明:

linux程序跑时,program loader会自动被加载并跑起来(即上面加红的/lib64/ld-linux-x86-64.so.2 (0x00007ff40629d000) )。它作用是找到当前程序依赖的各个库文件,并加载它们。

loader找到动态库文件有几种方法:

  1. ldconfig

这是最正式的方法,正式发布都应该使用这种方法。

默认的loader搜索动态库的路径在 /etc/ld.so.conf定义。

如:

[email protected]:/etc/ld.so.conf.d$ cat *
/usr/lib/x86_64-linux-gnu/libfakeroot
# libc default configuration
/usr/local/lib
# Multiarch support
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

因此,需要将动态库放到对应的地点,并对应修改或增加.conf文件。

之后,需要调用ldconfig。它的作用是建立起加载所需要的符号缓存。这里不做示例。

  1. prelaod

这种方式适用于需要部分替换已有库文件中的一些方法。当然也能作为加载路径使用。具体使用是使用LD_PRELOAD环境变量:

LD_PRELOAD=/home/ww/2.src/leveldb/out-shared/libleveldb.so ./main
Open db OK
  1. LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/home/ww/2.src/leveldb/out-shared:${LD_LIBRARY_PATH}

ldd main
        linux-vdso.so.1 (0x00007ffe239f5000)
        libleveldb.so.1 => /home/ww/2.src/leveldb/out-shared/libleveldb.so.1 (0x00007ff405fe6000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff405dc9000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff405abe000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff4057bd000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff4055a7000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff4051fc000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff40629d000)

调试时用此方法比较方便,正式场合也可用。但它有一些潜在的问题:

- 由于安全原因,在使用setuid的情况下不会生效。具体见参考文献。

  1. 直接使用loader指定路径调用
/lib64/ld-linux-x86-64.so.2 --library-path /home/ww/2.src/leveldb/out-shared ./main
Open db OK

调试使用。

参考:

【1】http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

【2】http://xahlee.info/UnixResource_dir/_/ldpath.html

时间: 2024-11-05 20:48:31

库文件的使用的相关文章

copy命令及库文件至/mnt/sysroot/目录shell脚本

#!/bin/bash # #获取目标目录 target=/mnt/sysroot #命令copy函数 cmndcopy(){         #假如命令不存在,return 1         if ! which $1 &> /dev/null; then                 return 1         fi         #获取命令决定路径         cmnd=$(which --skip-alias $1)         #获取命令目录名         

第一百六十一节,封装库--JavaScript,完整封装库文件

封装库--JavaScript,完整封装库文件 /** *feng_zhuang_ku_1.0版本,js封装库,2016/12/29日:林贵秀 **/ /** 前台调用 * 每次调用$()创建库对象,使其每次调用都是独立的对象 * $()创建库对象,有一个可选参数,参数有两种方式,1是传入的this,2是传入的字符串 * 可选参数说明: * 传入的this,this,就是当前对象本身 * * 传入的字符串,代表获取元素选择器 * 参数是元素选择器(id值.class值.标签名称)其中一样的字符串

linux-gcc 编译时头文件和库文件搜索路径

一.头文件  gcc 在编译时寻找所需要的头文件 :  ※搜寻会从-I开始  ※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH  ※再找内定目录/usr/include /usr/local/include/usr/lib/gcc-lib/i386-linux/2.95.2/include/usr/lib/gcc-lib/i386-linux/2.95.2/include/g++-3/usr/lib/gcc-lib/

iOS 创建静态库文件时去掉其中的Symbols

在工程中创建静态库文件时,默认会将一些Symbols加到静态库文件中,这样做有两个缺点: 1.如果引用静态库文件的工程中发生了bug,就会直接跳转到静态库的源码. 2.静态库文件的大小会因此翻几番.本人最近做的这个静态库文件中,去掉symbols前大小为7.8MB左右,去掉以后大小为2.8MB. 要去掉Symbols,首先打开Build Settings并选中静态库的Target,然后设置下列选项: 如果有错误或遗漏,欢迎批评指正. iOS 创建静态库文件时去掉其中的Symbols,布布扣,bu

linux下把log4cxx封装成so动态库文件(一)

这是一个经常遇到的问题,在软件开发过程中,需要将某些功能封装成一个独立的模块,这样维护升级也很方便.现在我们就要把开源日志库log4cxx封装成so动态加载库文件. 在上一篇文章<log4cxx日志库RedHat下安装>中,我们已经将log4cxx安装在home/mac/log4cxx/log4cxx下了,那么接下来的操作我们就继续在这个路径下进行. 还是先tree一下/home/mac/log4cxx这个目录吧 log4cxx ---apr ---apr-util ---log4cxx 那再

在Ubuntu宿主机上查看ARM交叉编译好的可执行程序和库文件的相关依赖关系,类似于PC上的ldd命令

在电脑上安装的Linux系统中,有一个ldd命令,可以查看对应的可执行文件或库文件依赖哪些库,但可执行文件或库文件要求与操作系统的编译器类型相同,即电脑是X86的GCC编译器,那么无法通过ldd命令查看ARM交叉编译器编译出来的可执行文件或库文件. 如果想在Ubuntu等Linux宿主机上查看ARM交叉编译好的可执行程序和库文件的相关依赖关系,可以通过以下命令: [email protected]:$ arm-linux-readelf  -a  busybox |grep "Shared&qu

visual stdio 安装OpenGL库文件

1.将下载的压缩包解开,将得到5个文件 1. 将glut解压出来,将其中的glut.h复制到C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\gl下,若gl目录不存在,则新建.(在这种情况下头文件为#include <gl/glut.h>,我是直接放在C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include下,所以头文件#include <glu

orcad常用库文件

ORCAD CAPTURE元件库介绍 AMPLIFIER.OLB amplifier 共182个零件,存放模拟放大器IC,如CA3280,TL027C,EL4093等. ARITHMETIC.OLB arithmetic 共182个零件,存放逻辑运算IC,如TC4032B,74LS85等. ATOD.OLB 共618个零件,存放A/D转换IC,如ADC0804,TC7109等. BUS DRIVERTRANSCEIVER.OLB 共632个零件,存放汇流排驱动IC,如74LS244,74LS37

(转) C语言头文件、库文件的查找路径

在程序设计中,文件包含是很有用的.一个大的程序可以分为多个模块,由多个程序员分别编程.有        些公    用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使        用.这样,可避免在每个文件开头都去书写那些公用量,从而节省时间,并减少出错. 对文件包含命令还要说明以下几点:1. 包含命令中的文件名可以用双引号括起来,也可以用尖括号括起来.例如以下写法都是允许的:    #include"stdio.h"    #include   

TCL:使用、添加库文件

>直接引用工具自带的库文件 通过指令: 1.1查看能直接调用的库文件路径 #可以查到工具默认库文件路径,一般包括回显中的路径以及回显中路径的父路径. info library #D:/Script.NET/V2/Interps/Tcl/Lib/tcl8.4 1.2.在上一步的路径下找找没有自己需要的库,通过指令: package require xxx 引用,一般直接写tcl文件名即可,如果不对,查看pkgIndex.tcl里package ifneeded 后边的名称. >引用别人的库文件或