首页 > 解决方案 > 编译问题“未定义的引用”

问题描述

尝试编译代码时出现以下错误

hdf5.o: In function `hdf5_module_mp_readhdf5_':
hdf5.F:(.text+0x322e): undefined reference to `courant_'

主要代码是channel.f(还有其他在这个问题中不起作用),其中包含一个名为“courant”的函数

      MODULE channel_module
      USE shared_module
      USE solvers_module
      USE les_module
      USE hdf5_module

      CONTAINS
      .....
      SUBROUTINE COURANT
      ..
      END SUBROUTINE COURANT
      .....
      END MODULE channel_module

问题出在 hdf5.f 中,其中还有另一个函数称为“courant”

      MODULE hdf5_module
      USE shared_module
      USE mpi_module

      CONTAINS 
      .....
      subroutine ReadHDF5
      ...
      CALL COURANT
      ...
      end subroutine ReadHDF5

      END MODULE hdf5_module

这是生成文件:

# This is the makefile 

COMPILER = ifort

USEROPTS = -O3 -fpp -mcmodel=large
FCOMP = -fpic -i_dynamic -mcmodel=large
LINK = -fpic -i_dynamic -mcmodel=large8.15-parallel

LINKDIR = -L/apps/fftw/2.1.5-double/lib -L/apps/hdf5/1.8.15/parallel/lib

INCLUDEDIR = -I/apps/fftw/2.1.5-double/include -I/apps/hdf5/1.8.15/parallel/include

PARALLEL = TRUE

LES = TRUE

NETCDF = FALSE
HDF5 = TRUE

NEWTON = FALSE

# Option to run different flavors (basic, ensemble, etc.)
ENSEM = FALSE
BATCH = FALSE
# **********    END of user definitions ************

ifeq ($(ARCH),ifort)
COMPILER = ifort
USEROPTS = -O3 -fpp
else ifeq ($(ARCH),gfortran)
COMPILER = gfortran
USEROPTS = -O3 -cpp
endif

ifeq ($(LES),TRUE)
LES_o = les.o
else
LES_o = no_les.o
endif

ALL2ALL=1

ifeq ($(PARALLEL),TRUE)
COMPILER = mpif90 
MPI = mpi.o
MPIF = mpi.alltoall$(ALL2ALL).F
ifeq ($(HDF5),TRUE)
HDF5_o = hdf5.o 
COMPILER = h5pfc
HDF5OPTS=-DHDF5
endif
ifeq ($(NEWTON),TRUE)
NEWTONOPTS=-DNEWTON
endif
else
ifeq ($(HDF5),TRUE)
HDF5_o = hdf5s.o 
COMPILER = h5pfc
HDF5OPTS=-DHDF5
endif
MPI = mpi_serial.o
endif

MAIN = diablo.f
HEADER = header
ENSEM_HOOKS = dummy_code/ensem_dummy.f
BATCH_HOOKS = dummy_code/batch_dummy.f
HOOKS = batch_hooks.o ensem_hooks.o
ADJOINT = 

ifeq ($(ENSEM),TRUE)
MAIN = ensemble.f
HEADER = header header_ensem
COMPILER = mpif90
ENSEM_HOOKS = ensem_hooks.f
endif

ifeq ($(BATCH),TRUE)
MAIN = batch.f
HEADER = header header_batch
BATCH_HOOKS = batch_hooks.f
#ADJOINT = adj_chan.o adj_per.o
ADJOINT = adj_per.o
endif

# Use the parameters to set flags
ifeq ($(NETCDF),TRUE)
COMPOPTS = $(USEROPTS) $(HDF5OPTS) $(NEWTONOPTS) $(INCLUDEDIR)
LINKOPTS = $(LINKDIR) -ldrfftw -ldfftw -lnetcdf
NETCDF_o = netcdf.o
else
COMPOPTS = $(USEROPTS) $(HDF5OPTS) $(NEWTONOPTS)
LINKOPTS = $(LINKDIR) -lrfftw -lfftw \
    ./lib/liblapack_ifort64.a \
    ./lib/libblas_ifort64.a
