使用 XL C/C++ 编辑、编译和链接程序

编译器阶段
编辑 C 和 C++ 源文件
使用 XL C/C++ 进行编译
编译并行化的 XL C/C++ 应用程序
XL C/C++ 输入文件
XL C/C++ 输出文件
指定编译器选项
链接 XL C/C++ 程序
在单独的步骤中编译和链接
动态和静态链接

基本的 C 和 C++ 程序开发就是编辑、编译和链接(缺省情况下与编译合并为单个步骤)和运行过程的重复循环。

先决条件信息:
  1. 必须首先确保正确地配置所有 Linux 设置(例如,某些环境变量和存储器限制),然后才能使用此编译器。有关更多信息,请参阅环境变量和 XL C/C++
  2. 要更多地了解有关编写 C 和 C++ 程序的信息,请参阅 XL C/C++ Advanced Edition V8.0 for Linux Language Reference

编译器阶段

典型的编译器调用命令按顺序执行下列某些或全部程序。对于链接时优化,将在编译期间多次执行某些阶段。当每个程序运行时,结果按顺序发送至下一个步骤。

  1. 预处理器
  2. 编译器,包括以下阶段:
    1. 前端解析和语义分析
    2. 循环变换
    3. 过程间分析
    4. 优化
    5. 寄存器分配
    6. 最终的汇编
  3. 汇编程序(用于在进行预处理后的 .s 文件和 .S 文件)
  4. 链接程序 ld

要查看编译器如何单步执行这些阶段,当编译应用程序时指定 -qphsinfo-v 编译器选项。

编辑 C 和 C++ 源文件

要创建 C 和 C++ 源程序,您可以使用任何可用的文本编辑器,如 vi emacs。除非配置文件-qsourcetype 编译器选项定义了其它非标准文件名后缀,否则源程序必须使用可识别的文件名后缀。请参阅XL C/C++ 输入文件,以获取 XL C/C++ 可识别的文件名后缀列表。

要使 C 或 C++ 源程序成为有效的程序,它必须符合在 XL C/C++ Advanced Edition V8.0 for Linux Language Reference 中指定的语言定义。

使用 XL C/C++ 进行编译

要编译源程序,请通过下面显示的语法使用一个编译器调用命令:

阅读语法图跳过直观语法图>>-compiler_invocation------------------------------------------>
 
   .-----------------------------------------.
   | .---------------------.                 |
   V V                     |                 |
>------+-----------------+-+----input_file---+-----------------><
       '-cmd_line_option-'
 

编译器调用命令执行所有必要的步骤来编译 C 或 C++ 源文件、汇编任何 .s.S 文件并将目标文件和库链接至可执行程序。

为了新的 C 或 C++ 应用程序能够工作,您应考虑使用 xlC 或 xlc++ 或者其线程安全等效项进行编译。

xlCxlc++ 将编译诸如 C 或 C++ 的程序源代码,但因为当 C 编译器调用链接程序时未指定 C++ 代码所需要的库,所以使用 xlc 编译 C++ 文件可能导致链接或运行时错误。其它基本编译器调用命令的目的主要是为 C 或 C++ 语言的不同级别和扩展提供显式编译支持。

除了基本编译器调用命令以外,XL C/C++ 还提供了许多基本编译器调用的专用变体。基本编译器调用的变体是通过将后缀连接至该调用命令的名称来命名的。调用变体的后缀意义为:

_r
线程安全调用变体,它支持将 POSIX Pthread API 用于多线程应用程序,包括使用 -qsmp 或使用包含 OpenMP 程序并行化伪指令的源代码编译的应用程序。
表 4. XL C/C++ 编译器调用命令
基本调用 基本调用上的变体 描述
xlC
xlc++
xlC_r
xlc++_r
调用编译器以便将源文件作为 C++ 语言源代码编译。
xlc xlc_r 调用编译器以便将源文件作为 C 源代码编译。
c99 c99_r 调用编译器以便严格遵循 ISO C99 标准(ISO/IEC 14882:1999)编译源文件。
注:
ISO C99 标准也指定运行时库中的功能部件。这些功能部件在系统上当前安装的运行时库中可能不受支持。
c89 c89_r 调用编译器以便严格遵循 ISO C89 标准(ISO/IEC 9899:1990)编译源文件。
cc cc_r 调用编译器以用于不要求符合 C89 或 C99 的旧的 C 代码。
gxlc   在将 GNU C 命令行选项转换为 XL C/C++ 选项之后调用编译器。
注:
并非每个 GNU C 选项都具有完全等价的 XL C/C++ 选项。
gxlC
gxlc++
  在将 GNU C++ 命令行选项转换为 XL C/C++ 选项之后调用编译器。
