http://blog.sina.com.cn/s/blog_602f87700100fc8t.html

libtool作用:

libtool 是一个通用库支持脚本(/usr/bin/libtool),将使用动态库的复杂性隐藏在统一、可移植的接口中。

可以在不同平台上创建并调用动态库,我们可以认为libtool是gcc的一个抽象,也就是说,它包装了gcc或者其他的任何编译器,用户无需知道细节, 只要告诉libtool说我需要要编译哪些库即可,并且,它只与libtool文件打交道,例如lo、la为后缀的文件。

libtool生成一个抽象的后缀名为la高层库libxx.la(其实是个文本文件),并将该库对其它库的依赖关系,都写在该la的文 件中。该文件中的dependency_libs记录该库依赖的所有库(其中有些是以.la文件的形式加入的);libdir则指出了库的安装位 置;library_names记录了共享库的名字;old_library记录了静态库的名字。

libtool使用方法:
1. 编译为一个object文件:

以BTX 为例:

源文件为:BTX.c. 头文件在 ../include/BTX.h

#libtool --mode=compile gcc -g -O -I../include -c BTX.c

用gcc编译一切正常:

mkdir .libs
gcc -g -O -I../include -c BTX.c  -fPIC -DPIC -o
.libs/BTX.o
gcc -g -O -I../include -c BTX.c -o BTX.o >/dev/null
2>&1

#libtool
--mode=compile mipsel_linux_gcc -g
-O -I../include -c BTX.c
显示需要--tag.

libtool支持多语言,以下是语言与tag的对应:

Language
name     
Tag name
C                 
CC
C++               
CXX
Java              
GCJ
Fortran
77        
F77
Windows Resource   RC

#libtool --mode=compile --tag=CC
mipsel-linux-gcc -g -I../include -c BTX.c

则正常了。

libtool: ignoring unknown tag
mipsel-linux-gcc
 mipsel-linux-gcc -g -I../include -c
BTX.c  -fPIC -DPIC -o .libs/BTX.o
 mipsel-linux-gcc -g -I../include -c BTX.c -o
BTX.o >/dev/null
2>&1

--mode:表示此次动作是 compile(编译)。

--tag: 如果是交叉编译器,则需要用--tag指定编译器。

gcc -g -O -I../include -c BTX.c: 很清楚。

然后libtool作了3件事:

1.创建.libs

2.编译了一个与位置无关(-fPIC)的obj文件。 放在 .lib中。

3.编译了一个普通obj文件在本地。

另外,它还创建了一个lo文件。用于描述上面2个obj文件和他们的位置。格式与la文件类似。

2. 将Object文件编译成可执行文件:

Object的描述文件为 *.lo文件,而libtool只与lo,la文件打交道,

#libtool --mode=link --tag=CC mipsel-linux-gcc main.lo
-o test

则利用先前编译出的main.lo编译出结果: 可执行文件test.

3. 编译一个库文件:

#libtool --mode=link --tag=CC gcc -g -O -o libBTX.la -rpath
/usr/local/lib BTX.lo

显示结果为:

rm -fr  .libs/libBTX.a .libs/libBTX.la
.libs/libBTX.lai .libs/libBTX.so .libs/libBTX.so.0
.libs/libBTX.so.0.0.0
gcc -shared 
.libs/BTX.o   -Wl,-soname
-Wl,libBTX.so.0 -o .libs/libBTX.so.0.0.0
(cd .libs && rm -f libBTX.so.0
&& ln -s libBTX.so.0.0.0
libBTX.so.0)
(cd .libs && rm -f libBTX.so
&& ln -s libBTX.so.0.0.0
libBTX.so)
ar cru .libs/libBTX.a  BTX.o
ranlib .libs/libBTX.a
creating libBTX.la
(cd .libs && rm -f libBTX.la
&& ln -s ../libBTX.la
libBTX.la)

link出两个共享库,一个是static,一个则是dynamic;需要注意的是,-rpath必须有才能产生dynamic库来,如果用-static,则只创建static库。

libBTX.la则指出静态库和动态库的名字和位置。

ranlib的作用:
在一些旧版本的系统上,ranlib负责把静态库转换为其他的某种格式,使得新的库能够更快的链接;现在ar命令已经包含了上述功能;

为了兼容性,在makefile中还是保留ranlib

#mipsel

#libtool --mode=link --tag=CC
mipsel-linux-gcc  -O -o libBTX.la -rpath
/usr/local/lib BTX.lo

当这样设置时,libtool会使用gcc,Sam 怎么也没法改正。所以只好临时在

/usr/bin/libtool中修改CC="mipsel-linux-gcc" 。这样就可以了。

mipsel-linux-gcc -shared 
.libs/BTX.o   -Wl,-soname
-Wl,libBTX.so.0 -o .libs/libBTX.so.0.0.0

