C / C ++构建步骤

时间:2011-07-13 23:57:13

标签: c++ c build linker

有人可以说明,在使用lib_xxxx*nix-like命令时,./configure系统下make个库的链接阶段会发生什么?

实际上,我有一个具体问题:

与简单归档所需的.o目标文件相比,makefile中链接阶段背后会发生什么?

所以,我很确定,例如,任何C库都可以使用来自对象文件夹的命令组合在一起。{/ 1}}。

但我怀疑,这不是实际做的(因为makefile使用ar r libXYZ.a *.o等等,...)。

目的是什么以及如何完成?


编译libtool代码库时的链接阶段(在一个简单的例子中,例如,当不需要跨对象优化时)?

我怀疑您也可以将生成的对象文件放入存档中并将其用作静态库。

那么实际上隐藏了什么以及它的目的是什么?

谢谢。

5 个答案:

答案 0 :(得分:3)

并非所有ar实用程序都是相同的。 libtool隐藏了不同工具链所需的不同选项等,并且还支持创建共享库和静态库。

答案 1 :(得分:0)

您刚才所说的内容有很多不同的步骤:

  1. configure是一个用于设置构建环境的shell脚本

  2. make是一个调用编译器的各种实例(以及许多其他东西)的工具,具体取决于文件依赖性(依赖文件是否比目标文件更新)。

  3. 实际的“编译器”调用可能是你最感兴趣的:预处理,编译,汇编,你似乎对这些调用很满意。

  4. 最后,链接:所有目标文件都必须变成可执行文件:链接器将查找一个入口点(通常为main())。出现的所有符号(即函数和全局变量)必须使用其他目标文件中提供的实际代码的地址填充。一旦使用了本地目标文件中的所有符号,您可能仍然需要从库中提供“未定义的符号”。

  5. 因此,完整链接的结果通常是二进制文件,其中所有函数名称(可能)已被删除,并被代码的实际地址(更不用说PIC)替换或加载时共享库的引用。实质上,您的初始对象集合在链接二进制文件中不再可见。 (现代链接时优化实际上可能会非常严重地混淆和修剪您的代码。)另一方面,使用ar 创建的静态库只是原始未链接对象的集合所有符号都完好无损,可用于链接。

    嗯,这是对一个广大主题的一个非常忙碌的概述,所以自然这远远不够完整或有代表性,可能只是部分正确。如果您有特殊疑虑,请发表评论。

答案 2 :(得分:0)

我已经发布了关于here

的链接的详细说明

答案 3 :(得分:0)

ar仅在创建静态库时使用,静态库基本上只是一个对象文件的blob(因此,只能用作ld的输入 - 它们无法加载在运行时)。创建动态库是一个完全独立的过程,ld必须参与其中。

在除OS X之外的大多数UNIX系统上,libtool只是编译器和链接器的前端。幕后发生的大部分内容仅为(g)ccld

(在OS X上,libtool是一个单独的实用程序,用于创建.a个静态库和.dylib共享库文件。)

答案 4 :(得分:0)

So, I'm pretty sure that, for example, any C library can be combined together
using command like: ar r libXYZ.a *.o from the object folder.

But I suspect, that this is not what is actually done
(because the makefiles use libtool, etc, ...).

What's the purpose of that and how is it done?

libtool 的目的是隐藏调用系统实际库工具的复杂性(例如, ar nm ld lipo 等),目的是使程序包在类似POSIX的操作系统中更具可移植性。 ./ configure 脚本将在执行期间输出 libtool 脚本。软件包维护者不 使用 libtool (并依赖于使用正确的标志手动调用本机工具),但它确实使工作更容易。

如您所料,命令行工具 用于构建库,但隐藏在 libtool 之后。您可以通过检查 libtool 输出的 .la 库文件之一来了解有关如何完成此操作的更多信息,但这只是答案的一部分。其余的答案取决于库的使用平台,因为库可以交叉编译。

What happens behind the linking stage in makefiles compared to simply archiving
the required .o object files?

同样,答案取决于使用库的平台。对于静态库,使用 ar 归档它们通常就足够了。对于动态库,答案因系统而异。 libtool 脚本内置了此信息,因此在调用 make install 时会发生正确的事情。