#------------------------------------------------------------------------------- # Common Makefile for CICE # # Command-line variables # MACFILE= ~ the macros definition file to use/include # EXEC= ~ name given to executable, default is a.out # VPATH= ~ VPATH , default is . (cwd only) # SRCS= ~ list of src files, default is all .c .F .F90 files in VPATH # VPFILE= ~ file with list of dirs, used to create VPATH # SRCFILE= ~ file with list of src files, used to create SRCS # # ~ any macro definitions found in this file or the included # MACFILE will be over-riden by cmd-line macro definitions # MODEL= ~ a standard macro definition, often found in the included # MACFILE, used to trigger special compilation flags # # Usage examples: # % gmake -j 8 VPFILE=Filepath EXEC=${ICE_RUNDIR}/cice \ # -f ${ICE_CASEDIR}/Makefile MACFILE=${ICE_CASEDIR}/Macros.conrad_intel \ # DEPFILE=${ICE_CASEDIR}/makdep.c cice #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # parse cmd-line and establish values for EXEC, VPATH, SRCS, OBJS, etc #------------------------------------------------------------------------------- EXEC := a.out MACFILE := NONE DEPFILE := NONE MODEL := NONE VPFILE := NONE VPATH := . SRCFILE := NONE SRCS := NONE # dependency generator DEPGEN := ./makdep OBJS_DEPGEN := $(DEPFILE) ifneq ($(ESMFMKFILE),) -include $(ESMFMKFILE) INCLDIR += $(ESMF_F90COMPILEPATHS) SLIBS += $(ESMF_F90LINKPATHS) $(ESMF_F90LINKRPATHS) $(ESMF_F90ESMFLINKLIBS) endif ifneq ($(VPATH),.) # this variable was specified on cmd line or in an env var else ifneq ($(VPFILE),NONE) # explicit list of VPATH dirs is provided VPATH := $(wildcard . $(shell cat $(VPFILE) ) ) endif endif ifneq ($(SRCS),NONE) # this variable was specified on cmd line or in an env var else ifneq ($(SRCFILE),NONE) # explicit list of src files is provided SRCS := $(shell cat $(SRCFILE) ) else # list of src files is all .F90 .F .c files in VPATH SRCS := $(wildcard $(addsuffix /*.F90 , $(VPATH)) \ $(addsuffix /*.[cF], $(VPATH)) ) endif endif OBJS := $(addsuffix .o, $(sort $(basename $(notdir $(SRCS))))) DEPS := $(addsuffix .d, $(sort $(basename $(notdir $(SRCS))))) INCS := $(patsubst %,-I%, $(VPATH) ) MODDIR:= -I. RM := rm AR := ar .SUFFIXES: .PHONY: all cice libcice targets target db_files db_flags clean realclean helloworld calchk sumchk bcstchk gridavgchk halochk optargs opticep all: $(EXEC) cice: $(EXEC) #------------------------------------------------------------------------------- # include the file that provides macro definitions required by build rules #------------------------------------------------------------------------------- -include $(MACFILE) #------------------------------------------------------------------------------- # echo supported targets, file names, paths, compile flags, etc. used during build #------------------------------------------------------------------------------- targets: @echo " " @echo "Supported Makefile Targets are: cice, libcice, makdep, depends, clean, realclean" @echo " Diagnostics: targets, db_files, db_flags" @echo " Unit Tests : helloworld, calchk, sumchk, bcstchk, gridavgchk, halochk, optargs, opticep" target: targets db_files: @echo " " @echo "* EXEC := $(EXEC)" @echo "* MACFILE := $(MACFILE)" @echo "* VPFILE := $(VPFILE)" @echo "* VPATH := $(VPATH)" @echo "* SRCFILE := $(SRCFILE)" @echo "* INCS := $(INCS)" @echo "* SRCS := $(SRCS)" @echo "* OBJS := $(OBJS)" @echo "* DEPS := $(DEPS)" @echo "* ULIBS := $(ULIBS)" @echo "* SLIBS := $(SLIBS)" @echo "* INCLDIR := $(INCLDIR)" @echo "* DEPFILE := $(DEPFILE)" @echo "* OBJS_DEPGEN := $(OBJS_DEPGEN)" db_flags: @echo " " @echo "* $(DEPGEN) := $(SCC) $(CFLAGS_HOST)" @echo "* %.d : %.c := $(DEPGEN) $(INCS)" @echo "* %.d : %.F := $(DEPGEN) $(INCS)" @echo "* %.d : %.F90 := $(DEPGEN) $(INCS)" @echo "* %.d : %.H := $(DEPGEN) $(INCS)" @echo "* cpp := $(CPP) $(CPPFLAGS) $(CPPDEFS) $(INCLDIR)" @echo "* .c.o := $(CC) $(CFLAGS) $(CPPDEFS) $(INCLDIR)" @echo "* .F.o := $(FC) -c $(FFLAGS) $(FIXEDFLAGS) $(CPPDEFS) $(INCLDIR)" @echo "* .F90.o := $(FC) -c $(FFLAGS) $(FREEFLAGS) $(CPPDEFS) $(MODDIR) $(INCLDIR)" @echo "* libcice := $(AR) -r $(EXEC) " @echo "* $(notdir $(EXEC)) := $(LD) $(LDFLAGS) $(ULIBS) $(SLIBS)" #------------------------------------------------------------------------------- # build rule for makdep: MACFILE, cmd-line, or env vars must provide # the needed macros #------------------------------------------------------------------------------- $(DEPGEN): $(OBJS_DEPGEN) @ echo "Building makdep" $(SCC) -o $@ $(CFLAGS_HOST) $< #------------------------------------------------------------------------------- # unit tests #------------------------------------------------------------------------------- # this builds all dependent source code automatically even though only a subset might actually be used # this is no different than the cice target and in fact the binary is called cice # it exists just to create separation as needed for unit tests calchk: $(EXEC) sumchk: $(EXEC) bcstchk: $(EXEC) gridavgchk: $(EXEC) halochk: $(EXEC) opticep: $(EXEC) # this builds just a subset of source code specified explicitly and requires a separate target HWOBJS := helloworld.o helloworld: $(HWOBJS) $(LD) -o $(EXEC) $(LDFLAGS) $(HWOBJS) $(ULIBS) $(SLIBS) OAOBJS := optargs.o optargs_subs.o optargs: $(OAOBJS) $(LD) -o $(EXEC) $(LDFLAGS) $(OAOBJS) $(ULIBS) $(SLIBS) #------------------------------------------------------------------------------- # build rules: MACFILE, cmd-line, or env vars must provide the needed macros #------------------------------------------------------------------------------- $(EXEC): $(OBJS) $(LD) -o $(EXEC) $(LDFLAGS) $(OBJS) $(ULIBS) $(SLIBS) libcice: $(OBJS) @ echo "$(AR) -r $(EXEC) $(OBJS)" $(AR) -r $(EXEC) $(OBJS) %.o : %.c $(CC) $(CFLAGS) $(CPPDEFS) $(INCLDIR) $< %.o : %.F %.d $(FC) -c $(FFLAGS) $(FIXEDFLAGS) $(CPPDEFS) $(INCLDIR) $< %.o : %.F90 %.d $(FC) -c $(FFLAGS) $(FREEFLAGS) $(CPPDEFS) $(MODDIR) $(INCLDIR) $< clean: $(RM) -f *.o *.d *.mod $(EXEC) realclean: clean $(RM) -f $(DEPGEN) #------------------------------------------------------------------------------- # Build & include dependency files #------------------------------------------------------------------------------- # ASSUMPTIONS: # o the dependency generator, $(DEPGEN), can be built, # its cmd line syntax is compatible with the build rules below. Eg, for # each .o file, there is a corresponding .d (dependency) file, and both # will be dependent on the same src file, eg. foo.o foo.d : foo.F90 # Also, the dependancy genorator's capabilities, limitations, and assumptions # are understood & accepted. #------------------------------------------------------------------------------- depends: $(DEPS) %.d : %.c $(DEPGEN) @ echo "Building dependency for $@" @ $(DEPGEN) -f $(INCS) $< | head -3 > $@ %.d : %.F $(DEPGEN) @ echo "Building dependency for $@" @ $(DEPGEN) -f $(INCS) $< > $@ %.d : %.F90 $(DEPGEN) @ echo "Building dependency for $@" @ $(DEPGEN) -f $(INCS) $< > $@ %.d : %.H $(DEPGEN) @ echo "Building dependency for $@" @ $(DEPGEN) -f $(INCS) $< > $@ # the if-tests prevent DEPS files from being created when they're not needed ifneq ($(MAKECMDGOALS), db_files) ifneq ($(MAKECMDGOALS), db_flags) ifneq ($(MAKECMDGOALS), clean) ifneq ($(MAKECMDGOALS), realclean) ifneq ($(MAKECMDGOALS), targets) ifneq ($(MAKECMDGOALS), target) ifneq ($(MAKECMDGOALS), makdep) ifneq ($(MAKECMDGOALS), depends) -include $(DEPS) endif endif endif endif endif endif endif endif