libtool 创建库的工具

1. 背景

  在不同的系统中建立动态链接库的方法有很大的差别,这主要是因为每个系统对动态链接库的用法和实现并不相同,以及编译器对动态链接库支持的选项也不太一样。

  对于开发人员,如果尝试将使用动态库的软件在这些系统之间移植,需要参考枯涩难懂的系统手册,以及修改相应的 Makefile,这一工作是乏味的,并且具有一定的难度。

  使用 GNU Libtool 可以容易的在不同的系统中建立动态链接库。它通过一个称为 Libtool 库的抽象,隐藏了不同系统之间的差异,给开发人员提供了一致的的接口。对于大部分情况,开发人员甚至不用去查看相应的系统手册,只需要掌握 GNU Libtool 的用法就可以了。并且,使用 Libtool 的 Makefile 也只需要编写一次就可以在多个系统上使用

  Libtool 库可以是一个静态链接库,可以是一个动态链接库,也可以同时包含两者。

  在这篇文档中,我们围绕 Libtool 库的建立和使用,只是在适当的说明 Libtool 库和系统动态或者静态链接库之间的映射关系

2. Libtool 是一个工具

  虽然 Libtool 隐藏了在不同平台创建链接库的复杂性,但其最终还是需要底层系统对链接库的支持,它不能超越系统的限制,例如,Libtool 并不能在不支持动态链接库的系统中创建出动态链接库。

3.  Libtool 基本用法

  以实例来说明如何使用 Libtool 从源代码创建最终链接库以及执行程序的完整步骤,这是软件开发过程中经常使用的内容,包括 :

  • 创建 Libtool 对象文件 ;
  • 创建 Libtool 库;
  • 安装 Libtool 库 ;
  • 使用 Libtool 库 ;
  • 卸载 Libtool 库 ;

  首先需要准备一个源文件 compress.c,代码如下

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include <zlib.h> /* 一个简单的文件压缩函数 */
int compress_file (const char *filename)
{
int src_fd, dest_fd;
struct stat sb;
Bytef *src, *dest;
uLong dest_len;
char dest_file[PATH_MAX]; src_fd = open (filename, O_RDONLY);
assert (dest_fd != -); assert (fstat (src_fd, &sb) != -); src = mmap (NULL, sb.st_size, PROT_READ, MAP_PRIVATE, src_fd, );
assert (src != MAP_FAILED); dest_len = compressBound (sb.st_size);
dest = malloc (dest_len);
assert (dest); assert (compress (dest, &dest_len, src, sb.st_size) == Z_OK); munmap (src, sb.st_size);
close (src_fd); snprintf (dest_file, sizeof (dest_file), "%s.z", filename);
dest_fd = creat (dest_file, S_IRUSR | S_IWUSR);
assert (dest_fd != -); write (dest_fd, dest, dest_len);
close (dest_fd);
free (dest); return ;
}

  这个文件实现了一个函数 compress_file(),它接收一个文件名作为参数,然后对文件进行压缩,生成一个 .z结尾的压缩文件。在这个文件中使用了 compress()函数,这个函数是有由 libz 提供的

  从源文件建立 Libtool 库需要经过两个步骤,先建立 Libtool 对象文件,再建立 Libtool 库。

(1) Libtool 对象文件

  如果使用传统的方式,建立对象文件通常使用下面的命令

$ gcc -c compress.c

  使用 Libtool 则使用下面的命令 :

$ libtool --mode=compile gcc -c foo.c    

  可以看到,使用 Libtool 只需要将“传统”的命令 (gcc -c foo.c) 作为参数传递给 Libtool 即可。

  在上面的命令中,libtool 使用 compile模式 (--mode=compile 选项 ),这是建立对象文件的模式,Libtool 还有其它的模式,后面将介绍。

  上面的命令输出如下 :

mkdir .libs
gcc -c compress.c -fPIC -DPIC -o .libs/compress.o
gcc -c compress.c -o compress.o >/dev/null >&

  它建立了两个文件,一个是 .libs/compress.o,在建立这个文件时,Libtool 自动插入了 -fPIC和 -DPIC选项,告诉编译器生成位置独立的代码,之后将用这个文件来建立动态链接库。生成第二个文件 compress.o没有添加额外的选项,它准备用来建立静态链接库。

  除了上面的两个文件之外,Libtool 还建立了一个文件 compress.lo,这个文件就是 Libtool 对象文件,实际上也就是一个文本文件,里面记录了建立动态链接库静态链接库分别所需要的真实文件名称,后面 Libtool 将使用这个文件而不是直接的使用 .libs/compress.o 和 compress.o。

