tom*_*fer 31 c c++ fortran compilation object-files
在去年,我开始在Fortran开设编程,在一所研究型大学工作.我之前的大部分经验都是使用PHP或旧ASP等网络语言,所以我是编译语句的新手.
我有两个不同的代码我正在修改.
其中 有一个明确的声明创建的.o从模块文件中创建可执行文件之前(如gfortran -c filea.f90).
另一个是直接创建可执行文件(有时创建.mod文件,但没有.o文件,例如gfortran -o executable filea.f90 fileb.f90 mainfile.f90).
kri*_*iss 29
首先编译为目标文件称为单独编译.有许多优点和一些缺点.
好处:
缺点:
.h与目标文件一起使用的文件.但无论如何这是好习惯.Eri*_*rik 14
如果项目包含几百个源文件,则每次更改时都不希望重新编译所有这些文件.通过将每个源文件编译为单独的目标文件并仅重新编译受更改影响的源文件,您可以花费从源代码更改到新可执行文件的最短时间.
make是用于跟踪此类依赖关系的常用工具,并在某些更改时重新创建二进制文件.通常,您可以设置每个源文件所依赖的内容(这些依赖项通常由编译器生成 - 以适合的格式make),并让make处理创建最新二进制文件的详细信息.
.o文件是对象文件.它是最终节目的中间代表.
具体来说,通常,.o文件具有已编译的代码,但它没有的是所有不同例程或数据的最终地址.
程序在运行之前需要的东西之一就是内存映像.
例如.
如果你有你的主要程序并且它调用例程A.(这是人造堡垒,我几十年没有碰过,所以在这里和我一起工作.)
PROGRAM MAIN
INTEGER X,Y
X = 10
Y = SQUARE(X)
WRITE(*,*) Y
END
Run Code Online (Sandbox Code Playgroud)
然后你有SQUARE功能.
FUNCTION SQUARE(N)
SQUARE = N * N
END
Run Code Online (Sandbox Code Playgroud)
这些是单独编译的单位.你可以看到,当编译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等等中,该过程是不同的,因为所有代码都在运行时加载到单个图像中.你可以考虑FORTRANs .o文件,类似于你如何使用PHP包括将文件组合成一个大而有凝聚力的整体的机制.