本节描述了编译和链接程序的某些方面。在以下示例中,使用 CC 编译三个源文件并链接目标文件以生成名为 prgrm 的可执行文件。
example% CC file1.cc file2.cc file3.cc -o prgrm |
在前面的示例中,编译器会自动生成加载器目标文件(file1.o、file2.o 和 file3.o),然后调用系统链接程序来为 prgrm 文件创建可执行程序。
编译后,目标文件(file1.o、file2.o 和 file3.o)仍保留不变。此约定让您易于重新链接和重新编译文件。
如果只编译了一个源文件,且在同一个操作中链接了程序,则对应的 .o 文件将会被自动删除。要保留所有 .o 文件,就不要在同一个操作中进行编译和链接,除非编译多个源文件。
如果编译失败,您将收到每个错误的对应消息。对于那些出现错误的源文件,不会生成 .o 文件,也不会生成可执行程序。
可以在不同的步骤中进行编译和链接。如果使用 -c 选项,将编译源文件并生成 .o 目标文件,但不创建可执行文件。如果不使用 -c 选项,编译器将调用链接程序。通过将编译和链接步骤分开,仅修复一个文件就不需要完整重新编译。以下示例显示了如何以独立的步骤编译一个文件并与其他文件链接:
example% CC -c file1.cc Make new object file example% CC -o prgrm file1.o file2.o file3.o Make executable file |
请确保链接步骤列出了生成完整程序所需的全部目标文件。如果在此步骤中缺少任何目标文件,链接将会失败,并出现 "undefined external reference" 错误(缺少例程)。
如果在不同的步骤中进行编译和链接,则使用3.3.3 编译时选项和链接时选项中所列的编译器选项时,一定要在编译和链接时保持一致。
如果使用其中任何选项编译子程序,必须在链接时也使用相同的选项:
如果使用 -library、-fast、-xtarget 和 -xarch 选项,必须确保包括相应的链接程序选项,如果编译和链接同时进行的话,就可以忽略这些链接程序选项。使用 —dryrun 查看这些选项的扩展以确定链接步骤中所需的选项。
如果使用 -p、-xpg 和 -xprofile,则在一个阶段中包括选项而在其他阶段中不包括相应选项并不影响程序的正确性,但不能进行文件配置。
如果使用 -g 和 -g0,则在一个阶段中包括选项而在其他阶段中不包括相应选项并不影响程序的正确性,但会影响调试程序的能力。对于没有使用其中任一选项编译但使用 -g 或 -g0 链接的模块,将无法正确调试。请注意,要对包含函数 main 的模块进行调试,通常必须使用 -g 选项或 -g0 选项对其进行编译。
在以下示例中,使用 -library=stlport4 编译器选项编译程序。
example% CC -library=stlport4 sbr.cc -c example% CC -library=stlport4 main.cc -c example% CC -library=stlport4 sbr.o main.o -o myprogram |
如果没有一致地使用 -library=stlport4,程序的某些部分将使用缺省的 libCstd,其他部分将使用可选的替换 STlport 库。生成的程序可能不进行链接,因此在任何情况下都不能正常运行。
如果程序使用模板,某些模板可以在链接时实例化。在这种情况下,来自最后一行(链接行)的命令行选项将用于编译实例化的模板。
使用新的 -m64 选项可指定目标编译的内存模型。生成的可执行文件仅能在运行 64 位内核的 Solaris OS 或 Linux OS 下的 64 位 UltraSPARC 或 x86 处理器上运行。64 位对象的编译链接和执行只能在支持 64 位执行的 Solaris 或 Linux OS 上进行。
使用 -V 选项可显示 CC 调用的每个程序的名称和版本号。使用 -v 选项可显示 CC 调用的完整命令行。
使用 —verbose=%all 可显示有关编译器的其他信息。
命令行上编译器无法识别的任何参数都解释为链接程序选项、目标程序文件名或库名称。
基本区别是:
对于无法识别的非选项(即前面没有短划线或加号),不会生成警告。(然而,这些选项会传递到链接程序。如果链接程序无法识别它们,将会生成链接程序错误消息。)
在以下示例中,请注意,CC 无法识别 -bit,该选项传递给链接程序 (ld),它会尝试解释该选项。因为一个字母的 ld 选项可以连在一起,所以链接程序将 -bit 视为 -b -i -t,所有这些都是合法的 ld 选项。这可能并不是您所希望看到的结果:
example% CC -bit move.cc < - -bit is not a recognized CC option CC: Warning: Option -bit passed to ld, if ld is invoked, ignored otherwise |
在下一个示例中,用户本想键入 CC 选项 -fast,但遗漏了前导短划线。编译器又一次将参数传递到链接程序,而链接程序将参数解释为文件名称:
example% CC fast move.cc < - The user meant to type -fast move.CC: ld: fatal: file fast: cannot open file; errno=2 ld: fatal: File processing errors. No output written to a.out |
C++ 编译器软件包由前端、优化器、代码生成器、汇编程序、模板预链接程序和链接编辑器组成。CC 命令会自动调用其中每个组件,除非使用命令行选项进行其他指定。
因为这些组件中的任何一个都可能生成错误,并且各个组件执行不同的任务,所以标识生成错误的组件是有意义的。可使用 -v 和 -dryrun 选项帮助解决此问题。
正如下表所示,不同编译器组件的输入文件拥有不同的文件名后缀。后缀建立了要进行的编译类型。有关文件后缀的含义,请参阅表 2–1。
表 2–2 C++ 编译系统的组件
组件 |
说明 |
使用说明 |
---|---|---|
前端(编译器预处理程序和编译器) | ||
代码优化器 |
-xO[2-5], -fast |
|
x86: 中间语言转换器 |
-xO[2-5], -fast |
|
SPARC: 汇编语言模板的内联扩展 |
指定 .il 文件 |
|
汇编程序 | ||
SPARC: 代码生成器、内联函数、汇编程序 |
|
|
ube |
x86: 代码生成器 |
-xO[2-5], -fast |
模板预链接程序 |
仅与 -instances=extern 选项一起使用 |
|
链接编辑器 |