通过更改 makefile 结合 FORTRAN 和 C

标签 c makefile fortran fortran-iso-c-binding

我有一个 FORTRAN 代码,它调用 C 例程来计算度量。 FORTRAN 代码是:

program fortran
implicit none
interface
double precision function fpli_hv(A, d, n)
real :: A(5,3)
integer :: d, n
end function fpli_hv
end interface
real :: A(5,3)
double precision :: HV
integer :: i, j
A(1,:) = (/1.1,3.2,2.0/)
A(2,:) = (/6.3,5.2,7.2/)
A(3,:) = (/3.3,4.4,9.1/)
A(4,:) = (/3.3,5.2,2.1/)
A(5,:) = (/7.6,1.7,4.3/)
HV = fpli_hv(A, 3, 5)
end program fortran  

c 函数如下所示:

double fpli_hv(double *front, int d, int n, double *ref);  

为了结合 c 和 fortran,我需要在我的 makefile 中包含一个 Makefil.lib。我这样做了,并按如下方式准备了我的 makefile:

# The makefile should contain a set of suffix rules. All suffixes must
# be defined. In this case we will have .o for object files, .c for
# C files, and .f for Fortran files.
.SUFFIXES: .o .c .f90

# LIBRARY:
LIBHV = /gpfs0/home/shafiiha/programs/hv-2.0rc1-src/fpli_hv.a
#include Makefile.lib

# Define the C and Fortran compilers to be used in this makefile:
CC=
FC=gfortran -ffree-form -c

# Define flags to be used by the C and Fortran compilers:
CFLAGS =    
FFLAGS =

# Define include to be used by the C and Fortran compilers:
C_INCLUDES =     
F_INCLUDES = fortran.f90

# The linker executable in this case must be the MPI Fortran compiler
# to build a mixed C and Fortran MPI code:
LINK = gfortran

# Define values of parameters that appear in the source codes:
DEFINES =

# Define the list of object files for the linker. The linker will use
# those files to build the executable.
OBJECTS = fortran.o

# The rule that makes the drv executable (note that libraries have
# been specified by the mpif90 linker):
fortran: $(OBJECTS) 
    $(LINK) -o fortran $(OBJECTS) $(LIBHV)

# The rule that makes all object files from C sources:
.c.o:
    $(CC) $(CFLAGS) $(C_INCLUDES) $(DEFINES) $<

# The rule that makes all object files from Fortran sources:
.f90.o:
    $(FC)  $(FFLAGS)  $(F_INCLUDES) $^ $(LIBHV)

# The rule for deleting object files no longer needed after using
# make for drv:
clean:
    rm  *.o

但是当我成功的时候,我收到了这个消息:

gfortran -o fortran fortran.o /gpfs0/home/shafiiha/programs/hv-2.0rc1-src/fpli_hv.a  
fortran.o: In function `MAIN__':  
fortran.f90:(.text+0x548): undefined reference to `fpli_hv_'  
collect2: ld returned 1 exit status  
make: *** [fortran] Error 1  

你能帮我看看为什么会出现这个错误吗?非常感谢。

最佳答案

在这个时代,从 Fortran 调用 C 的最佳方式是使用 ISO C 绑定(bind)。您的问题是 Fortran 默认执行的名称修改以避免与 C 或标准库的例程冲突,通常添加下划线。使用 ISO C 绑定(bind),您既可以指定被调用例程的确切名称,覆盖名称修改,又可以轻松实现参数的 Fortran-C 一致性。在 Fortran 端,您编写一个接口(interface)来描述 C 例程。这里有以前的答案,gfortran 手册中有示例。这些示例不是 gfortran 独有的,因为 ISO C 绑定(bind)是 Fortran 2003 语言标准的一部分。

关于通过更改 makefile 结合 FORTRAN 和 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10836510/

相关文章:

c++ - Makefile:为什么这种自动生成先决条件的方法有效?

gcc - 将工作代码从 double 转换为四精度 : How to read quadruple-precision numbers in FORTRAN from an input file

fortran - 代码指定 double 与编译器选项 double 之间的区别

c++ - 不必要的 else 语句 : Is there any disadvantage to using ELSE IF when just IF can be used?

使用更多进程在 C 中捕获 SIGTERM

c++ - 如何在make下编译多个文件

c - `main.c' 需要错误 : make: *** No rule to make target `main.o' ,。停止

arrays - 如何有效地设计一个迭代数组并在一组子例程中分配相应条目的 Fortran 程序?

C 如何正确测量时间?

c - 编写忽略操作顺序的 C 程序?