我正在尝试编译一个代码(不是我的),它由混合的Fortran和C源文件组成,这些文件被编译成一个库。这个库既可以直接链接,也可以(更有用地)从python类驱动。我以前使用g77和gcc成功地将代码构建为32位,但我遇到了一种情况,即代码使用大块内存,需要64位。
我尝试使用gfortran 4.2.3(来自AT& T R项目的二进制dist)和系统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
我做了一些愚蠢的事情,比如不包括对链接器的必要切换,或者这里有更微妙的事情吗?
答案 0 :(得分:1)
Per 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一起使用的通用库,但我不确定我是否想要诱惑命运。