(2)建立 Libtool 库

$ libtool --mode=link gcc -o libcompress.la【目标文件】 compress.lo【输入文件】 -rpath /tmp -lz

  注意这里使用 compress.lo 作为输入文件,并且告诉 Libtool 生成的目标文件为 libcompress.la,.la 是 Libtool 的库文件后缀。

  -rpath选项告诉 Libtool 这个库将被安装到什么地方,如果省略了 -rpath选项,那么不会生成动态链接库

  因为我们的库中使用了 libz 提供的 compress 函数,所以也提供了 -lz 选项,Libtool 会记住这个依赖关系,后续在使用我们的库时自动的将依赖的库链接进来。

gcc -shared  .libs/compress.o  -lz  -Wl,-soname -Wl,libcompress.so.
-o .libs/libcompress.so.0.0.
(cd .libs && rm -f libcompress.so. &&
ln -s libcompress.so.0.0. libcompress.so.)
(cd .libs && rm -f libcompress.so &&
ln -s libcompress.so.0.0. libcompress.so)
ar cru .libs/libcompress.a compress.o
ranlib .libs/libcompress.a
creating libcompress.la
(cd .libs && rm -f libcompress.la &&
ln -s ../libcompress.la libcompress.la)

  可以看到,Libtool 自动的插入了建立动态链接库需要的编译选项 -shared。并且,它也建立了静态链接库 .libs/libcompress.a,后面我们将会介绍如何控制 Libtool 只建立需要的库

  你可能会奇怪为什么建立的动态链接库有 .0 和 .0.0.0 这样的后缀,这里先不用理会它,后面在介绍 Libtool 库版本信息时将会解释这点。

  值得注意的是,Libtool 希望后续使用 libcompress.la 文件而不是直接使用 libcompress.a 和 libcompress.so 文件,如果你这样做,虽然可以,但会破坏 Libtool 库的可移植性。

4. 安装 Libtool 库

  发布建立好的 Libtool 库,可以使用下面的命令安装它 :

$ libtool --mode=install install -c libcompress.la /tmp

  我们需要告诉 Libtool 使用的安装命令,Libtool 支持 install 和 cp,这里使用的是 install。

  虽然前面我们在建立库时,通过 -rpath 选项指定了库准备安装的路径 (/tmp),但是这里我们还得要提供安装路径。请确保它们一致。

  这个命令的输出如下 :

install .libs/libcompress.so.0.0. /tmp/libcompress.so.0.0.
(cd /tmp && { ln -s -f libcompress.so.0.0. libcompress.so. ||
{ rm -f libcompress.so. &&
ln -s libcompress.so.0.0. libcompress.so.; }; })
(cd /tmp && { ln -s -f libcompress.so.0.0. libcompress.so ||
{ rm -f libcompress.so && ln -s libcompress.so.0.0. libcompress.so; }; })
install .libs/libcompress.lai /tmp/libcompress.la
install .libs/libcompress.a /tmp/libcompress.a
chmod /tmp/libcompress.a
ranlib /tmp/libcompress.a
...

  可以看到它安装了真实的动态链接库和静态链接库,同时也安装了 Libtool 库文件 libcompress.la,这个文件可以被后续的 Libtool 命令使用。

  在安装完成之后,可能还需要做一些配置才能正确使用,Libtool 的 finish 模式可以在这方面给我们一些提示 :

$ libtool -n --mode=finish /tmp

  这个命令的输出有点长,所以不在这里列出,如果不能正常的使用安装好的库,请运行这个命令。

5.使用 Libtool 库

  要在应用程序中使用前面创建的 Libtool 库很简单,准备一个源文件 main.c,它将使用 libcompress.la 库中定义的函数,代码如下 :

  清单 2: main.c

#include <stdio.h> 

extern int compress_file (const char *filename); 

int main (int argc, char *argv[])
{
if (argc < )
{
printf ("usage : %s file\n", argv[]);
return ;
}
return compress_file (argv[]);
}

  我们还是要先为 main.c 建立 Libtool 对象文件,这和前面的方法一样 :

$ libtool --mode=compile gcc -c main.c

。。。。。

参考博客:

  https://www.ibm.com/developerworks/cn/aix/library/1007_wuxh_libtool/index.html

