为什么要重新编译整个程序来更新库?

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

有人可以向我解释为什么一个程序在更新之后应该重build一个程序?

这是怎么回事,因为“主”文件根本没有改变?

Solutions Collecting From Web of "为什么要重新编译整个程序来更新库?"

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

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

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

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

有两种兼容性:API和ABI。

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

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

什么是“图书馆”?

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

otoh,库通常不仅仅包含二进制对象 – 例如,头文件可能包含一些内联(或宏)逻辑。 如果是的话,重新链接是不够的,你可能需要重新编译才能使用最新版本的lib。