注:
并非每个 GNU C++ 选项都具有完全等价的 XL C/C++ 选项。

编译并行化的 XL C/C++ 应用程序

XL C/C++ 提供线程安全编译调用,您可以在编译要在多处理器环境下使用的并行化应用程序时使用这些调用。

这些调用类似于其相应的基本编译器调用,只是它们会将已编译的对象链接和绑定至线程安全组件和库。

注:
单独使用这些命令中的任何一个并不暗示并行化。为了让编译器能够识别 OpenMP 伪指令并激活并行化,您还必须指定 -qsmp 编译器选项。而您只能将 -qsmp 选项与这六个调用命令中的一个一起指定。当您指定 -qsmp 时,驱动程序链接将指向配置文件的活动节中 smp 库行上所指定的库。

XL C/C++ 输入文件

编译器的输入文件为:

源文件(.c 后缀表示 C 语言,.C .cc .cp .cpp .cxx .c++ 后缀表示 C++ 语言
编译器将具有这些后缀的文件视为要编译的 C 或 C++ 源文件。

编译器按您在命令行上指定的顺序编译源文件。如果编译器找不到指定的源文件,则编译器生成一条错误消息并继续编译下一个文件(如果下一个文件存在的话)。

如果您有不符合标准 C 或 C++ 文件命名约定的 C 或 C++ 源文件,则您可以使用 -+ 编译器选项来指示编译器像处理 C 或 C++ 源文件一样处理这样的文件。当 -+ 编译器选项生效时,除了有 .a、.o、.so、.s 或 .S 文件名后缀的文件以外,这样的文件将作为 C++ 源文件进行编译。

包含文件也包含源代码,且常常具有与平常用于 C 或 C++ 源文件的那些后缀不同的后缀。

预处理源文件(.i 后缀)
编译器将预处理源文件 filename.i 发送至 编译器,将在那里再次像对待 .c.C 文件一样预处理它。预处理文件可用于检查宏和预处理器伪指令。
目标文件(.o 后缀)
在编译器编译源文件之后,它使用 ld 命令来链接产生的 .o 文件、您指定为输入文件的任何 .o 文件以及产品和系统库目录中某些 .o 和 .a 文件。然后编译器可以从这些目标文件生成单个 .o 目标文件或单个可执行输出文件。
汇编程序源文件(.s 和 .S 后缀)
编译器将汇编程序源文件发送至汇编程序(as)。汇编程序在链接时将目标文件发送至链接程序。
注:
编译器首先预处理文件名后缀为 .S 的汇编程序源文件,然后将它发送至汇编程序。
共享目标或库文件(.so 后缀)
这些文件是可以在运行时装入并由多个进程共享的目标文件。当在链接期间指定了共享目标时,关于该目标的信息记录在输出文件中,但输出文件中实际上不包括来自共享目标的代码。
配置文件(.cfg 后缀)
配置文件的内容确定编译过程的许多方面,最普通的是确定编译器的缺省选项。可以使用配置文件来集中不同的缺省编译器选项组或使 XL C/C++ 编译器的多个级别在系统上存在。

缺省配置文件是 /etc/opt/ibmcmp/vac/8.0/vac.cfg/etc/opt/ibmcmp/vac/8.0/gxlc.cfg

概要数据文件

-qpdf1 选项生成运行时概要信息以在后续编译中使用。此信息存储在名称与模式 *pdf* 匹配的一个或多个隐藏文件中。

XL C/C++ 输出文件

C 和 C++ 生成的输出文件为:

可执行文件:a.out
缺省情况下,XL C/C++ 在当前目录中生成命名为 a.out 的可执行文件。
目标文件:filename.o
如果您指定 -c 编译器选项,则不生成可执行文件,而是编译器为每个指定的程序源代码输入文件生成一个目标文件,并且汇编程序为每个指定的汇编程序输入文件生成一个目标文件。缺省情况下,将使用与输出目标文件的相应源代码输入文件相同的文件名前缀将该输出目标文件保存到当前目录。
汇编程序源文件:filename.s
如果您指定 -S 编译器选项,则不会生成可执行文件,而是 XL C/C++ 编译器为每个指定的输入源文件生成一个等价的汇编程序源文件。缺省情况下,将使用与输出汇编程序源文件的相应源代码输入文件相同的文件名前缀将该输出汇编程序源文件保存到当前目录。
编译器列表文件:filename.lst
缺省情况下,除非您指定了一个或多个与列表相关的编译器选项,否则不会生成列表。列表文件将放置在当前目录中,其文件名前缀与源文件的相同。
cpp 预处理源文件:filename.i
要创建预处理源文件,在编译时指定 -P 选项。源文件将会被预处理但不会被编译。也可以通过 -E 选项重定向输出以生成包含 #line 伪指令的预处理文件。将为每个源文件生成一个预处理源文件 filename.i。缺省情况下,将使用与输出预处理器源文件的相应源代码输入文件相同的文件名前缀将该输出预处理器源文件保存到当前目录。
生成依赖性文件:filename.u
-M-qmakedep 编译器选项生效时,编译器为编译的每个 C 或 C++ 源文件创建一个 .u 文件。可以使用由 .u 文件提供的依赖性信息来帮助您创建 make 文件。

每个 .u 文件包含一行表示输入文件,并包含一个条目表示每个包含文件,该文件采用以下通用格式:

file_name.o :file_name.c 
file_name.o :include_file_name

将根据编译器搜索 #include 预处理器伪指令的顺序规则来列示包含文件。如果找不到包含文件,则不会将它添加至 .u 文件。不具有 include 语句的文件所生成的输出文件将包含一个仅列示输入文件名的行。

概要数据文件(.*pdf*)
它们是 -qpdf1 编译器选项生成的概要定向反馈文件。将在后续编译中使用它们以根据实际执行结果来调整优化。

指定编译器选项

编译器选项执行各种功能,如设置编译器特征、描述要生成的目标代码、控制发出的诊断消息和执行某些预处理器功能。

您可以用以下方式指定编译器选项:

当指定了多个编译器选项时,有可能发生选项冲突和不兼容。为了以一致的方式解决这些冲突,编译器通常应用以下一般优先级顺序:

  1. 源文件中的伪指令语句覆盖命令行设置
  2. 命令行编译器选项设置覆盖配置文件设置
  3. 配置文件设置覆盖缺省设置

通常,如果调用编译器时在命令行上多次指定了相同的编译器选项,则最后指定的那个选项起作用。

注:
-I 编译器选项是一种特殊情况。编译器在搜索在命令行上用 -I 指定的目录之前,它首先搜索在 vac.cfg 文件中用 -I 指定的任何目录。该选项是累积的而不是优先的。

具有累积行为的其它选项是 -R 和 (小写 L)。

还可以将编译器选项传递至链接程序、汇编程序和预处理器。有关编译器选项和如何指定它们的更多信息,请参阅 Compiler options reference

链接 XL C/C++ 程序

缺省情况下,不需要执行任何特殊操作来链接 XL C/C++ 程序。编译器调用命令自动调用 链接程序来生成可执行输出文件。例如,运行以下命令:

xlC file1.C file2.o file3.C

编译并生成目标文件 file1.ofile3.o,然后将所有目标文件(包括 file2.o)提交至链接程序以生成一个可执行文件。

在链接之后,遵循运行 XL C/C++ 程序中的指示信息来执行程序。

在单独的步骤中编译和链接

要生成稍后可以链接的目标文件,使用 -c 选项。

xlc++ -c file1.C               # Produce one object file (file1.o)
xlc++ -c file2.C file3.C       # Or multiple object files (file1.o, file3.o)
xlc++ file1.o file2.o file3.o  # Link object files with appropriate libraries

通常最好的方法是通过编译器调用命令执行链接程序,因为这会自动将某些额外的 ld 选项和库名传递至链接程序。

动态和静态链接

XL C/C++ 允许程序利用操作系统设施进行动态和静态链接:

有关链接您的程序的更多信息,请参阅 Invoking the linkage editor

此外,有关编译和链接库的更多信息,请参阅 Constructing a library