I am trying to build a model written in F90. I keep having problems with it especially in the linking phase. I tried to compile both with gfortran and with ifort but both of them are complaining about undefined symbols. Here are the errors from ifort (gfortran has very similar ones) after the compilation which works fine
ar rs /Users/manfredo/Desktop/ED2/ED/build//ed_2.1-opt.a allometry.o an_header.o average_utils.o bdf2_solver.o budget_utils.o canopy_air_coms.o canopy_layer_coms.o canopy_radiation_coms.o canopy_struct_dynamics.o c34constants.o charutils.o consts_coms.o dateutils.o decomp_coms.o detailed_coms.o disturbance.o disturb_coms.o edio.o ed_1st.o ed_bigleaf_init.o ed_driver.o ed_filelist.o ed_grid.o ed_init.o ed_init_atm.o ed_init_full_history.o ed_load_namelist.o ed_max_dims.o ed_mem_alloc.o ed_mem_grid_dim_defs.o ed_met_driver.o ed_misc_coms.o ed_model.o ed_mpass_init.o ed_nbg_init.o ed_node_coms.o ed_opspec.o ed_params.o ed_para_coms.o ed_para_init.o ed_print.o ed_read_ed10_20_history.o ed_read_ed21_history.o ed_state_vars.o ed_therm_lib.o ed_type_init.o ed_var_tables.o ed_work_vars.o ed_xml_config.o ename_coms.o euler_driver.o events.o farq_leuning.o fatal_error.o fire.o forestry.o fusion_fission_coms.o fuse_fiss_utils.o great_circle.o grid_coms.o growth_balive.o h5_output.o hdf5_coms.o hdf5_utils.o heun_driver.o hybrid_driver.o hydrology_coms.o hydrology_constants.o init_hydro_sites.o invmondays.o landuse_init.o lapse.o leaf_database.o libxml2f90.f90_pp.o lsm_hyd.o mem_polygons.o met_driver_coms.o mortality.o multiple_scatter.o numutils.o old_twostream_rad.o optimiz_coms.o phenology_aux.o phenology_coms.o phenology_driv.o phenology_startup.o photosyn_driv.o physiology_coms.o pft_coms.o radiate_driver.o radiate_utils.o reproduction.o rk4_coms.o rk4_derivs.o rk4_driver.o rk4_integ_utils.o rk4_misc.o rk4_stepper.o rsys.o soil_coms.o soil_respiration.o stable_cohorts.o structural_growth.o therm_lib.o therm_lib8.o twostream_rad.o update_derived_props.o utils_c.o utils_f.o vegetation_dynamics.o
cp -f /Users/manfredo/Desktop/ED2/ED/src/driver/edmain.F90 edmain.F90
ifort -c -DUSE_INTERF=1 -DUSENC=0 -DMAC_OS_X -DUSE_HDF5=1 -DUSE_COLLECTIVE_MPIO=0 -DUSE_MPIWTIME=0 -O0 -gen-interfaces -I/usr/include/malloc -I/Users/manfredo/Desktop/ED2/ED/src/include -I/usr/local/hdf5_mio/include edmain.F90
rm -f edmain.F90
ifort -o /Users/manfredo/Desktop/ED2/ED/build/ed_2.1-opt edmain.o -I/usr/local/hdf5_mio/include/Users/manfredo/Desktop/ED2/ED/build/ed_2.1-opt.a -lm -lz -L/usr/local/hdf5_mio/lib -lhdf5 -lhdf5_fortran -lhdf5_hl
ifort version 14.0.4
ld: warning: path '/dev/null' following -L not a directory
Undefined symbols for architecture x86_64:
"_decomp_coms_mp_cwd_frac_", referenced from:
_init_decomp_params_ in ed_2.1-opt.a(ed_params.o)
_update_polygon_derived_props_ in ed_2.1-opt.a(update_derived_props.o)
_read_ed_xml_config_ in ed_2.1-opt.a(ed_xml_config.o)
_write_ed_xml_config_ in ed_2.1-opt.a(ed_xml_config.o)
_resp_rh_ in ed_2.1-opt.a(soil_respiration.o)
"_decomp_coms_mp_decay_rate_fsc_", referenced from:
_init_decomp_params_ in ed_2.1-opt.a(ed_params.o)
_read_ed_xml_config_ in ed_2.1-opt.a(ed_xml_config.o)
_write_ed_xml_config_ in ed_2.1-opt.a(ed_xml_config.o)
_resp_rh_ in ed_2.1-opt.a(soil_respiration.o)
_update_c_and_n_pools_ in ed_2.1-opt.a(soil_respiration.o)
another bunch of similar errors
ld: symbol(s) not found for architecture x86_64
make[1]: *** [/Users/manfredo/Desktop/ED2/ED/build//ed_2.1-opt] Error 1
make: *** [all] Error 2
file ed_params.f90 reads
subroutine init_decomp_params()
use decomp_coms , only : n_decomp_lim
decomp_coms.f90 is a module file.
This is the important part of the Makefile
#----- Define path and compilation --------------------------------------------------------#
include paths.mk
include include.mk.$(OPT)
#------------------------------------------------------------------------------------------#
#------------------------------------------------------------------------------------------#
# Double check that the "LOWO" flags have been set. In case they have not, clone the #
# standard options. LOWO stands for LOWer Optimisation, and these flags are used for a #
# subroutines that are taking several hours to compile with ifort-13 (ed_state_vars.f90 #
# and a few others). #
#------------------------------------------------------------------------------------------#
ifeq ($(F_LOWO_OPTS),)
F_LOWO_OPTS = $(F_OPTS)
endif
#------------------------------------------------------------------------------------------#
#----- Compiler commands. -----------------------------------------------------------------#
INCLUDES = $(PAR_INCS) -I$(ED_INCS) $(HDF5_INCS) $(MPI_INCS)
F90_COMMAND = $(F_COMP) -c $(F_OPTS) $(INCLUDES) $(PAR_DEFS)
F90_LOWO_COMMAND = $(F_COMP) -c $(F_LOWO_OPTS) $(INCLUDES) $(PAR_DEFS)
FPP_COMMAND = $(F_COMP) -c -DUSE_INTERF=$(USE_INTERF) -DUSENC=$(USENC) -D$(CMACH) \
-DUSE_HDF5=$(USE_HDF5) -DUSE_COLLECTIVE_MPIO=$(USE_COLLECTIVE_MPIO) \
-DUSE_MPIWTIME=$(USE_MPIWTIME) $(F_OPTS) $(INCLUDES) $(PAR_DEFS)
FPP_LOWO_COMMAND = $(F_COMP) -c -DUSE_INTERF=$(USE_INTERF) -DUSENC=$(USENC) -D$(CMACH) \
-DUSE_HDF5=$(USE_HDF5) -DUSE_COLLECTIVE_MPIO=$(USE_COLLECTIVE_MPIO) \
-DUSE_MPIWTIME=$(USE_MPIWTIME) $(F_LOWO_OPTS) $(INCLUDES) $(PAR_DEFS)
CXX_COMMAND = $(C_COMP) -c $(C_OPTS) -D$(CMACH) $(HDF5_INCS) $(INCLUDES) $(PAR_DEFS)
#------------------------------------------------------------------------------------------#
#----- Define archive and executable names. -----------------------------------------------#
EXE=$(BASE)/ed_$(ED_VERSION)-$(OPT)
LIBMODEL=$(BASE)/ed_$(ED_VERSION)-$(OPT).a
#------------------------------------------------------------------------------------------#
include objects.mk
#----- Define targets. --------------------------------------------------------------------#
all:
make gendep
make $(EXE)
make $(EXE)
make $(EXE)
make $(EXE)
make $(EXE)
gendep:
@echo ""
./generate_deps.sh $(ED_ROOT)
@echo === Finished dependencies ===
$(EXE): $(LIBMODEL) $(MAINOBJ)
@echo ""
$(LOADER) -o $(EXE) edmain.o $(LOADER_OPTS) $(INCLUDES) $(LIBMODEL) $(HDF5_LIBS) \
$(PAR_LIBS) $(NC_LIBS) $(LIBS) $(LOADER_OPTS)
@echo ""
@echo Finished building === $(EXE)
@echo ""
$(MAINOBJ): $(MAIN)
@echo ""
cp -f $< $(<F:.F90=.F90)
$(FPP_COMMAND) $(<F:.F90=.F90)
rm -f $(<F:.F90=.F90)
$(LIBMODEL): $(OBJ_MODEL)
$(ARCHIVE) $(LIBMODEL) $(OBJ_MODEL)
which includes the following file (objects.mk)
#Makefile objects_edofl.mk
# Define main source.
MAIN = $(ED_DRIVER)/edmain.F90
MAINOBJ = edmain.o
# Define objects.
OBJ_MODEL = \
allometry.o \
an_header.o \
average_utils.o \
bdf2_solver.o \
budget_utils.o \
canopy_air_coms.o \
canopy_layer_coms.o \
canopy_radiation_coms.o \
canopy_struct_dynamics.o \
c34constants.o \
charutils.o \
consts_coms.o \
dateutils.o \
decomp_coms.o \
detailed_coms.o \
disturbance.o \
other_objects
and this other file (include.mk.opt.macosx)
MAKE=/usr/bin/make
# libraries.
BASE=$(ED_ROOT)/build/
# Activate appropriate parts below, comment out others.
# HDF 5 Libraries
# ED2 HAS OPTIONAL HDF 5 I/O
# If you wish to use this functionality specify USE_HDF5=1
# and specify the location of the include directory
# library files. Make sure you include the zlib.a location too.
USE_HDF5=1
HDF5_INCS=-I/usr/local/hdf5_mio/include
HDF5_LIBS=-lm -lz -L/usr/local/hdf5_mio/lib -lhdf5 -lhdf5_fortran -lhdf5_hl
#---------------------------------------------------------------
# If you have a version of hdf5 compiled in parallel, then you
# may benefit from collective I/O, then use this flag = 1
# Otherwise, set it to zero.
USE_COLLECTIVE_MPIO=0
#---------------------------------------------------------------
# netCDF libraries ---------------------------------------------
# If you have netCDF set USENC=1 and type the lib folder
# at NC_LIBS, with the leading -L (e.g. -L/usr/local/lib).
# If you don't have it, leave USENC=0 and type a dummy
# folder for NC_LIBS (e.g. -L/dev/null or leave it blank)
USENC=0
NC_LIBS=-L/dev/null
# --------------------------------------------------------------
# interface ----------------------------------------------------
# This should be 1 unless you are running with -gen-interfaces.
# Interfaces usually make the compilation to crash when the
# -gen-interfaces option are on, so this flag bypass all
# interfaces in the code.
USE_INTERF=1
# MPI_Wtime. ---------------------------------------------------
# If USE_MPIWTIME=1, then it will use MPI libraries to compute
# the wall time (the only double-precision intrinsic). In case
# you don't have it, leave USE_MPIWTIME=0, in which case it will
# use a simpler, single-precision function.
USE_MPIWTIME=0
#----------------- MAC_OS_X (Leopard) ---- gfortran/gcc ---------------
CMACH=MAC_OS_X
F_COMP=ifort
C_COMP=icc
LOADER=ifort
MOD_EXT=mod
##################################### COMPILER OPTIONS #####################################
#------------------------------------------------------------------------------------------#
# A. Pickiest - Use this whenever you change arguments on functions and subroutines. #
# This will perform the same tests as B but it will also check whether all #
# arguments match between subroutine declaration and subroutine calls. #
# WARNING: In order to really check all interfaces you must compile with #
# this option twice: #
# 1. Compile (./compile.sh) #
# 2. Prepare second compilation(./2ndcomp.sh) #
# 3. Compile one more time (./compile.sh) #
# If the compilation fails either at step 1 or 3, then your code has inter- #
# face problems. If it successfully compiles, then you can switch to B. #
#------------------------------------------------------------------------------------------#
#USE_INTERF=0
#F_OPTS=-O0 -Wall -ffpe-trap=invalid,zero,overflow,underflow,precision,denormal \
# -ffree-line-length-none
#C_OPTS=-O0 -DUNDERSCORE -DLITTLE
#LOADER_OPTS=-O0 -ffree-line-length-none
#------------------------------------------------------------------------------------------#
# E. Fast - This is all about performance, use only when you are sure that the model has #
# no code problem, and you want results asap. This will not check for any #
# problems, which means that this is an option suitable for end users, not de- #
# velopers. #
#------------------------------------------------------------------------------------------#
USE_INTERF=1
F_OPTS= -O0 -v
C_OPTS= -DLITTLE -v
F_LOWO_OPTS= -O0
LOADER_OPTS= -ffixed-line-length-none
#------------------------------------------------------------------------------------------#
#---------------If using scritps 'mpicc' e 'mpif90'---------------'
MPI_PATH=
PAR_INCS=-I/usr/include/malloc
PAR_LIBS=
PAR_DEFS=
#-----------------------------------------------------------------
# For IBM,HP,SGI,ALPHA,LINUX use these:
ARCHIVE=ar rs
# For NEC SX-6
#ARCHIVE=sxar rs
# For SUN,CONVEX
#ARCHIVE=ar r'
When looking at the source files these errors kind of make sense because most of the subroutines are declared without explicit interfaces, that is without a module
and a corresponding use
statement.
The problem is that the package encompasses hundreds of files and going through all of them to change the interfaces is not feasible. Moreover the same package can be built on other platforms/compilers.
Thus my question is, is it possible to give the compiler options that enable the correct linking even if most of the subroutines don't have explicit interface. Thanks for help