NETCDF_o = no_netcdf.o
endif



diablo: $(MAIN) diablo_io.o channel.o $(LES_o) \
    fft.o newton.o shared.o solvers.o $(MPI) \
    $(HDF5_o)
    $(COMPILER) $(COMPOPTS) $(MAIN) -o diablo \
    diablo_io.o channel.o $(LES_o) \
    fft.o newton.o shared.o solvers.o \
    $(MPI) $(LINKOPTS) $(HDF5_o)

shared.o: shared.F grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c shared.F

solvers.o: solvers.F shared.o grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c solvers.F

diablo_io.o: diablo_io.F shared.o channel.o solvers.o fft.o $(HDF5_o)
    $(COMPILER) $(COMPOPTS) -c diablo_io.F

channel.o: channel.F solvers.o fft.o $(MPI) shared.o $(LES_o) grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c channel.F

ifeq ($(LES),TRUE) 
les.o: les.F fft.o shared.o $(MPI) $(HDF5_o) grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c les.F
else
no_les.o: dummy_code/no_les.f fft.o shared.o $(MPI) $(HDF5_o) grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c dummy_code/no_les.f
endif

ifeq ($(NETCDF),TRUE)
netcdf.o: netcdf.f header
    $(COMPILER) $(COMPOPTS) -c netcdf.f
else
no_netcdf.o: dummy_code/no_netcdf.f 
    $(COMPILER) $(COMPOPTS) -c dummy_code/no_netcdf.f
endif

ifeq ($(PARALLEL),TRUE)
mpi.o: $(MPIF) shared.o solvers.o grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c -o mpi.o $(MPIF) 
else
mpi_serial.o: dummy_code/mpi_serial.f shared.o solvers.o grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c dummy_code/mpi_serial.f
endif

header : header_mpi grid_def

header_mpi : grid_mpi

hdf5.o : hdf5.F shared.o fft.o $(MPI) grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c hdf5.F

fft.o:  fft.F shared.o $(MPI) grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c fft.F

#rand.o:  rand.f grid_def grid_mpi
#   $(COMPILER) $(COMPOPTS) -c rand.f

newton.o: newton.F90 $(LES_o) $(HDF5_o) $(MPI) fft.o shared.o solvers.o \
    diablo_io.o grid_def grid_mpi NewtonHook.o GMRESm.o
    $(COMPILER) $(COMPOPTS) -c newton.F90

NewtonHook.o: NewtonHook.F90 $(LES_o) $(HDF5_o) $(MPI) fft.o shared.o solvers.o \
    diablo_io.o grid_def grid_mpi GMRESm.o
    $(COMPILER) $(COMPOPTS) -c NewtonHook.F90

GMRESm.o: GMRESm.F90 $(LES_o) $(HDF5_o) $(MPI) fft.o shared.o solvers.o \
    diablo_io.o grid_def grid_mpi
    $(COMPILER) $(COMPOPTS) -c GMRESm.F90

clean:
    rm -f *.o fort.* *~ diablo core *.mod

这是怎么回事?

标签: fortran

解决方案


COURANT中定义channel_module

所以你需要在需要use channel_module它的地方,hdf5_module而不是相反。

现在你的代码use hdf5_modulechannel_module. 相反,请尝试以下操作:

MODULE channel_module
  USE shared_module
  USE solvers_module
  USE les_module

  CONTAINS
  .....
  SUBROUTINE COURANT
  ..
  END SUBROUTINE COURANT
  .....
END MODULE channel_module

MODULE hdf5_module
  USE shared_module
  USE mpi_module
  USE channel_module

  CONTAINS 
  .....
  subroutine ReadHDF5
  ...
  CALL COURANT
  ...
  end subroutine ReadHDF5

END MODULE hdf5_module

推荐阅读