9

关于以下链接: http ://www.archlinux.org/news/libpnglibtiff-rebuilds-move-from-testing/

有人可以向我解释为什么在更新其库之一后应该重建程序吗?

由于“主”文件根本没有更改,这有什么意义?

4

3 回答 3

17

如果所涉及的函数的签名没有改变,那么“重建”程序意味着必须重新链接目标文件。您不需要再次编译它们。

API 是描述库中公共函数接口的合约。当编译器生成代码时,它需要知道将什么类型的变量传递给每个函数,以及传递的顺序。它还需要知道返回类型,因此它知道将从函数返回的数据的大小和格式。编译代码时,库函数的地址可能表示为“库的开头,加上 140 个字节”。编译器不知道绝对地址,所以它只是指定了从库开头的偏移量。

库中,函数的内容(即实现)可能会发生变化。发生这种情况时,代码的长度可能会发生变化,因此函数的地址可能会发生变化。链接器的工作是了解每个函数的入口点所在的位置,并将这些地址填充到目标代码中以创建可执行文件。

另一方面,如果库中的数据结构发生了变化,并且库需要调用者来管理内存(这是一种不好的做法,但不幸的是很常见),那么您需要重新编译代码以便它能够解释这些变化。例如,如果您的代码用于malloc(sizeof(dataStructure))为大小翻倍的库数据结构分配内存,则需要重新编译代码,因为sizeof(dataStructure)它将具有更大的值。

于 2012-04-22T14:44:19.150 回答
6

有两种兼容性:API 和 ABI。

API 兼容性是关于其他程序可能依赖的函数和数据结构。例如,如果 0.1 版的 libfoo 定义了一个名为“hello_world()”的 API 函数,而 0.2 版将其删除,则任何依赖“hello_world()”的程序都需要更新才能使用新版本的 libfoo。

ABI 兼容性是关于如何在二进制文件中表示函数,特别是数据结构的假设。例如,如果 libfoo 0.1 还定义了一个recipe包含两个字段的数据结构:“instructions”和“ingredients”,并且 libfoo 0.2 在“ingredients”字段之前引入了“measurements”,那么基于 libfoo 0.1 recipes 的程序必须重新编译,因为“instructions”和“成分”字段可能位于 0.2 版本的 libfoo.so 二进制文件中的不同位置。

于 2012-04-22T14:48:10.893 回答
2

什么是“图书馆”?

如果“库”只是一个二进制文件(例如,动态链接库,又名“.dll”、“.dylib”或“.so”;或静态链接库,又名“.lib”或“.a”),则存在不需要重新编译,重新链接就足够了(在某些特殊情况下甚至可以避免)

另一方面,库通常不仅仅包含二进制对象——例如,头文件可能包含一些内联(或宏)逻辑。如果是这样,重新链接是不够的,您可能必须重新编译才能使用最新版本的库。

于 2012-04-22T14:53:25.333 回答