去年,我开始在Fortran的一所研究型大学工作。我以前的大部分经验都是使用PHP或旧ASP等网络语言,所以我是新手编译语句。
我正在修改两个不同的代码。
在创建可执行文件之前,一个有显式语句从模块创建.o文件(例如gfortran -c filea.f90)。
另一个 直接创建可执行文件(有时创建.mod文件,但没有.o文件,例如gfortran -o executable filea.f90 fileb.f90 mainfile。 F90)。
答案 0 :(得分:29)
首先编译到目标文件称为单独编译。有许多优点和一些缺点。
优点:
缺点:
.h
个文件以与目标文件一起使用。但无论如何这都是好习惯。答案 1 :(得分:14)
如果项目包含几百个源文件,则每次更改时都不希望重新编译全部。通过将每个源文件编译为单独的目标文件并仅重新编译受更改影响的源文件,您可以花费从源代码更改到新可执行文件的最短时间。
make
是用于跟踪此类依赖项并在某些内容发生更改时重新创建二进制文件的常用工具。通常,您可以设置每个源文件所依赖的内容(这些依赖项通常由编译器生成 - 以适合make
的格式),并让make处理创建最新二进制文件的详细信息。
答案 2 :(得分:5)
.o文件是对象文件。它是最终节目的中间代表。
具体来说,通常,.o文件具有已编译的代码,但它没有的是所有不同例程或数据的最终地址。
程序运行之前需要的东西之一就像记忆图像一样。
例如。
如果你有你的主程序并且它调用例程A.(这是人造堡垒,我几十年没碰过,所以在这里和我一起工作。)
PROGRAM MAIN
INTEGER X,Y
X = 10
Y = SQUARE(X)
WRITE(*,*) Y
END
然后你有SQUARE功能。
FUNCTION SQUARE(N)
SQUARE = N * N
END
是单独编译的单位。你可以看到,当编译MAIN时,它不知道“SQUARE”在哪里,它的地址是什么。它需要知道,当它调用微处理器JUMP SUBROUTINE(JSR)指令时,该指令有一些地方可以去。
.o文件已经有JSR指令,但它没有实际值。这是在链接或加载阶段的后期(取决于您的应用程序)。
因此,MAINS .o文件包含main的所有代码,以及它想要解析的引用列表(特别是SQUARE)。 SQUARE基本上是独立的,它没有任何引用,但与此同时,它没有关于它在内存中的位置的地址。
链接器将从.o文件中取出所有内容并将它们合并到一个exe文件中。在过去,编译的代码实际上是一个内存映像。该程序将从某个地址开始,然后简单地加载到RAM批发中,然后执行。因此,在该场景中,您可以看到链接器获取两个.o文件,将它们连接在一起(以获取SQUARE的实际地址),然后它将返回并在MAIN中找到SQUARE引用,并填写地址。
现代链接器并没有那么远,并且将最终处理的大部分推迟到程序实际加载时。但这个概念是相似的。
通过编译.o文件,您最终得到可重复使用的逻辑单元,然后在执行之前由链接和加载进程组合。
另一个不错的方面是.o文件可以来自不同的语言。只要调用机制是兼容的(即参数如何传递到函数和过程以及从函数和过程传递),那么一旦编译成.o,源语言就变得不那么相关了。您可以使用FORTRAN代码链接,组合C代码,比如说。
在PHP等等中,该过程是不同的,因为所有代码都在运行时加载到单个图像中。你可以考虑类似于使用PHP的FORTRANs .o文件包括将文件组合成一个大而有凝聚力的整体的机制。
答案 3 :(得分:2)
答案 4 :(得分:1)
我们编译到目标文件,以便能够将它们链接在一起以形成更大的可执行文件。这不是唯一的方法。
还有一些编译器没有这样做,而是编译到内存并立即执行结果。早些时候,当学生不得不使用大型机时,这是标准配置。 Turbo Pascal也是这样做的。