Oracle® Developer Studio 12.5:C++ 用户指南

退出打印视图

更新时间: 2016 年 7 月
 
 

2.4 编译和链接

本节介绍了编译和链接程序的某些方面。在以下示例中,使用 CC 编译三个源文件并链接对象文件以生成名为 prgrm 的可执行文件。

example% CC file1.cc file2.cc file3.cc -o prgrm

2.4.1 编译和链接序列

在前面的示例中,编译器会自动生成加载器对象文件(file1.ofile2.ofile3.o),然后调用系统链接程序来为 prgrm 文件创建可执行程序。

编译后,对象文件(file1.ofile2.ofile3.o)仍保留不变。此约定使您易于重新链接和重新编译文件。


注 -  如果只编译了一个源文件,且在同一个操作中链接了程序,则对应的 .o 文件将会被自动删除。 要保留所有 .o 文件,就不要在同一个操作中进行编译和链接,除非编译多个源文件。

如果编译失败,您将收到每个错误的对应消息。对于那些出现错误的源文件,不会生成 .o 文件,也不会生成可执行程序。

2.4.2 分别编译和链接

可以在不同的步骤中进行编译和链接。-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" 错误(缺少例程)。

2.4.3 一致编译和链接

如果在不同的步骤中进行编译和链接,在使用编译时选项和链接时选项中所列的编译器选项时,一定要在编译和链接时保持一致。

如果使用其中任何选项编译子程序,必须在链接时也使用相同的选项:

  • 如果使用 -library-m64/-m32 选项进行编译,则必须在所有 CC 命令中使用相同的选项。

  • 如果使用 -compat-std 选项进行编译,则必须在所有 CC 命令中使用相同或等效选项。例如,-compat=5-std=sun03 是等效的。

  • 如果使用 -p-xpg-xprofile,则在一个阶段中包括选项而在其他阶段中不包括相应选项并不影响程序的正确性,但不能进行分析。

  • 如果使用 -g[n] 和 -xdebuginfo,则在一个阶段中包括选项而在其他阶段中不包括相应选项并不影响程序的正确性,但会影响调试程序的能力。对于没有使用其中任一选项编译但使用 -g[n] 或 -xdebuginfo 链接的模块,将无法正确调试。请注意,要对包含函数 main 的模块进行调试,通常必须使用 –g[n] 选项或 -xdebuginfo 选项对其进行编译。

在以下示例中,使用 -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 库。生成的程序可能不进行链接,因此在任何情况下都不能正常运行。

如果程序使用模板,某些模板可能会在链接时实例化。 在这种情况下,来自最后一行(链接行)的命令行选项将用于编译实例化的模板。

2.4.4 编译器命令行诊断

使用 -V 选项可显示 CC 调用的每个程序的名称和版本号。使用 -v 选项可显示 CC 调用的完整命令行。

使用 —verbose=%all 可显示有关编译器的其他信息。

命令行上编译器无法识别的任何参数都解释为链接程序选项、对象程序文件名或库名称。

基本区别是:

  • 对于无法识别的选项(前面有短划线 () 或加号 (+)),会生成警告。

  • 对于无法识别的非选项(即前面没有短划线或加号),不会生成警告。然而,这些选项会传递到链接程序。如果链接程序无法识别它们,将会生成链接程序错误消息。

在以下示例中,请注意,CC 无法识别 -bit,该选项传递给链接程序 (ld),它会尝试解释该选项。因为一个字母的 ld 选项可以连在一起,所以链接程序将 -bit 视为 -b -i -t,所有这些都是合法的 ld 选项。该结果可能并不是您所希望看到的结果:

example% CC -bit move.cc  -bit 不是可识别的编译器选项
CC: Warning: Option -bit passed to ld, if ld is invoked, ignored otherwise

在下一个示例中,用户本想键入 CC 选项 -fast,但遗漏了前导短划线。编译器又一次将参数传递到链接程序,而链接程序将参数解释为文件名称:

example% CC fast move.cc           <-用户原本打算键入 -fast
move.CC:
ld: fatal: file fast: cannot open file; errno=2
ld: fatal: File processing errors. No output written to a.out

2.4.5 了解编译器的组织

C++ 编译器软件包由前端、优化器、代码生成器、汇编程序、模板预链接程序和链接编辑器组成。CC 命令会自动调用其中每个组件, 除非使用命令行选项进行其他指定。

因为这些组件中的任何一个都可能生成错误,并且各个组件执行不同的任务,所以识别生成错误的组件可能很有帮助。使用 -v-dryrun 选项可以显示编译器执行期间的更多详细信息。

正如下表所示,不同编译器组件的输入文件拥有不同的文件名后缀。后缀建立了要进行的编译类型。有关文件后缀的含义,请参阅表 1

表 2  C++ 编译系统的组件
组件
说明
使用说明
ccfe
前端(编译器预处理程序和编译器)
iropt
代码优化器
-xO[2-5], -fast
inline
(SPARC) 汇编语言模板的内联扩展
指定 .il 文件
fbe
汇编程序
cg
(SPARC) 代码生成器、内联函数、汇编程序
-xO[1-5], -fast, -std=c++11
ube
(x86) 代码生成器
-xO[1-5], -fast, -std=c++11
CClink
模板预链接程序
仅与 -instances=extern 选项一起使用
ld
链接编辑器