【问题标题】:Makefile Compiling Issue for Mixed C++ and Fortran Program混合 C++ 和 Fortran 程序的 Makefile 编译问题
【发布时间】:2013-07-31 20:21:34
【问题描述】:

这是我的生成文件:

    PROGRAM = mf2005-GPU.f

    # Define the Fortran compile flags
    F90FLAGS= -g -fopenmp
    F90= gfortran

    # Define the C compile flags
    # -D_UF defines UNIX naming conventions for mixed language compilation.
    CFLAGS= -D_UF -O3
    CC= gcc

    CPPFLAGS= -Dcpp_variable
    CXX= g++

    # Define GMG objects
    #
    GMG = r_vector.o\
      solvers.o\
      ccfd.o\
      mf2kgmg.o\

    # Define the libraries

    SYSLIBS= -lc
    USRLIB  = 
    CUDA_LIB64=/cm/shared/apps/cuda40/toolkit/4.0.17/lib64/
    LFLAGS = -L$(CUDA_LIB64) -lcuda -lcudart -lcusparse -lcublas -lpthread -lm -lcufft -lcurand -lnpp -lgomp 

    # Define all object files which make up MODFLOW

    OBJECTS = \
    dblas.o\
    gwf2bas7.o \
    de47.o \
    dlapak.o\
    pcg7.o \
    sip7.o \
    gmg7.o \
    mhc7.o \
    gwf2bcf7.o \
    gwf2lpf7.o \
    gwf2huf7.o \
    gwf2rch7.o \
    gwfuzfmodule.o \
    gwfsfrmodule.o \
    gwf2lak7.o \
    gwf2sfr7.o \
    gwf2uzf1.o \
    gwf2gag7.o \
    gwf2chd7.o \
    gwf2drn7.o \
    gwf2drt7.o \
    gwf2ets7.o \
    gwf2evt7.o \
    gwf2fhb7.o \
    gwf2ghb7.o \
    gwf2hfb7.o \
    gwf2ibs7.o \
    gwf2res7.o \
    gwf2riv7.o \
    gwf2str7.o \
    gwf2sub7.o \
    gwf2swt7.o \
    gwf2wel7.o \
    hufutl7.o \
    obs2bas7.o \
    obs2drn7.o \
    obs2ghb7.o \
    obs2riv7.o \
    obs2chd7.o \
    obs2str7.o \
    parutl7.o \
    gwf2mnw17.o \
    gwf2mnw27.o \
    gwf2mnw2i7.o \
    utl7.o \
    lmt7.o \
    gwf2hydmod7.o \
    upcg7.o \
    upcgc.o \
    upcg7lanczos.o \
    upcg7polya.o \
    upcg7polyu.o \
    mf2005-GPU.o \

    # Define Task Function

    all: mf2005-GPU

    # Define what mf2005

    mf2005-GPU: $(OBJECTS) $(GMG) 
-$(F90) $(F90FLAGS) -o mf2005-GPU $(OBJECTS) cuda_kernels.o $(GMG)  $(USRLIB)  $(SYSLIBS)    $(LFLAGS)

    # Object codes

    .f.o:
    $(F90) $(F90FLAGS) -c $<

    .c.o:
    $(CC) $(CFLAGS) -c $<


    .cpp.o:
    $(CXX) $(CPPFLAGS) -c $<

    #  end

这就是我编译 cuda_kernels.cu 的方式 nvcc -c -arch sm_20 -lcuda -lcudart -lcusparse cuda_kernels.cu

这是我得到的错误

    upcg7.o: In function `upcg7ar':
    /home/zhangmj/MF2005_MAKE/upcg7.f:731: undefined reference to `upcgc7_init_'
    upcg7.o: In function `upcg7ap':
    /home/zhangmj/MF2005_MAKE/upcg7.f:1272: undefined reference to `upcgc7_'
    upcg7.o: In function `upcg7da':
    /home/zhangmj/MF2005_MAKE/upcg7.f:1416: undefined reference to `upcgc7_final_'
    upcgc.o: In function `UPCGC7':
    upcgc.cpp:(.text+0xf6a): undefined reference to `SUPCGILU0A'
    collect2: ld returned 1 exit status
    make: [mf2005-GPU] Error 1 (ignored)

下面是upcg7.f(这不是我的代码,我从这里下载) https://github.com/jdhughes-usgs/modflow-2005-upcg/blob/master/code/src/UPCG/upcg7.f

下面是upcgc.cpp和upcgc.h(这不是我的代码,我从这里下载) https://github.com/jdhughes-usgs/modflow-2005-upcg/blob/master/code/src/UPCG/upcgc.cpp

**我的问题是** SUPCGILU0A 是 upcg7.f 中定义的子程序。从 C++ 程序 upcgc.cpp 调用子程序 SUPCGILU0A。 upcgc7_init、upcgc7和upcgc7_final定义在upcgc.cpp中,这三个是从fortran程序upcg7.f中调用的。

从我的研究中了解到,这些可能是链接器问题,或者 C++ 和 Fortran 需要相互转换一些函数/例程,但我无法弄清楚问题所在。有没有人可能对问题所在有所了解?

【问题讨论】:

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


    【解决方案1】:

    如果 upcgc7 例程位于 C 代码中,它们可能没有尾随下划线。解决这个问题的最好方法是利用 Fortran 中的 ISO_C_BINDING 接口并声明这些例程的接口。

    【讨论】:

    • 非常感谢您的回复。因为 upcg7 例程位于 C++ 代码中,而 upcgc.cpp 函数也位于 Fortran 代码中,所以我添加了尾随下划线,但它不起作用。我将尝试按照您的建议使用 ISO_C_BINDING 接口。但是我是在 UNIX 下编译的,那么 ISO_C_BINDING 可以在 UNIX 下工作吗?
    • 是的,当然。这不取决于操作系统,而是取决于您使用的编译器。如果编译器提供了它,你就可以开始了。根据您的 makefile,您使用的是自 2007 年以来支持它的 gfortran:gcc.gnu.org/wiki/Fortran2003Bind_C.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    相关资源
    最近更新 更多