但这里,Sam发现libBTX.la中并没有显示出libBTX.so依赖于libbluetooth.so。这不是没有达到使用libtool的目的吗?

于是Sam又作了修改:

#libtool --mode=link --tag=CC
mipsel-linux-gcc BTX.lo -rpath
/home/sam/work/current/BCM/BCM7405/ToolChain/crosstools_hf-linux-2.6.18.0_gcc-4.2-9ts_uclibc-nptl-0.9.29-20070423_20080702/mipsel-linux/lib
-o libBTX.la -lbluetooth

果然:在la文件中,可以看到dependency_libs='
-lbluetooth'

则在编译为可执行文件时,可以不用写 -lbluetooth

#libtool --mode=link --tag=CC mipsel-linux-gcc main.lo
libBTX.la -o test -lpthread

当然,也可以隐式的写:

#libtool --mode=link --tag=CC mipsel-linux-gcc main.lo
-lBTX -o test -lpthread

结果也正常:

mipsel-linux-gcc .libs/main.o -o .libs/test 
/home/sam/work/current/BCM/BCM7405/Bluetooth/Bluetooth_App/Second_New_Version/BTX_source/BTX_Release/src/.libs/libBTX.so
-lbluetooth -lpthread  
-Wl,--rpath
-Wl,/home/sam/work/current/BCM/BCM7405/ToolChain/crosstools_hf-linux-2.6.18.0_gcc-4.2-9ts_uclibc-nptl-0.9.29-20070423_20080702/mipsel-linux/lib

creating test

libtool 从libBTX.la中取出相应的东西。

4. 将object + so 编译出一个可执行文件:

#libtool --mode=link mipsel-linux-gcc -L../resource main.lo
libBTX.la -o BTX_Test -lbluetooth -lpthread

显示为:

mipsel-linux-gcc .libs/main.o -o
.libs/BTX_Test 
-L/home/sam/work/current/BCM/BCM7405/Bluetooth/Bluetooth_App/Second_New_Version/BTX_source/BTX_Release/resource
./.libs/libBTX.so -lbluetooth
-lpthread   -Wl,--rpath
-Wl,/usr/local/lib

背景知识:

背景知识1:libtool为何使用 -Wl,--rpath-link -Wl,

使用libtool解决编译问题看上去没什么问题:库的名称、路径、依赖都得到了很好的解决。但下结论不要那么着急,一个显而易见的问题就是:并不是所有的库都是用libtool编译的。

例如:我用常规办法生成libBTX.so. 则需要编译连接成可执行文件时,就没有libBTX.la文件。

这样,libBTX.so依赖于 libbluetooth.so这个信息就无人得知。

#libtool --mode=link --tag=CC mipsel-linux-gcc main.lo
-L./ -lBTX -o test -lpthread

则因为没有libBTX.la, 所以根本没有 依赖于
libbluetooth.so的信息。所以用到libbluetooth.so的东西全无法链接。

选项“-Wl,--rpath-link
–Wl,DIR”会把-rpath-link选项及路径信息传递给链接器。

相当于 --rpath-link /xxx/lib

背景知识2:

是因为如果在本地编译的情况下,link时,gcc在命令行中找不到一个库(比如上面的liba.so)依赖的其它库(比如libb.so),链接器会按照某种策略到某些路径下面去寻找需要的共享库:

1. 所有由'-rpath-link'选项指定的搜索路径.

2. 所有由'-rpath'指定的搜索路径.
'-rpath'跟'-rpath_link'的不同之处在于,由'-rpath'指定的路径被包含在可执行文件中,并在运行时使用,
而'-rpath-link'选项仅仅在连接时起作用.

3. 在一个ELF系统中, 如果'-rpath'和'rpath-link'选项没有被使用,
会搜索环境变量'LD_RUN_PATH'的内容.它也只对本地连接器起作用.

4. 在SunOS上, '-rpath'选项不使用, 只搜索所有由'-L'指定的目录.

5. 对于一个本地连接器,环境变量'LD_LIBRARY_PATH'的内容被搜索.

6. 对于一个本地ELF连接器,共享库中的`DT_RUNPATH'和`DT_RPATH'操作符会被需要它的共享库搜索.
如果'DT_RUNPATH'存在了, 那'DT_RPATH'就会被忽略.

7. 缺省目录, 常规的,如'/lib'和'/usr/lib'.

8. 对于ELF系统上的本地连接器, 如果文件'/etc/ld.so.conf'存在,
这个文件中有的目录会被搜索.

从以上可以看出,在使用本地工具链进行本地编译情况下,只要库存在于某个位置,gcc总能通过如上策略找到需要的共享库。但在交叉编译下,上述八种策略,可以使用的仅仅有两个:-rpath-link,-rpath。这两个选项在上述八种策略当中优先级最高,当指定这两个选项时,如果链接需要的共享库找不到,链接器会优先到这两个选项指定的路径下去搜索需要的共享库。通过上面的描述可以看到:-rpath指定的路径将被写到可执行文件中;-rpath-
link则不会
;我们当然不希望交叉编译情况下使用的路径信息被写进最终的可执行文件,所以我们选择使用选项-rpath-link。

 
 

