libtool 源码编译与使用

1,下载编译安装 libtool

bash 复制代码
sudo apt install help2man
bash 复制代码
git clone git://git.savannah.gnu.org/libtool.git
bash 复制代码
./bootstrap
mkdir build

cd build/
../configure --prefix=${PWD}/../../local_libt
make -j
make install

ls ../../local_libt

2. libtool 解决的问题和方法

Libtool 是一个 GNU 工具,用于简化和管理共享库的创建和使用。它解决了在不同平台上构建和使用共享库时遇到的许多常见问题。以下是 libtool 能解决的一些问题及其解决方法:

  1. 跨平台共享库构建

问题: 不同操作系统和编译器对共享库的构建和使用有不同的要求和命令。

解决方法:

Libtool 提供了一个统一的接口来创建和使用共享库。开发者只需使用 libtool 的命令,而不必关心底层平台的细节。

例如,使用 libtool --mode=compile 和 libtool --mode=link 来编译和链接库,libtool 会根据目标平台自动选择正确的编译和链接选项。

  1. 共享库版本管理

问题: 共享库的版本管理在不同平台上可能有不同的约定,导致版本冲突或不兼容。

解决方法:

Libtool 使用一个标准化的版本号系统,允许开发者指定接口版本和实现版本。它会自动生成适合目标平台的版本号格式。

例如,开发者可以使用 -version-info 选项来指定库的版本信息,libtool 会根据平台生成正确的库文件名。

  1. 处理符号链接和库路径

问题: 在开发和安装过程中,库文件的位置可能会改变,导致符号链接和库路径问题。

解决方法:

Libtool 生成的包装器脚本可以自动处理符号链接和库路径,确保程序在开发和安装后都能正确找到所需的库。

例如,libtool 会在构建时创建一个包装器脚本,设置正确的 LD_LIBRARY_PATH 或等效变量,以便程序在运行时能找到正确的库。

  1. 静态库和动态库的选择

问题: 在某些情况下,开发者可能需要选择使用静态库或动态库,但不同平台的实现方式不同。

解决方法:

Libtool 允许开发者在构建时选择是创建静态库、动态库还是两者都创建。它会根据平台自动选择合适的构建选项。

例如,使用 libtool --mode=link 时,可以通过选项指定是链接静态库还是动态库。

  1. 便携性和可移植性

问题: 编写可移植的构建脚本以支持多种平台和编译器是一项复杂的任务。

解决方法:

Libtool 提供了一个抽象层,隐藏了不同平台之间的差异,使得构建脚本可以在多个平台上无缝运行。

例如,开发者可以编写一个使用 libtool 的构建脚本,该脚本在 Linux、macOS 和 Windows 上都能正常工作,而不需要为每个平台编写特定的逻辑。

通过这些功能,libtool 大大简化了共享库的管理和使用,使得开发者可以专注于应用程序的开发,而不必担心底层平台的差异。

3. libtool 应用示例

将 lib 项目的源码 adddd.c 编译,链接成为动态库和静态库

源码:

adddd.c

cpp 复制代码
#include <stdio.h>

float adddd(float a, float b){

	float c;

	c = a + b;
	printf("addd=%7.4f", c);
	
	return c;
}

3.1 编译链接库

生成位置无关目标文件和普通目标文件

bash 复制代码
../local_libt/bin/libtool --mode=compile gcc -c adddd.c

完成这个编译动作,可以从输出发现,libtool 驱动 gcc 做了三件事情:

生成一个位置无关的目标文件: .libs/adddd.o,用于建立动态链接库;

生成一个普通的目标文件: adddd.o,用于建立静态链接库;

生成一个后缀为.lo 的文本文件:adddd.lo,用于说明用于建立动态链接库和动态链接的文件路径

3.2 链接生成链接库

生成静态链接库和动态链接库

bash 复制代码
../local_libt/bin/libtool --mode=link  gcc  adddd.lo -o libadddd.la -rpath /home/hipper/ex_libtool/tmp/ex/libdir

注意一个概念,libtool 库文件,后缀为la,是一个抽象了静态库和动态库的高层概念,库文件。

这里是 libadddd.la

3.3 安装链接库

将 la 等安装到指定目录,这个普通的lib开发的安装是同等动作,安装后方便使用。

bash 复制代码
../local_libt/bin/libtool --mode=install cp  libadddd.la /home/hipper/ex_libtool/tmp/ex/libdir

3.4 链接调用链接库中的函数

app.c

cpp 复制代码
#include <stdio.h>

extern float adddd(float a, float b);

int main()
{
	float x = 7.777f;
	float y = 1.111f;
	float z = 0.0f;

	z = adddd(x, y);

	printf("main: z = %7.4f", z);

	return 0;
}

3.4.1 编译生成 app 目标文件

bash 复制代码
../../local_libt/bin/libtool --mode=compile gcc -c app.c

3.4.2 链接生成 app 程序文件

3.4.2.1 使用链接库的动态库
bash 复制代码
../../local_libt/bin/libtool --mode=link gcc app.lo -o app_dynamic /home/hipper/ex_libtool/tmp/ex/libdir/libadddd.la

注意到这里链接的是 libaddd.so

如果是链接了 libadddd.a, 那么是静态链接,ldd就无法查看到,如下边 3.4.2.2 静态链接示例。

运行:

3.4.2.2 使用链接库的静态库
bash 复制代码
../../local_libt/bin/libtool --mode=link gcc app.lo -o app_ /home/hipper/ex_libtool/tmp/ex/libdir/libadddd.la -static-libtool-libs

3.5 卸载链接库

bash 复制代码
../../local_libt/bin/libtool --mode=uninstall rm /home/hipper/ex_libtool/tmp/ex/libdir/libadddd.la

所有相关文件都会被删除。

相关推荐
专注VB编程开发20年1 年前
VC++彻底理解链接器:四,重定位
java·开发语言·c++·链接器
私房菜1 年前
GNU链接脚本详解
linux·gnu·linker·链接器·链接器脚本