【问题标题】:Link multiple object files in gfortran在 gfortran 中链接多个目标文件
【发布时间】:2015-07-27 09:57:03
【问题描述】:

我有包含多个对象 (.o) 文件的“库”文件夹。这些文件包含不会因项目而异的子例程。每个新项目都使用其中一些目标文件,但不是全部。
您能否告诉我有什么方法可以告诉 gfortran 在该文件夹中查找必要的 .o 文件吗?
我试过 -I 和 -L 选项,但没办法。当我直接写 .o 名称时,它可以工作:
gfortran main.for ./library/obj1.o ./library/obj2.o
但我有很多 .o 文件,写所有文件都浪费时间。 我可以写
gfortran main.for ./*.o
但随后主程序将与所有 .o 文件链接,但它只需要其中一些文件。 我希望像
gfortran main.for -L./library/
这样的东西会起作用,但它没有。
我使用 OS X 和 gcc 版本 5.1.0。 而且我很确定我应该在这种情况下使用makefile

【问题讨论】:

    标签: compilation makefile linker fortran gfortran


    【解决方案1】:

    您将目标文件与静态库混淆了。目标文件 不是静态库和 gfortran 链接器 - 这很简单 由gfortran 调用的GNU 系统链接器不会这样对待它。 您需要一个静态库,并且您正在尝试使用目标文件来代替。

    链接器通过扩展名.o 识别目标文件。它承认 扩展名为.a 的静态库,它需要.a 文件的内容 具有静态库的形式,而不是目标文件的格式。 (那么你 不能通过重命名将目标文件变成静态库)。

    链接器会将出现在其上的每个目标文件链接到您的程序中 命令行,无论是否需要。它不希望你提及 目标文件,如果您不希望它们链接。链接器选项 -L-l 用于 定位不适用于目标文件。

    静态库是一个相当简单的存档,包含一些 目标文件,加上一个管理头文件和通常的索引 在包含的目标文件中定义的公共符号。

    当链接器在其命令行上遇到静态库时,它不会 链接库的全部内容(除非你明确告诉它)。它检查 包含的目标文件,以确定其中哪些(如果有)包含 在链接中该点尚未定义的符号的定义 的程序。如果发现库中的任何目标文件提供任何 缺少的定义,然后从库中提取该目标文件 并链接到程序中。 库中的对象文件不提供 缺少的定义没有链接。命令行上的库是按顺序排列的 以这种方式检查,直到程序引用的所有符号 在链接的对象文件中有定义,或者没有更多的库。

    如果如您所说,您尝试用作库的目标文件是稳定的 您不必为项目构建的资源,那么您只需制作一个静态的 从它们中提取库并将该库与您的每个项目程序链接起来。

    要从目标文件创建静态库,请使用ar 工具。 见man ar

    当你创建了你的库时,比如说libsubs.a,并决定它应该驻留 在某个目录中,/path/to/subs,然后通过添加将其与程序链接

        -L/path/to/subs -lsubs
    

    到您的程序链接的命令行。这将导致链接器 在目录/path/to/subs 中搜索名为libsubs.a 的库。

    因此,如果您在一个步骤中进行编译和链接,请像这样使用它:

    gfortran -o myprog myprog.f90 -L/path/to/subs -lsubs
    

    如果您在不同的步骤中编译和链接,请像这样使用它:

    gfortran -c -o myprog_1st_file.o myprog_1st_file.f90
    gfortran -c -o myprog_2nd_file.o myprog_2nd_file.f90
    gfortran -o myprog myprog_1st_file.o myprog_2nd_file.o -L/path/to/subs -lsubs
    

    这就是你应该如何使用一组目标文件资源,其中 与不同的程序链接需要不同的子集:你把 它们在一个库中并链接该库。

    【讨论】:

    • 太棒了!你准确地描述了我需要什么。不知道为什么我错过了将所有目标文件组织到静态库中的想法。非常感谢!
    • 还有一件事)如果我需要对静态库中的一个子例程进行临时更改怎么办?例如,我在calc.o 中有一个名为CALC 的子例程。我将calc.o 和许多其他.o 文件打包到静态库中。但在开发过程中,我需要对calc.o 添加一些临时更改。如果我将MainProgram.forcalc.for 放在一起并用lib 编译和链接它们,链接器会说我重复了CALC 的引用。是否可以告诉链接器,如果它已经在目标文件中找到子例程,那么它不应该从 lib 链接它?
    • 您只需将calc.o 的专用版本放在比静态库更早的链接中。正如我所解释的,只有当目标文件提供了在链接中的那个点仍未定义的某些符号的定义时,链接器才会从静态库中提取和链接目标文件。如果您的 calc.o 定义了与库版本相同的所有符号,那么如果首先链接您的 calc.o,则忽略库的版本。
    猜你喜欢
    • 1970-01-01
    • 2014-08-09
    • 2012-06-24
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多