编译源代码#

构建过程的第一步是编译源代码。此步骤的输出通常称为目标代码——从人类可读的源代码生成的计算机指令集。不同的编译器会从相同的源代码生成不同的目标代码,并且命名约定也不同。

后果

  • 如果您对一个源文件使用特定的编译器,则需要对所有其他部分使用相同的编译器(或兼容的编译器)。毕竟,一个程序可以由许多不同的源文件构建而成,并且编译后的部分必须能够协同工作。

  • 每个源文件都将被编译,结果将存储在一个扩展名为“.o”或“.obj”的文件中。正是这些目标文件是下一步的输入:链接过程。

编译器是复杂的软件:它们必须比普通程序员更详细、更深入地理解语言。它们还需要了解计算机的内部工作原理。然后,多年来,它们已经扩展了许多选项,以自定义编译过程和将要构建的最终程序。

但基本原理很简单。以 gfortran 编译器为例,它是 GNU 编译器集合的一部分。要编译上面类似的简单程序(该程序由一个源文件组成),请运行以下命令,假设源代码存储在文件“hello.f90”中

$ gfortran -c hello.f90

这将生成一个文件“hello.o”(因为 gfortran 编译器使用“.o”作为目标文件的扩展名)。

选项“-c”表示:仅编译源文件。如果您将其省略,则编译器的默认操作是编译源文件并启动链接器以构建实际的可执行程序。命令

$ gfortran hello.f90

将在 Linux 上生成一个可执行文件“a.out”,在 Windows 上生成“a.exe”。

一些说明

  • 如果编译器发现源文件的内容有错误(例如拼写错误或未知关键字),它可能会报错。在这种情况下,编译过程将中断,您将无法获得目标文件或可执行程序。例如,如果“program”一词意外地被输入为“prgoram”

$ gfortran hello3.f90
hello.f90:1:0:

    1 | prgoram hello
      |
Error: Unclassifiable statement at (1)
hello3.f90:3:17:

    3 | end program hello
      |                 1
Error: Syntax error in END PROGRAM statement at (1)
f951: Error: Unexpected end of file in 'hello.f90'

使用此编译报告,您可以更正源代码并重试。

  • 如果没有“-c”的步骤只有在源文件包含主程序时才能成功——在 Fortran 中由program语句表征。否则,链接步骤将抱怨缺少“符号”,类似于以下内容

$ gfortran hello2.f90
/usr/lib/../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status

文件“hello2.f90”与文件“hello.f90”几乎相同,只是关键字program已被关键字subroutine替换。

编译器输出的上述示例因编译器和运行它的平台而异。这些示例来自在 Windows 上的 Cygwin 环境中运行的 gfortran 编译器。

编译器在其支持的选项方面也存在差异,但通常

  • 用于优化代码的选项——生成更快的程序或更小的内存占用量;

  • 用于检查源代码的选项——例如检查变量在赋值之前是否已使用,或检查是否使用了语言的一些扩展;

  • 用于包含文件或模块文件位置的选项,请参见下文;

  • 用于调试的选项。