libtool 创建库的工具的更多相关文章

  1. 使用 GNU Libtool 创建库

    这篇文档向大家介绍 GNU Libtool 的用途及基本使用方法,同时描述如何结合 GNU Autoconf 和 Automake 来使用 Libtool. 3 评论: 吴 小虎, 程序员, 天用唯勤 ...

  2. 顶级的JavaScript框架、库、工具及其使用

    几乎每隔一个星期,就有一个新的 JavaScript 库席卷网络社区!Web 社区日益活跃.多样,并在多个领域快速成长.想要研究每一个重要的 JavaScript 框架和库,是个不可能完成的任务.接下 ...

  3. 15个JavaScript本地存储技术的函数库和工具

    当构建更复杂的JavaScript应用程序运行在用户的浏览器是非常有用的,它可以在浏览器中存储信息,这样的信息可以被共享在不同的页面,浏览会话. 在最近的过去,这将有可能只被cookies文本文件保存 ...

  4. 加速编码的 JavaScript 库和工具

    JavaScript库是 一个提前写好的JavaScript文件库,它可以很容易的开发基于JavaScript的应用,特别是AJAX和一些其它的以web为中心的技术.运用JavaScript最基本的方 ...

  5. 性能:15个JavaScript本地存储技术的函数库和工具

    当构建更复杂的JavaScript应用程序运行在用户的浏览器是非常有用的,它可以在浏览器中存储信息,这样的信息可以被共享在不同的页面,浏览会话. 在最近的过去,这将有可能只被cookies文本文件保存 ...

  6. Visual Studio命令行创建库文件lib

    Visual Studio命令行创建库文件lib OS:win7 旗舰版SP1 64位 编译器: VS 2013 express 的cl 建一个文件Static_Lib.h,源代码如下 #ifndef ...

  7. Python 库/模块/工具收集

    1 算法 1.1 字符串处理 re 正则表达式的标准库. StringIO / cStringIO 以读写文件的方式来操作字符串(有点类似于内存文件). cStringIO 是 C 语言实现的,提供高 ...

  8. C/C++常用库及工具

    值得学习的C语言开源项目 - 1. Webbench Webbench是一个在Linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的 ...

  9. 各种 Python 库/模块/工具

    1 算法 1.1 字符串处理 re 正则表达式的标准库. StringIO / cStringIO 以读写文件的方式来操作字符串(有点类似于内存文件). cStringIO 是 C 语言实现的,提供高 ...

随机推荐

  1. centos7更换镜像源

    更换软件源 由于国外的软件源在yum 安装时比较慢,更换为国内的源,以阿里的源的更换方式 下载wgetyum install wget -y echo 备份当前的yum源mv /etc/yum.rep ...

  2. 2D情况下,复数的意义代表旋转

    4 x i x i = - 4 就是"4"在数轴上旋转了180度. 那么4 x i = 4i 就旋转了90度. 复数的意义就表示旋转 乘以-1,表示x正半轴的数,围绕原点,逆时针偏 ...

  3. Yii2 数据操作Query Builder查询数据

    Query Builder $rows = (new \yii\db\Query()) ->select(['dyn_id', 'dyn_name']) ->from('zs_dynast ...

  4. C++连接MySQL(Windows)

    一般来说,VS下采用微软自身的SQL Server是比较常见的做法,但SQL Server只适合学习,不适合真正应用.在此,我们选择MySQL作为后台数据库.C++语言本身并没有提供访问数据库的东西, ...

  5. GCC编译的几个步骤

    参考资料: https://blog.csdn.net/czg13548930186/article/details/78331692 一个C/C++文件要经过预处理(preprocessing).编 ...

  6. java 内存, 类加载g

    1. java 内存区域 方法区 虚拟机栈 本地方法栈 堆 程序计数器 其中 :  方法区  和 堆 是所有线程共享的 , 其他是线程隔离的 1.  程序计数器 : 可以看做是当前线程所执行的字节码的 ...

  7. python - package - bs4 - 美味汤

    Beautiful Soup 3 only works on Python 2.x, but Beautiful Soup 4 also works on Python 3.x. 你可能在寻找 Bea ...

  8. 关于 Web Api 2 认证与授权

    认证与授权 认证与授权,Authentication and Authorize,这个是两个不同的事.认证是对访问身份进行确认,如验证用户名和密码,而授权是在认证之后,判断是否具有权限进行某操作,如 ...

  9. Svn项目管理工具

    1       svn介绍 1.1     项目管理中的版本控制问题 通常软件开发由多人协作开发,如果对代码文件.配置文件.文档等没有进行版本控制,将会出现很多问题: 备份多个版本,占用磁盘空间大 解 ...

  10. 2019.01.02 bzoj2467: [中山市选2010]生成树(矩阵树定理)

    传送门 矩阵树定理模板题. 题意简述:自己看题面吧太简单懒得写了 直接构建出这4n4n4n个点然后按照题面连边之后跑矩阵树即可. 代码: #include<bits/stdc++.h> # ...