libtool工具的使用的更多相关文章

  1. 源码编译安装libtool工具

    1. 获取源码 wget http://ftpmirror.gnu.org/libtool/libtool-2.4.6.tar.gz tar xvf libtool-2.4.6.tar.gz -C ~ ...

  2. 安装性能测试工具:sysbench和使用apache的ab

    一.软件的用途,它主要包括以下几种方式的测试:1.cpu性能2.磁盘io性能3.调度程序性能4.内存分配及传输速度5.POSIX线程性能6.数据库性能(OLTP基准测试) 这个软件为什么找不到官网呢? ...

  3. 解决 free(): invalid pointer: 0x00000000019ff700 运行时报错(caffe)(libtool使用)

    编译成功,运行时报错: 在使用 pytorch or tensorflow or caffe 时,都可能存在这个问题: *** Error in `xxx': free(): invalid poin ...

  4. libtool的工作原理

    libtool 是一个通用库支持脚本,将使用动态库的复杂性隐藏在统一.可移植的接口中:使用libtool的标准方法,可以在不同平台上创建并调用动态库.可以认为libtool是gcc的一个抽象,其包装了 ...

  5. sysbench基准测试工具

    一.简介SysBench是一个模块化的.跨平台.多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况.当前功能允许测试的系统参数有:file I/O performance (文件I ...

  6. 系列篇|编译可在Android上运行的依赖库(一):glib库

    前言 这是系列文章,它们由<编译可在Android上运行的glib库>及其他4篇文章组成,这4篇文章在“编译依赖库”一节中列出.由于glib库依赖于其他第三方库,所以需要先将依赖的第三方库 ...

  7. CWMP开源代码研究2——easycwmp安装和学习

    声明:本文是对开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文所有笔记和代码可以到csdn下载:http://download.csdn.n ...

  8. 161230、利用代理中间件实现大规模Redis集群

    前面在<大规模互联网应用Redis架构要点>和<Redis官方集群方案 Redis Cluster>两篇文章中分别介绍了多Redis服务器集群的两种方式,它们是基于客户端sha ...

  9. Redis/SSDB+Twemproxy的配置与使用(Mac/Linux平台)

    对于redis而已,相信不少的后台开发人员一直都在使用,相比memcache而已,redis不仅可以作为key-value缓存使用,而且提供了丰富的数据结构如set.list.map等,能够实现很多复 ...

随机推荐

  1. 【BZOJ 3106】 3106: [cqoi2013]棋盘游戏 (对抗搜索)

    3106: [cqoi2013]棋盘游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 544  Solved: 233 Description 一个 ...

  2. 【BZOJ 2728】 2728: [HNOI2012]与非 (线性基?)

    2728: [HNOI2012]与非 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 813  Solved: 389 Description Inpu ...

  3. 【BZOJ 2121】字符串游戏

    http://www.lydsy.com/JudgeOnline/problem.php?id=2121 dp,设\(f(i,j,k,l)\)表示原串i到j这个子串能否被删成第k个串的长度为l的前缀. ...

  4. BZOJ 3626: [LNOI2014]LCA 树链剖分 线段树 离线

    http://www.lydsy.com/JudgeOnline/problem.php?id=3626 LNOI的树链剖分题没有HAOI那么水,学到的东西还是很多的. 我如果现场写,很难想出来这种题 ...

  5. bzoj 2154

    收获: 1.当一个东西的取值范围很小时,或者感觉它很麻烦时,就枚举它 2.熟悉mobius函数.euler函数的和函数,以及euler函数用mobius函数的表示. 3.下取整分块理解更深了. /** ...

  6. bzoj 2002 LinkCutTree

    我的第一道LCT题(居然1A,O(∩_∩)O哈哈~) 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 大概题意: 给一颗有根树,维护每个 ...

  7. Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

    BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1044  Solved: 322[Submit][ ...

  8. HDU 5297 Y sequence 容斥 迭代

    Y sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5297 Description Yellowstar likes integer ...

  9. jmeter用beanshell调用自己写的jar进行MD5加密

    1.先在eclipse里面写好MD5的加密文件,用eclipse执行一遍,确保文件不会报错 Str2MD5.java 内容如下: package hehe.md5; import java.secur ...

  10. 原来通过修改dns加快app store下载速度的确有效

    说来惭愧,这几天休假,并没有做什么技术上的修行.小伙伴推荐我一款avg游戏<11eyes 罪与罚与被诅咒的少女>,说是神作.但是app store上卖rmb118元,起初并没有什么兴趣去购 ...