AR、链接和未定义引用的问题

problem with ar, linking and undefined reference

提问人:ron 提问时间:5/15/2020 更新时间:5/19/2020 访问量:522

问:

我有一个软件包,其中包含一些 500+ fortran .f 文件。它被很好地组织成各种子文件夹,并且有一个高级编译脚本调用子文件夹中的各种 Makefile

使用 PGI 编译器,我在 SLES 11.4 x86_64上执行此操作。

没有编译错误。

问题发生在最后,当链接尝试创建一个可执行文件时,结果是相同的 10 个左右对各种函数的未定义引用。我已经浏览了所有的 Makefile,其中没有遗漏的语句,对于所述的未定义引用,它们各自的文件存在于文件夹中,并且我还认识到所有这些文件都用于创建文件。.oobjects/.o.a

在整个编译过程中总共创建了 3 个文件,在编译了 50 个左右的 .f 文件后,会打印出随后运行 ar 的位置。对于每个 和 和 在编译期间,这种情况会发生很多次。.aUpdating whatever#.awhatever1.awhatever2.awhatever3.a

问题是,我知道我能说的 Makefile 中没有错误,我可以触发一个 .f 的重新编译,它对应于一个未定义的引用,当该文件更新并链接时,特定的未定义引用消失了。所以我尝试为其他人这样做,有时它有效,但有些则无效,这似乎是偶然的,我能够以这种方式为一些未定义的引用修复它。whatever#.a

另一件主要的事情是创建所有对象文件,如果我简单地删除所有 3 个文件并运行编译脚本,那么只有碰巧重新创建这 3 个文件,然后是最终链接,然后说一大堆不同的未定义引用.o.aar.a.

我相信问题在于它的版本的使用和/或操作系统有问题。有人知道真正的原因以及如何解决这个问题吗?我正在考虑修改编译脚本,而不是链接 3 个文件,以手动导致与所有 ~500 文件的链接并完全删除它。ar.a.oar

可以放入文件中的文件数量是否有限制?.o.a.ar

Linux 链接器 undefined-reference unix-ar

评论

0赞 Jonathan Leffler 5/15/2020
这可能是三个库的排序问题 - 如果您有 ,并且按该顺序列在链接行上,则可能是 定义 but 是第一个被引用的地方,因此链接器跳过了 中的定义(在扫描时不需要它),并且从未在 或 中找到它。您可以在链接器行上重复库 — 列表。如果这可行,或者至少更改了未定义的引用,那么这就是基本问题。修复很乏味。[...继续...]libAlibBlibClibAundef1libBundef1libAlibAlibBlibC-lA -lB -lC -lA -lB -lC
0赞 Jonathan Leffler 5/15/2020
[...继续...]最简单的解决方法是将三个单独的库合并为一个复合库,并仅与该库链接()。否则,你就会在库之间追逐循环引用,这一点也不好玩。某些版本的 GNU 能够对库进行分组,以便加载程序自动重新扫描组中的库,直到无法满足任何引用。libABC-lABCld
0赞 ron 5/16/2020
是需要做还是做?如果只是这样,这是否会导致符号表出现问题,文件中的符号表可能是问题吗?ranlibar sar.a
0赞 Jonathan Leffler 5/16/2020
这取决于平台,但通常既不需要也不需要特殊调用。通常,当您用于编辑库时,它还会更新将创建的符号表。但是,可能有一些平台(尽管我不认为 Linux 通常是其中之一——但我最近没有使用过 SLES)需要使用或明确告知更新符号表。ranlibararranlibranlibar
0赞 ron 5/16/2020
我确实知道未定义的引用不是异花授粉的,可以这么说,这 3 个库之间。它说找不到<函数名称>,我知道它在哪个文件中定义,我知道它被放入 3 个库中的哪一个。但我会在星期一尝试你的想法,谢谢。我知道它不是 linux 中缺少的第 3 方库,它都在这个软件程序中,它最多与 sin/cos/tan 的数学链接。.a.o.aar

答:

1赞 ron 5/19/2020 #1

终于让我的源文件链接了。解决方案是按照打印未定义引用的顺序从最后到第一名工作......

我会转到那些特定文件所在的子文件夹,未定义的引用抱怨。/objects/whatever/.o

我只是删除了这些文件,然后重新运行了我的编译脚本,该脚本调用了一个 Makefile,它只重新编译了这些文件,然后将这些文件放入现有库中。然后那些特定的未定义引用消失了。我对最初出现的 10 到 15 个未定义的参考文献重复了这一点,最终取得了成功。.o.far r.a

对现有文件执行或 ranlib 操作无济于事。所以我想这是一个编译顺序,并包含在文件中,这是问题所在吗?因为我最初知道所有必要的文件都在这三个文件中。ar -s.a.a.o.a