2013-07-31 3 views
0

Это мой Makefile:Makefile Компиляция Проблема для смешанного C++ и Fortran Программа

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. И подпрограмма SUPCGILU0A вызывается из C++-программы upcgc.cpp. upcgc7_init, upcgc7 и upcgc7_final определены в upcgc.cpp, и эти три вызываются из программы fortran upcg7.f.

Насколько я понимаю из моих исследований, это скорее проблемы с компоновщиками, или C++ и Fortran нужно перевести некоторые функции/подпрограммы с другого, но я не могу понять, в чем проблема. Есть ли кто-нибудь, кто мог бы понять, в чем проблема?

ответ

0

Если подпрограммы upcgc7 находятся в коде C, у них, вероятно, нет конечного подчеркивания. Лучший способ справиться с этим - использовать интерфейс ISO_C_BINDING в Fortran и объявить интерфейсы для этих подпрограмм.

+0

Большое спасибо за ваш ответ. Поскольку подпрограммы upcg7 находятся в коде на C++, а функция upcgc.cpp также находится в коде Fortran, я добавил завершающий знак подчеркивания, но он не работает. Я попытаюсь использовать интерфейс ISO_C_BINDING как то, что вы предложили. Но я собирался под UNIX, так может ли ISO_C_BINDING работать под UNIX? – user2639490

+0

Да, определенно. Это не зависит от ОС, а скорее от используемого вами компилятора. Если компилятор предоставляет это, вы можете идти. Согласно вашему make-файлу, вы используете gfortran, который поддерживает его с 2007 года: http://gcc.gnu.org/wiki/Fortran2003Bind_C. – haraldkl