libtool工具的使用
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工具的使用的更多相关文章
- 源码编译安装libtool工具
1. 获取源码 wget http://ftpmirror.gnu.org/libtool/libtool-2.4.6.tar.gz tar xvf libtool-2.4.6.tar.gz -C ~ ...
- 安装性能测试工具:sysbench和使用apache的ab
一.软件的用途,它主要包括以下几种方式的测试:1.cpu性能2.磁盘io性能3.调度程序性能4.内存分配及传输速度5.POSIX线程性能6.数据库性能(OLTP基准测试) 这个软件为什么找不到官网呢? ...
- 解决 free(): invalid pointer: 0x00000000019ff700 运行时报错(caffe)(libtool使用)
编译成功,运行时报错: 在使用 pytorch or tensorflow or caffe 时,都可能存在这个问题: *** Error in `xxx': free(): invalid poin ...
- libtool的工作原理
libtool 是一个通用库支持脚本,将使用动态库的复杂性隐藏在统一.可移植的接口中:使用libtool的标准方法,可以在不同平台上创建并调用动态库.可以认为libtool是gcc的一个抽象,其包装了 ...
- sysbench基准测试工具
一.简介SysBench是一个模块化的.跨平台.多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况.当前功能允许测试的系统参数有:file I/O performance (文件I ...
- 系列篇|编译可在Android上运行的依赖库(一):glib库
前言 这是系列文章,它们由<编译可在Android上运行的glib库>及其他4篇文章组成,这4篇文章在“编译依赖库”一节中列出.由于glib库依赖于其他第三方库,所以需要先将依赖的第三方库 ...
- CWMP开源代码研究2——easycwmp安装和学习
声明:本文是对开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文所有笔记和代码可以到csdn下载:http://download.csdn.n ...
- 161230、利用代理中间件实现大规模Redis集群
前面在<大规模互联网应用Redis架构要点>和<Redis官方集群方案 Redis Cluster>两篇文章中分别介绍了多Redis服务器集群的两种方式,它们是基于客户端sha ...
- Redis/SSDB+Twemproxy的配置与使用(Mac/Linux平台)
对于redis而已,相信不少的后台开发人员一直都在使用,相比memcache而已,redis不仅可以作为key-value缓存使用,而且提供了丰富的数据结构如set.list.map等,能够实现很多复 ...
随机推荐
- Yum安装时提示多库版本保护 Multilib version problems found
例如: yum install pcre pcre-devel 出现一下错误: 解决方法:yum install --setopt=protected_multilib=false pcre pcre ...
- [TJOI2017]DNA --- 后缀数组
[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S, 有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个 ...
- 【并查集】BZOJ1370- [Baltic2003]Gang团伙
[题目大意] 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌人的敌人是我的朋友: 所有是朋友的人组成一个团伙.告诉你关于这n个人的m条信 ...
- Understanding Cache Access
URL Loading System提供了综合的disk 和 in-memory 策略的请求缓存.使用缓存有利于减少程序对网络的依赖,并且能提高程序的体验. Using the Cache for a ...
- [HAOI2015]数组游戏
题目大意: 有一排n个格子,每个格子上都有一个白子或黑子,在上面进行游戏,规则如下: 选择一个含白子的格子x,并选择一个数k,翻转x,2x,...,kx格子上的子. 不能操作者负. 思路: 将“某个格 ...
- [SimpleOJ236]暴风雨
题目大意: 给你一棵n个点的树,以及m+q条信息. m条描述点a到b有边直接相连. q条描述点a和点b的LCA为c. 问有多少符合条件的以1为根的树. 思路: 状压DP. e[i]记录需要与点i直接相 ...
- 修改npm仓库地址
在C:\Users\Administrator文件夹下找到.npmrc 添加registry = http://registry.cnpmjs.org淘宝镜像地址,保存
- Hash表及hash算法的分析
Hash表中的一些原理/概念,及根据这些原理/概念: 一. Hash表概念 二. Hash构造函数的方法,及适用范围 三. Hash处理冲突方法,各自特征 四. ...
- PAT甲级1049. Counting Ones
PAT甲级1049. Counting Ones 题意: 任务很简单:给定任何正整数N,你应该计算从1到N的整数的十进制形式的1的总数.例如,给定N为12,在1,10, 11和12. 思路: < ...
- ArcGIS教程:编辑特征
摘要 通过合并.又一次编号和删除类特征来编辑和更新特征文件. 使用方法 · 编辑特征工具同意您通过下面全部操作或某一操作来改动现有特征文件: 合并一组特征类 又一次编号特征类 ID 删除不须要的特征 ...