我有一个 fortran 90 程序,它通过 FCVODE 接口调用 Sundials CVODE。日晷是用 C 语言编写的,但它们为 fortran 提供了两个接口。一个接口用于 fortran 77 应用程序,一个使用现代 fortran 方法 (iso_c_binding)。
我的代码使用 fortran 77 接口(就像它最终的结果一样,我知道 iso_c_binding 会更好)
这是我的项目(开发分支):https ://github.com/Nicholaswogan/PhotochemPy/tree/dev
我的目标是编写一个 CMakesLists.txt,它可以一口气编译所有的 fortran 和 C。我已经这样做了,但它只适用于某些编译器组合和操作系统。例如,在带有 clang 12.0.5 和 gfortran 11.1.0 的 MacOS 上,一切正常。但是,在 MacOS 上,当我切换到 gcc 11.1.0(而不是 clang)时,链接我的可执行文件时出现错误:
[ 98%] Building Fortran object CMakeFiles/photo.run.dir/src/main.f90.o
[100%] Linking Fortran executable photo.run
duplicate symbol '_F2C_CVODE_linsol' in:
lib/libsundials_fcvode.a(fsunlinsol_band.c.o)
lib/libsundials_fcvode.a(fcvnulllinsol.c.o)
duplicate symbol '_F2C_CVODE_matrix' in:
lib/libsundials_fcvode.a(fsunmatrix_band.c.o)
lib/libsundials_fcvode.a(fcvnullmatrix.c.o)
ld: 2 duplicate symbols for architecture x86_64
collect2: error: ld returned 1 exit status
make[2]: *** [photo.run] Error 1
make[1]: *** [CMakeFiles/photo.run.dir/all] Error 2
make: *** [all] Error 2
我看过libsundials_fcvode.a
and libsundials_fcvode.a
,它们确实包含这些重复的符号。然而,当我用 clang + gfortran 编译时,这些库也有这些重复的符号,但是,在这种情况下,这些编译器似乎并没有被它打扰。
此外,在带有 gcc 9 和 gfortran 9 的 Ubuntu 20.04 上,我得到一个未定义的符号:
[ 98%] Building Fortran object CMakeFiles/photo.run.dir/src/main.f90.o
[100%] Linking Fortran executable photo.run
/usr/bin/ld: lib/libsundials_fcvode.a(fcvband.c.o): in function `FCVBandJac':
fcvband.c:(.text+0x141): undefined reference to `fcvbjac_'
/usr/bin/ld: lib/libsundials_fcvode.a(fcvode.c.o): in function `FCVf':
fcvode.c:(.text+0x50): undefined reference to `fcvfun_'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/photo.run.dir/build.make:91: photo.run] Error 1
make[1]: *** [CMakeFiles/Makefile2:711: CMakeFiles/photo.run.dir/all] Error 2
make: *** [Makefile:130: all] Error 2
这个丢失的符号非常令人费解,因为它没有丢失!我习惯于nm
询问我要链接到的库,并且符号在那里:
...
cvode_funcs.f90.o:
0000000000000250 T fcvbjac_
0000000000000000 T fcvfun_
...
我的问题:CMakesList.txt 中缺少哪些常见项目会导致这些问题?或者在没有iso_c_binding
.
编辑:
我最终花时间从 fortran 77 接口切换到使用 iso_c_binding 的现代 fortran C 接口。我尝试过的每个编译器都有效。