1

我正在尝试编译由混合的 Fortran 和 C 源文件组成的代码(不是我的),这些文件被编译成一个库。这个库既可以直接链接,也可以(更有用)从 python 类驱动。我之前使用g77和gcc成功地将代码构建为32位,但是我遇到了代码使用大块内存的情况,并且需要是64位的。

我尝试使用 gfortran 4.2.3(来自 AT&T R 项目的二进制文件)和系统 gcc(4.2)构建 64 位或通用二进制文件。源文件构建正确,但是当我尝试链接库时,我收到许多 Fortran 函数的“未定义符号”错误。库上的 nm 显示符号似乎存在,但显然链接器没有找到它们。

以下是两个(许多)编译命令(不会产生错误):

/usr/local/bin/gfortran -arch ppc -arch i386 -arch x86_64  -fPIC -fno-strength-reduce -fno-common -ff2c -Wall -c  lsame.f

gcc -c -I/Users/keriksen/Research/atomic_data/fac -I/Users/keriksen/Research/atomic_data/fac/faclib -O2 -fPIC -fno-strength-reduce -fno-common pmalloc.c

和链接步骤,炸弹:

gcc -o sfac sfac.c stoken.c -I/Users/keriksen/Research/atomic_data/fac -I/Users/keriksen/Research/atomic_data/fac/faclib -O2 -fPIC -fno-strength-reduce -fno-common -L/Users/keriksen/Research/atomic_data/fac -lfac -lm -lgfortran -lgcc

示例未定义符号:

  "_acofz1", referenced from:
      _HydrogenicDipole in libfac.a(coulomb.o)
      _HydrogenicDipole in libfac.a(coulomb.o)

以及显示该符号存在的相应 nm:

    niobe:atomic_data/fac[14] nm libfac.a | grep acof

0000000000000000 T _acofz1_
0000000000002548 S _acofz1_.eh
                 U _acofz1

我是在做一些愚蠢的事情,比如不包括对链接器的必要切换,还是这里发生了一些更微妙的事情?

4

1 回答 1

1

根据 Yuji 的建议:

处理 C/Fortran 兼容性问题的 cfortran.h 头文件(可在 Web 上获得,并且显然被广泛使用)不处理开箱即用的 gfortran。我(错误地)破解了它以忽略这个事实,并为我的无礼付出了代价。

具体问题是 gfortran 发出的目标代码包含带有尾随下划线的符号,而 gcc 不会。

正确的做法是将环境变量 CPPFLAGS 设置为 -Df2cFortran。一旦设置了这个宏,cfortran.h 就会为调用 C 函数的目标代码中的符号添加必要的下划线,链接器就会很高兴。

在这个特定实例中,另一个令人惊讶的事情是配置脚本查看 F77 环境变量以获取 fortran 编译器的名称。一旦我将 F77 设置为“/usr/local/bin/gfortran -arch x86_64”,生成的 Makefile 是正确的,它只生成了 64 位的目标代码。我不确定这是否是标准配置行为,或者它是否是这个特定脚本的特性。

结果是我现在有了一个 64 位共享库,它可以很好地与我下载的 64 位 python 配合使用。我正在考虑返回并尝试生成一个可以与系统 python 一起使用的通用库,但我不确定我是否想试探命运。

于 2011-08-23T15:55:04.073 回答