本章提供了有关当前 Sun Studio C++ 编译器的一般信息:
本节简要介绍在 Sun Studio 12 Update 1 C++ 5.10 编译器发行版中引入的 C 编译器的新特性和新功能。有关详细的说明,请参见每项的交叉引用。
如果应用程序代码中包含带有参数或返回值(使用 _m128/_m64 数据类型)的函数,则在 x86 平台的 Solaris OS 上或 Linux OS 上,编译器创建的目标文件与以前的编译器版本不兼容。使用 .il 内联函数文件、汇编程序代码或调用这些函数的 asm 内联语句的用户也需要注意这种不兼容性。
为 x86 处理器 woodcrest、penryn、nehalem、core2 和 SPARC 处理器 ultraT2plus 及 sparc64vii 新增了 -xtarget 值。
为 x86 体系结构 ssse3、sse4_1、sse4_2 和 SPARC 体系结构 sparcima 新增了 -xarch 值。
为 SPARC 处理器 sparc64vii、ultraT2plus 新增了 —xchip 值。为 x86 处理器 core2、penryn、nehalem 新增了 —xchip 值。
-xprofile=collect 和 -xprofile=use 选项为动态链接的多线程应用程序的文件配置提供了改进的支持。
-xcrossfile=1 选项成为 -xipo=1 选项的别名。-xcrossfile=0 选项不再起任何作用。具体来说,-xcrossfile=1 和 -xcrossfile=0 等效于 -xipo=1。
在 Solaris 平台上,-xpec[=yes|no] 选项会生成可重新编译的 PEC 二进制文件,以用于自动调优系统 (Automatic Tuning System, ATS)。
-Y 选项不接受 i 作为参数。
在 SPARC 平台上,现在针对 x03 或更高优化级别隐式启用 -xdepend 选项,-fast 选项的扩展中不再包括此选项。
OpenMP 3.0 的支持包括 libmtsk 库。缺省情况下,OpenMP 程序将与此库链接,而不是与 Solaris OS 中的 libmtsk 库链接。
-xannotate[=yes|no](仅限 SPARC 平台)指示编译器创建二进制文件,之后这些文件可以由 binopt(1) 之类的二进制文件修改工具进行转换。
现在,在 x86 Solaris 平台上支持 -xia(区间运算)选项。
现在,在 x86 Solaris 平台和 Linux 平台上支持 -xipo_archive 选项。
-Qoption 选项不再接受 ube_ipa 作为参数。
-fast 选项的扩展现在包括 -D_MATHERR_ERRNO_DONTCARE。
现在支持用于显示并行化警告消息的 -xvpara 选项。
-sb、-sbfast、-xsb 和 -xsbfast 选项现已过时,默认忽略。
现在,在优化级别为 -O 或 -xO 的情况下,指定 -g 选项时,只要不同时指定 +d,编译器就会内联代码。
现在支持 pragma must_have_frame。
在标准 C++ 中,switch 语句中的 case 标签只能有一个关联值。Sun Studio C++ 编译器允许在某些编译器中出现扩展,称为 case 范围。
编译器通常在 /tmp 目录中创建临时文件。可以通过设置 TMPDIR 环境变量指定另一个目录。
现在支持函数的以下属性:_attribute_((const)) _attribute_((constructor)) _attribute_((destructor))
现在仅对 struct 类型和 enum 类型支持变量的以下属性:_attribute_((packed))
现在支持通用字符名称。
现在支持循环 pragma。
现在支持用户定义的宏 variadic 参数名称。
添加了用来指定预处理程序 include 文件的 -include filename 选项。
针对 x86 Solaris 平台进行编译时,有一些重要问题值得注意。
传统的 Sun 样式的并行 pragma 在 x86 上不可用。而改用 OpenMP。有关将传统并行化指令转换为 OpenMP 的信息,请参见《Sun Studio 12 Update 1:OpenMP API 用户指南》。
xarch 设置为 -sse、sse2、sse2a、sse3 或更高时编译的程序只能在提供这些扩展和功能的平台上运行。
从 Solaris 9 4/04 开始的 Solaris OS 发行版在 Pentium 4 兼容的平台上支持 SSE/SSE2。早期版本的 Solaris OS 不支持 SSE/SSE2。如果所运行的 Solaris OS 不支持由 -xarch 选定的指令集,则编译器无法为该指令集生成链接代码。
如果在不同的步骤中进行编译和链接,请始终使用编译器和相同的 -xarch 设置进行链接,以确保链接正确的启动例程。
在 x86 上得到的数值结果可能与在 SPARC 上得到的结果不同,这是由 x86 80 位浮点寄存器造成的。为了最大限度减少这些差异,请使用 -fstore 选项或使用 -xarch=sse2 进行编译(如果硬件支持 SSE2)。
Solaris 和 Linux 之间的数值结果也可能不同,因为内部数学库(例如,sin(x))并不相同。
使用 —m32 选项可针对 ILP32 32 位模型进行编译。使用 —m64 选项可针对 LP64 64 位模型进行编译。
ILP32 模型指定 C++ 语言的 int、long 和 pointer 数据类型的宽度均为 32 位。LP64 模型指定 long 和 pointer 数据类型均为 64 位。Solaris 和 Linux OS 还支持 LP64 内存模型下的大型文件和大型数组。
如果使用 —m64 进行编译,则生成的可执行文件仅能在运行 64 位内核的 Solaris OS 或 Linux OS 下的 64 位 UltraSPARC 或 x86 处理器上运行。64 位对象的编译、链接和执行只能在支持 64 位执行的 Solaris 或 Linux OS 上进行。
在 Solaris 系统上,从 Sun Studio 11 开始,Sun Studio 编译器编译的程序二进制文件都标记了体系结构硬件标志(表示由编译的二进制文件采用的指令集)。在运行时,会检查这些标记标志以确认二进制文件是否可在尝试在其上执行的硬件上运行。
如果程序不包含这些体系结构硬件标志,或者如果平台没有启用适当的功能或指令集扩展,则运行此程序可能会导致段故障或错误结果,且不会显示任何显式警告消息。
这一警告还会扩展到采用 .il 内联汇编语言函数或 __asm() 汇编程序代码(利用 SSE、SSE2、SSE2a、SSE3 和更新的指令及扩展)的程序。
C++ 编译器 (CC) 支持 C++ ISO 国际标准 ISO IS 14882:2003 编程语言-C++。当前发行版本附带的自述文件描述了与标准需求的所有差异。
在 SPARCTM 平台上,编译器提供了对 SPARC V8 和 SPARC V9(包括 UltraSPARC 实现)优化开发功能的支持。在 Prentice-Hall for SPARC International 发行的第 8 版 (ISBN 0-13-825001-4) 和第 9 版 (ISBN 0-13-099227-5) SPARC Architecture Manual 中定义了这些功能。
在本文档中,“标准”是指与上面列出的标准版本相一致。“非标准”或“扩展”是指这些标准的这些版本之外的功能。
负责标准的一方可能会不时地修订这些标准。C++ 编译器兼容的适用标准版本可能被修订或替换,这将会导致以后的 Sun C++ 编译器发行版本在功能上与旧的发行版本产生不兼容。
C++ 编译器的自述文件列出了关于编译器的重要信息,其中包括:
在手册印刷之后发现的信息
新特性和更改的特性
软件更正
问题和解决办法
限制和不兼容
可发送库
未实现的标准
可以在 Sun Developer Network Sun Studio 门户网站 http://developers.sun.com/sunstudio/documentation 上找到此 Sun Studio 发行版及早期发行版的 C++ 编译器自述文件。
联机手册 (man) 页提供了关于命令、函数、子例程以及收集这些信息的文档。
可以通过运行以下命令来显示手册页:
example% man topic |
在整个 C++ 文档中,手册页参考都以主题名称和手册节编号表示:通过 man CC 访问 CC(1)。例如,可在 man 命令中使用 -s 选项来访问 ieee_flags(3M) 指示的其他部分:
example% man -s 3M ieee_flags |
此发行版本的 C++ 支持使用英语以外的其他语言进行应用程序的开发,包括了大多数欧洲语言和日语。因此,您可以十分便捷地将应用程序从一种语言切换到另一种语言。此功能被称为国际化。
通常,C++ 编译器按如下方式实现国际化:
C++ 从国际化的键盘识别 ASCII 字符(也就是说,它具有键盘独立性和 8 位清除)。
C++ 允许使用本地语言打印某些消息。
C++ 允许在注释、字符串和数据中使用本地语言。
C++ 只支持符合扩展 UNIX 字符 (Extended UNIX Characte, EUC) 的字符集,在该字符集中,字符串内每个空字节是一个空字符,而字符串内每个 ascii 值为 "/" 的字节是一个 "/" 字符。
变量名称不能国际化,必须使用英文字符集。
您可以设置语言环境将应用程序从一种本地语言更改为另一种语言。关于这一点和其他本地语言支持功能的信息,请参见操作系统文档。
本章描述了如何使用 C++ 编译器。
任何编译器的主要用途是将高级语言(如 C++)编写的程序转换成目标计算机硬件可执行的数据文件。您可以使用 C++ 编译器完成以下任务:
将源文件转换成可重定位的二进制 (.o) 文件,以后链接到可执行文件、静态(归档)库 (.a) 文件(使用 – xar)或动态(共享)库 (.so) 文件中
将目标文件或库文件(或两者)链接或重链接成可执行文件
在运行时调试处于启用状态的情况下编译可执行文件 (-g)
使用运行时语句或过程级文件配置 (-pg) 编译可执行文件
本节简要概述了如何使用 C++ 编译器编译和运行 C++ 程序。有关命令行选项的完整参考,请参见16.8 使用 dlopen 从 C 程序访问 C++ 库。
本章中的命令行示例说明了 CC 的用法。打印输出可能会稍有不同。
生成和运行 C++ 程序的基本步骤包括:
使用编辑器创建 C++ 源文件(后缀为表 2–1 中所列有效后缀之一)
调用编译器来生成可执行文件
通过输入可执行文件的名称来启动程序
以下程序在屏幕上显示消息:
example% cat greetings.cc #include <iostream> int main() { std::cout << “Real programmers write C++!” << std::endl; return 0; } example% CC greetings.cc example% ./a.out Real programmers write C++! example% |
在此示例中, CC 编译源文件 greetings.cc,并且在缺省情况下编译可执行程序生成文件 a.out。要启动该程序,请在命令提示符下键入可执行文件的名称 a.out。
传统的方法是,UNIX 编译器为可执行文件命名 a.out。每次编译都写入到同一个文件是比较笨拙的方法。另外,如果已经有这样一个文件存在,下次运行编译器时该文件将被覆盖。因此,改用 -o 编译器选项来指定可执行输出文件的名称,如以下示例所示:
example% CC– o greetings greetings.cc |
在此示例中,-o 选项通知编译器将可执行代码写入文件 greetings。(由单独源文件组成的程序通常提供无后缀的源文件名称。)
也可以在每次编译后使用 mv 命令来为缺省的 a.out 文件重命名。无论是哪种方法,都可以通过键入可执行文件的名称来运行程序:
example% ./greetings Real programmers write C++! example% |
本章其余部分讨论了 CC 命令使用的约定、编译器源代码行指令和其他有关编译器的使用问题。
CC [options] [source-files] [object-files] [libraries] |
选项是前缀为短划线 (–) 或加号 (+) 的选项关键字。某些选项带有参数。
通常,编译器选项的处理顺序是从左到右,从而允许有选择地覆盖宏选项(包含其他选项的选项)。在大多数的情况下,如果您多次指定同一个选项,那么最右边的赋值会覆盖前面的赋值,而不会累积。注意以下特殊情况:
所有链接程序选项和 -features、–I -l、– L、-library、–pti、–R、-staticlib、-U、-verbose、-xdumpmacros 和 -xprefetch 选项都会累积,但它们不会覆盖。
所有 –U 选项都在所有 –D 选项之后处理。
源文件、目标文件和库按它们在命令行上出现的顺序编译并链接。
在以下示例中,在启用了运行时调试的情况下,使用 CC 编译两个源文件(growth.C 和 fft.C)来生成名为 growth 的可执行文件:
example% CC -g -o growth growth.C fft.C |
命令行上附加在文件名后面的后缀确定了编译器处理文件的方式。如果文件名称的后缀没有在下表中列出,或文件名称没有后缀,那么都要传递到链接程序。
表 2–1 C++ 编译器识别的文件名称后缀
后缀 |
语言 |
操作 |
---|---|---|
C++ |
以 C++ 源文件编译,将目标文件放在当前目录中;目标文件的缺省名称是源文件名称加上 .o 后缀。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
将预处理程序输出文件作为 C++ 源文件处理。操作与 .c 后缀相同。 |
|
汇编程序 |
使用汇编程序的汇编源文件。 |
|
汇编程序 |
使用 C 语言预处理程序和汇编程序的汇编源文件。 |
|
内联扩展 |
处理内联扩展的汇编内联模板文件。编译器将使用模板来扩展选定例程的内联调用。(内联模板文件是特殊的汇编文件。请参见 inline(1) 手册页。 |
|
目标文件 |
将目标文件传递到链接程序。 |
|
静态(归档)库 |
将目标库名传递到链接程序。 |
|
动态(共享)库 |
将共享对象的名称传递到链接程序。 |
C++ 编译器在命令行上接受多个源文件。编译器编译的单个源文件和其直接或间接支持的任何文件一起统称为编译单元。C++ 将每个源作为一个单独的编译单元处理。
缺省情况下,该编译器不使用高速缓存。只有指定了 -instances=extern 时,它才使用高速缓存。如果编译器使用高速缓存,它会检查高速缓存目录的版本,并在遇到高速缓存版本问题时发出错误消息。以后的 C++ 编译器也会检查缓存的版本。例如,具有不同模板缓存版本标识的未来版本编译器在处理此发行版本的编译器生成的缓存目录时,会发出与以下消息类似的错误:
Template Database at ./SunWS_cache is incompatible with this compiler |
编译器遇到新版本的编译器生成的缓存目录时,也会发出类似的错误。
升级编译器时,最好清除缓存。可对包含模板高速缓存目录(大多数情况下,模板高速缓存目录名为 SunWS_cache))的每个目录运行 CCadmin -clean。也可以使用 rm -rf SunWS_cache。
本节描述了编译和链接程序的某些方面。在以下示例中,使用 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 选项一起使用 |
|
链接编辑器 |
本节讨论了关于预处理 C++ 编译器所特有的指令的信息。
预处理程序指令 pragma 是 C++ 标准的一部分,但每个编译器中,pragma 的形式、内容和含义都不相同。有关 C++ 编译器可识别的 pragma 的详细信息,请参见附录 B。
Sun C++ 还支持 C99 关键字 _Pragma。这两种调用
#pragma dumpmacros(defs) _Pragma("dumpmacros(defs)") |
是等效的。要使用 _Pragma 而不是 #pragma,请将 pragma 文本写成文字字符串(用括号括起来作为 _Pragma 关键字的一个参数)。
C++ 编译器接受以下形式的 #define 预处理程序指令。
#define identifier (...) replacement_list #define identifier (identifier_list, ...) replacement_list |
如果列出的宏参数以省略号结尾,那么该宏的调用允许使用除了宏参数以外的其他更多参数。其他参数(包括逗号)收集到一个字符串中,宏替换列表中的名称 __VA_ARGS__ 可以引用该字符串。以下示例说明了如何使用可变参数列表的宏。
#define debug(...) fprintf(stderr, __VA_ARGS__) #define showlist(...) puts(#__VA_ARGS__) #define report(test, ...) ((test)?puts(#test):\ printf(__VA_ARGS__)) debug(“Flag”); debug(“X = %d\n”,x); showlist(The first, second, and third items.); report(x>y, “x is %d but y is %d”, x, y); |
其结果如下:
fprintf(stderr, “Flag”); fprintf(stderr, “X = %d\n”, x); puts(“The first, second, and third items.”); ((x>y)?puts(“x>y”):printf(“x is %d but y is %d”, x, y)); |
附录中的表 A–2 介绍了预定义的宏。可以在 #ifdef 这样的预处理程序条件中使用这些值。+p 选项可防止自动定义 sun、unix、sparc 和 i386 预定义宏。
发出警告后,#error 指令不再继续编译。指令原来的行为是发出警告并继续编译。其新行为(和其他编译器保持一致)是发出错误消息并立即停止编译。编译器退出并报告失败。
编译需要的内存量取决于多个参数,包括:
每个过程的大小
优化级别
为虚拟内存设置的限制
磁盘交换文件的大小
在 SPARC 平台上,如果优化器用完了所有内存,那么它将通过在较低优化级别上重试当前过程来尝试恢复。然后优化器将以在命令行上通过 -xOlevel 选项指定的原始级别恢复后续例程。
如果编译包括大量例程的单独源文件,编译器可能会用完所有内存或交换空间。可以尝试降低优化级别。或者,将最大的过程分为其自身的单独文件。
swap -s 命令用于显示可用的交换空间。有关更多信息,请参见 swap(1M) 手册页。
以下示例演示了 swap 命令的用法:
example% swap -s total: 40236k bytes allocated + 7280k reserved = 47516k used, 1058708k available |
使用 mkfile(1M) 和 swap(1M) 可增加工作站上交换空间的大小。(您必须成为超级用户才能执行该操作)。mkfile 用于命令创建特定大小的文件,而 swap -a 用于将文件增加到系统交换空间:
example# mkfile -v 90m /home/swapfile /home/swapfile 94317840 bytes example# /usr/sbin/swap -a /home/swapfile |
在 -xO3 或更高级别编译非常大型的例程(一个过程中有数几千行代码)需要大量内存。在这种情况下,系统性能可能降低。您可以通过限制单个进程的可用虚拟内存量来控制这种情况。
要在 sh shell 中限制虚拟内存,请使用 ulimit 命令。有关更多信息,请参见 sh(1) 手册页。
以下示例显示了如何将虚拟内存限制为 4GB:
example$ ulimit -d 4000000 |
在 csh shell 中,可使用 limit 命令限制虚拟内存。有关更多信息,请参见 csh(1) 手册页。
下一个示例也显示了如何将虚拟内存限制为 4GB:
example% limit datasize 4G |
这些示例都会使优化器在数据空间达到 4GB 时尝试恢复。
虚拟空间的限制不能大于系统总的可用交换空间。在实际使用时,虚拟空间的限制要足够的小,以允许在大型编译过程中正常使用系统。
请确保编译不会消耗一半以上的交换空间。
有 8GB 的交换空间时,请使用以下命令:
在 sh shell 中:
example$ ulimit -d 4000000 |
在 csh shell 中:
example% limit datasize 4G |
最佳设置取决于要求的优化程度、实际内存量和可用的虚拟内存量。
工作站至少应有 1 GB 内存,推荐使用 2 GB。有关详细的要求,请参见产品发行版自述文件 (http://developers.sun.com/sunstudio/documentation/)。
不应将 Unix strip 命令用于 C++ 目标文件,因为这会导致这些目标文件不可用。
可以通过定义特殊的 shell 别名、使用 CCFLAGS 环境变量或使用 make 来简化复杂的编译器命令。
以下示例为带有常用选项的命令定义了别名。
example% alias CCfx "CC -fast -xnolibmil" |
以下示例使用了别名 CCfx。
example% CCfx any.C |
现在命令 CCfx 等效于:
example% CC -fast -xnolibmil any.C |
可以通过设置 CCFLAGS 变量来指定选项。
可以在命令行中显式使用 CCFLAGS 变量。以下示例说明了如何设置 CCFLAGS (C Shell):
example% setenv CCFLAGS ’-xO2 -m64’ |
以下示例显式使用了 CCFLAGS。
example% CC $CCFLAGS any.cc |
使用 make 时,如果像上述示例那样设置 CCFLAGS 变量,且 makefile 的编译规则是隐式的,那么调用 make 的结果就相当于下面的编译:
CC -xO2 -m64 files...
make 实用程序是功能非常强大的程序开发工具,可以方便地与所有 Sun 编译器一起使用。有关更多信息,请参见 make(1S) 手册页。
使用 makefile 的隐式编译规则(即没有 C++ 编译行)时,make 程序会自动使用 CCFLAGS。
本章解释了如何使用命令行 C++ 编译器选项,并按功能汇总它们的使用。A.2 选项参考中对这些选项进行了详细说明。
下表显示了本书中使用的典型选项语法格式的示例。
表 3–1 选项语法格式示例
语法格式 |
示例 |
---|---|
-选项 |
–E |
–选项值 |
–Ipathname |
–选项=值 |
–xunroll=4 |
–选项 值 |
–o filename |
圆括号、大括号、方括号、"|" 或 "-" 字符以及省略号是选项说明中使用的元字符,而不是选项自身的一部分。有关用法语法的详细说明,请参见本手册前言中的印刷约定。
C++ 编译器选项的某些通用指南:
– llib 选项用于与库 liblib.a(或 liblib.so)进行链接。较稳妥的方式是总是将 – llib 放在源文件和目标文件后面,这样可以确保库搜索顺序。
通常,编译器选项的处理顺序是从左到右(但 – U 选项在所有 – D 选项之后处理这种情况除外),从而可以有选择地覆盖宏选项(包括其他选项的选项)。此规则不适用于链接程序选项。
-features、–I -l、–L、-library、–pti、–R、-staticlib、-U、-verbose 和 -xprefetch 选项会累积,但不会覆盖。
-D 选项会累积,但相同名称的多个 -D 选项会互相覆盖。
在本节中,编译器选项按功能分组以便提供快速参考。有关各个选项的详细说明,请参阅附录 A。
这些选项适用于除了特别注明之外的所有平台;基于 SPARC 的系统上的 Solaris OS 特有的功能标识为 SPARC,基于 x86 的系统上的 Solaris OS 特有的功能标识为 x86。
选项 |
操作 |
---|---|
–compat |
设置编译器的主发行版本兼容模式。 |
+e{0|1} |
控制虚拟表的生成。 |
–g |
用于与调试一起使用的编译。 |
–KPIC |
生成位置独立的代码。 |
–Kpic |
生成位置独立的代码。 |
–mt |
编译和链接多线程代码。 |
-xaddr32 |
将代码限定于 32 位地址空间 (x86/x64) |
-xarch |
指定目标体系结构。 |
–xcode=a |
(SPARC) 指定代码地址空间。 |
–xMerge |
(SPARC) 将数据段和文本段合并。 |
-xtarget |
指定目标系统。 |
–xmodel |
针对 Solaris x86 平台修改 64 位对象形式 |
+w |
标识可能产生不可预料结果的代码。 |
+w2 |
发出由 +w 发出的所有警告以及关于技术违规的警告,这些技术违规可能是无害的,但可能会降低程序的最大可移植性。 |
-xregs |
如果编译器可以使用更多的寄存器用于临时存储(临时寄存器),那么编译器将能生成速度更快的代码。该选项使得附加临时寄存器可用,而这些附加寄存器通常是不适用的。 |
-z arg |
链接程序选项。 |
选项 |
操作 |
---|---|
–instlib |
禁止生成已出现在指定库中的模板实例。 |
-m32|-m64 |
指定编译的二进制对象的内存模型。 |
-xinstrument |
编译程序并为其提供程序设备以便 Thread Analyzer 对其进行分析。 |
–xjobs |
设置编译器可以为完成工作而创建的进程数量。 |
–xpch |
可以减少应用程序的编译时间,该应用程序的源文件共享一组共同的 include 文件。 |
–xpchstop |
指定在使用 -xpch 选项创建预编译头文件时要考虑的最后一个 include 文件。 |
–xprofile_ircache |
(SPARC) 重新使用在执行 -xprofile=collect 期间保存的编译数据。 |
–xprofile_pathmap |
(SPARC) 支持单个配置文件目录中有多个程序或共享库。 |
选项 |
操作 |
---|---|
-fast | |
-m32|-m64 |
指定编译的二进制对象的内存模型。 |
-mt | |
-xarch | |
-xautopar | |
-xhwcprof | |
-xipo | |
-xlinkopt | |
-xmemalign | |
-xopenmp | |
-xpagesize | |
-xpagesize_heap | |
-xpagesize_stack | |
-xpg | |
-xprofile | |
-xvector |
选项 |
操作 |
---|---|
+d |
不扩展 C++ 内联函数。 |
–dryrun |
显示但不编译由驱动程序传递到编译器的选项。 |
–E |
仅对 C++ 源文件运行预处理程序,并将结果发送到 stdout。不编译。 |
–g |
用于与调试一起使用的编译。 |
–g0 |
编译以便进行调试,但不禁用内联。 |
–H |
打印包含文件的路径名称。 |
–keeptmp |
保留编译时创建的临时文件。 |
–migration |
解释可以从早期编译器获得有关移植信息的位置。 |
–P |
仅预处理源文件,输出到 .i 文件。 |
–Qoption |
直接将选项传递到编译阶段。 |
–readme |
显示联机 README 文件的内容。 |
–s |
从可执行文件中去掉符号表,这样可以保护调试代码的能力。 |
–temp=dir |
为临时文件定义目录。 |
–verbose=vlst |
控制编译器详细内容。 |
-xcheck |
对栈溢出增加一个运行时检查。 |
-xdumpmacros |
打印诸如定义、定义及未定义的位置和已使用的位置的宏信息。 |
–xe |
仅检查语法和语义错误。 |
–xhelp=flags |
显示编译器选项汇总列表。 |
–xport64 |
对 32 位体系结构到 64 位体系结构的移植过程中的常见问题发出警告。 |
选项 |
操作 |
---|---|
-fma |
(SPARC) 启用自动生成浮点乘加指令。 |
–fns[={no|yes}] |
(SPARC) 禁用或启用 SPARC 非标准浮点模式。 |
–fprecision=p |
x86: 设置浮点精度模式。 |
–fround=r |
设置启动时生效的 IEEE 舍入模式。 |
–fsimple=n |
设置浮点优化首选项。 |
–fstore |
x86: 强制浮点表达式的精度。 |
–ftrap=tlst |
设置启动时生效的 IEEE 陷阱操作模式。 |
–nofstore |
x86: 禁用表达式的强制精度。 |
–xlibmieee |
使 libm 在异常情况下对于数学例程返回 IEEE 754 值。 |
选项 |
操作 |
---|---|
–compat |
设置编译器的主发行版本兼容模式。 |
–features=alst |
启用或禁用各种 C++ 语言特性。 |
-xchar |
在 char 类型定义为无符号的系统上,简化代码的移植。 |
–xldscope |
控制变量和函数定义的缺省链接程序范围,以创建更快更安全的共享库。 |
–xthreadvar |
(SPARC) 更改缺省的线程局部存储访问模式。 |
-xtrigraphs |
启用三字母序列的识别。 |
–xustr |
启用识别由 16 位字符构成的文本字符串。 |
选项 |
操作 |
---|---|
–Bbinding |
请求符号、动态或静态库链接。 |
–d{y|n} |
允许或不允许整个可执行文件的动态库。 |
–G |
生成动态共享库来取代可执行文件。 |
–hname |
为生成的动态共享库指定内部名称。 |
–i |
通知 ld(1) 忽略任何 LD_LIBRARY_PATH 设置。 |
–Ldir |
将 dir 添加到要在其中搜索库的目录列表。 |
–llib |
将 liblib.a 或 liblib.so 添加到链接程序的库搜索列表。 |
–library=llst |
强制将特定库和相关文件包含到编译和链接中。 |
–mt |
编译和链接多线程代码。 |
–norunpath |
不将库的路径生成到可执行文件中。 |
–Rplst |
将动态库搜索路径生成到可执行文件中。 |
–staticlib=llst |
说明哪些 C++ 库是静态链接的。 |
–xar |
创建归档库。 |
-xbuiltin[=opt] |
启用或禁用标准库调用的更多优化。 |
-xia |
(Solaris) 链接合适的区间运算库并设置适当的浮点环境。 |
-xlang=l[,l] |
包含适当的运行库,并确保指定语言的正确运行时环境。 |
–xlibmieee |
使 libm 在异常情况下对于数学例程返回 IEEE 754 值。 |
–xlibmil |
内联选定的 libm 库例程以进行优化。 |
–xlibmopt |
使用优化数学例程的库。 |
–xnolib |
禁止链接缺省系统库。 |
–xnolibmil |
在命令行上取消 – xlibmil。 |
–xnolibmopt |
不使用数学例程库。 |
以下选项要么当前已废弃所以编译器不再接受它们,要么将从以后的发行版中删除。
选项 |
操作 |
---|---|
-library=%all |
废弃的选项,在以后的发行版本中将被删除。 |
-xlic_lib=sunperf |
使用 —library=sunperf 可链接到 Sun 性能库。 |
-xlicinfo |
已过时。 |
–noqueue |
禁用许可证队列。 |
-ptr |
编译器忽略。以后的编译器发行版本可以使用其他行为来重用该选项。 |
-sb、—sbfast、—xsb、—xsbfast |
已过时,默认忽略。 |
-vdelx |
废弃的选项,在以后的发行版本中将被删除。 |
-x386 |
使用适当的 —xtarget 选项。 |
-x486 |
使用适当的 —xtarget 选项。 |
-xcg89 |
使用 -xtarget=ss2。 |
-xcrossfile |
改用 -xipo。 |
-xnativeconnect |
已废弃,没有替代选项。 |
-xprefetch=yes |
改用 -xprefetch=auto,explicit。 |
-xprefetch=no |
改用 -xprefetch=no%auto,no%explicit。 |
-xvector=yes |
改用 -xvector=lib。 |
-xvector=no |
改用 -xvecttor=none。 |
选项 |
操作 |
---|---|
–c |
仅编译;生成目标 (.o) 文件,但抑制链接。 |
–dryrun |
显示但不编译由驱动程序传递到编译器的所有命令行。 |
–E |
仅对 C++ 源文件运行预处理程序,并将结果发送到 stdout。不编译。 |
-erroff |
禁止编译器警告消息。 |
-errtags |
显示每条警告消息的消息标记。 |
-errwarn |
如果发出指示的警告消息,cc 将以失败状态退出。 |
-filt |
禁止编译器应用到链接程序错误消息的过滤。 |
–G |
生成动态共享库来取代可执行文件。 |
–H |
打印包含文件的路径名称。 |
–migration |
解释可以从早期编译器获得有关移植信息的位置。 |
–o filename |
将输出文件或可执行文件的名称设置为 filename。 |
–P |
仅预处理源文件,输出到 .i 文件。 |
–Qproduce sourcetype |
使 CC 驱动程序生成类型为 sourcetype 的输出。 |
–s |
从可执行文件去掉符号表。 |
–verbose=vlst |
控制编译器详细内容。 |
+w |
必要时打印附加警告。 |
+w2 |
适当时仍打印更多警告。 |
–w |
禁止警告消息。 |
-xdumpmacros |
打印诸如定义、定义及未定义的位置和已使用的位置的宏信息。 |
-xe |
对源文件仅执行语法和语义检查,但不生成任何对象或可执行代码。 |
–xhelp=flags |
显示编译器选项汇总列表。 |
–xhelp=readme |
显示联机 README 文件的内容。 |
–xM |
输出 makefile 依赖性信息。 |
–xM1 |
生成依赖性信息,但排除 /usr/include。 |
–xtime |
报告每个编译阶段的执行时间。 |
–xwe |
将所有的警告转换为错误。 |
-z arg |
选项 |
操作 |
---|---|
–fast |
选择编译选项的组合以优化某些程序的执行速度。 |
-fma |
(SPARC) 启用自动生成浮点乘加指令。 |
-g |
指示编译器和链接程序准备程序以进行性能分析(以及调试)。 |
–s |
从可执行文件去掉符号表。 |
-m32|-m64 |
指定编译的二进制对象的内存模型。 |
-xalias_level |
启用编译器执行基于类型的别名分析和优化。 |
–xarch=isa |
指定目标体系结构指令集。 |
-xbinopt |
准备二进制文件以便以后进行优化、转换和分析。 |
-xbuiltin[=opt] |
启用或禁用标准库调用的更多优化。 |
–xcache=c |
(SPARC) 定义优化器的目标高速缓存属性。 |
–xcg89 |
为通用 SPARC v7 体系结构编译。 |
–xcg92 |
为 SPARC V8 体系结构编译。 |
–xchip=c |
指定目标处理器芯片。 |
–xF |
启用函数和变量的链接程序重新排序。 |
-xinline=flst |
指定用户编写的哪些例程可以被优化器内联 |
-xipo |
执行过程间的优化。 |
–xlibmil |
内联选定的 libm 库例程以进行优化。 |
–xlibmopt |
使用优化数学例程的库。 |
–xlinkopt |
(SPARC) 在对目标文件进行优化的基础上对生成的可执行文件或动态库执行链接时优化。 |
–xmemalign=ab |
(SPARC) 指定假定的最大内存对齐以及未对齐的数据访问的行为。 |
–xnolibmil |
在命令行上取消 – xlibmil。 |
–xnolibmopt |
不使用数学例程库。 |
–xOlevel |
将优化级别指定为 level。 |
–xpagesize |
设置栈和堆的首选页面大小。 |
-xpagesize_heap |
设置堆的首选页面大小。 |
-xpagesize_stack |
设置栈的首选页面大小。 |
-xprefetch[=lst] |
在支持预取的体系结构上启用预取指令。 |
-xprefetch_level |
控制 -xprefetch=auto 设置的自动插入预取指令的主动性。 |
–xprofile |
收集运行时文件配置数据或使用运行时文件配置数据进行优化。 |
–xregs=rlst |
控制临时寄存器的使用。 |
–xsafe=mem |
(SPARC) 不允许有基于内存的陷阱。 |
–xspace |
(SPARC) 不允许会增大代码大小的优化。 |
–xtarget=t |
指定目标指令集和优化系统。 |
–xthreadvar |
更改缺省的线程局部存储访问模式。 |
–xunroll=n |
启用在可能的场合下解开循环。 |
–xvis |
(SPARC) 使编译器可以识别 VISTM 指令集中定义的汇编语言模板。 |
选项 |
操作 |
---|---|
–Dname[= def] |
为预处理程序定义符号 name。 |
–E |
仅对 C++ 源文件运行预处理程序,并将结果发送到 stdout。不编译。 |
-H |
打印包含文件的路径名称。 |
–P |
仅预处理源文件,输出到 .i 文件。 |
–Uname |
删除预处理程序符号 name 的初始定义。 |
–xM |
输出 makefile 依赖性信息。 |
–xM1 |
生成依赖性信息,但排除 /usr/include。 |
选项 |
操作 |
---|---|
–p |
准备目标代码来收集数据以使用 prof 进行文件配置。 |
–xa |
为文件配置生成代码。 |
–xpg |
编译以便使用 gprof 配置程序进行文件配置。 |
–xprofile |
收集运行时文件配置数据或使用运行时文件配置数据进行优化。 |
选项 |
操作 |
---|---|
–migration |
解释可以从早期编译器获得有关移植信息的位置。 |
–xhelp=flags |
显示编译器选项汇总列表。 |
–xhelp=readme |
显示联机 README 文件的内容。 |
选项 |
操作 |
---|---|
-H |
打印包含文件的路径名称。 |
–Ipathname |
将 pathname 添加到 include 文件搜索路径。 |
-I- |
更改包含文件搜索规则 |
–xM |
输出 makefile 依赖性信息。 |
–xM1 |
生成依赖性信息,但排除 /usr/include。 |
选项 |
操作 |
---|---|
–instances=a |
控制模板实例的放置和链接。 |
–template=wlst |
启用或禁用各种模板选项。 |
选项 |
操作 |
---|---|
–mt |
编译和链接多线程代码。 |
–xsafe=mem |
(SPARC) 不允许有基于内存的陷阱。 |
–xthreadvar |
(SPARC) 更改缺省的线程局部存储访问模式。 |