diff --git a/.testing/Makefile b/.testing/Makefile index 7f52d2a47a..64686c0727 100644 --- a/.testing/Makefile +++ b/.testing/Makefile @@ -324,7 +324,7 @@ $(TARGET_CODEBASE): # FMS # Set up the FMS build environment variables -FMS_ENV = PATH="${PATH}:$(realpath ../ac)" FCFLAGS="$(FCFLAGS_DEBUG)" +FMS_ENV = PATH="${PATH}:../../bin" FCFLAGS="$(FCFLAGS_DEBUG)" # TODO: *.mod dependencies? $(DEPS)/lib/libFMS.a: $(DEPS)/fms/build/libFMS.a @@ -335,6 +335,7 @@ $(DEPS)/fms/build/libFMS.a: $(DEPS)/fms/build/Makefile $(DEPS)/fms/build/Makefile: $(DEPS)/fms/src/configure $(DEPS)/Makefile.fms.in $(FMS_ENV) $(MAKE) -C $(DEPS) fms/build/Makefile + $(MAKE) -C $(DEPS) fms/build/Makefile $(DEPS)/Makefile.fms.in: ../ac/deps/Makefile.fms.in $(DEPS)/Makefile cp $< $(DEPS) diff --git a/ac/Makefile.in b/ac/Makefile.in index 2e482ab0c5..711fab1f6f 100644 --- a/ac/Makefile.in +++ b/ac/Makefile.in @@ -2,34 +2,65 @@ # # Compiler flags are configured by autoconf's configure script. # -# Source code dependencies are configured by makedep and saved to Makefile.dep. +# Source code dependencies are configured by mkmf and list_paths, specified in +# the `Makefile.mkmf` file. +# +# mkmf conventions are close, but not identical, to autoconf. We attempt to +# map the autoconf variables to the mkmf variables. +# +# The following variables are used by Makefiles generated by mkmf. +# +# CC C compiler +# CXX C++ compiler +# FC Fortran compiler (f77 and f90) +# LD Linker +# AR Archiver +# +# CPPDEFS Preprocessor macros +# CPPFLAGS C preprocessing flags +# CXXFLAGS C++ preprocessing flags +# FPPFLAGS Fortran preprocessing flags +# +# CFLAGS C compiler flags +# FFLAGS Fortran compiler flags +# LDFLAGS Linker flags + libraries +# ARFLAGS Archiver flags +# +# OTHERFLAGS Additional flags for all languages (C, C++, Fortran) +# OTHER_CFLAGS Optional C flags +# OTHER_CXXFLAGS Optional C++ flags +# OTHER_FFLAGS Optional Fortran flags +# TMPFILES Placeholder for `make clean` deletion (as `make neat`). +# +# +# NOTES: +# - FPPFLAGS and FFLAGS always appear as a pair, and autoconf does not use +# FPPFLAGS, so FPPFLAGS does not serve much purpose. +# +# - mkmf's FFLAGS does not distinguish between autoconf's fixed-format +# FFLAGS and free-format FCFLAGS. +# +# - LDFLAGS does not distinguish between autoconf's LDFLAGS and LIBS. +# It also places both after the executable rather than just LIBS. FC = @FC@ LD = @FC@ -MAKEDEP = @MAKEDEP@ -DEFS = @DEFS@ +CPPDEFS = @DEFS@ CPPFLAGS = @CPPFLAGS@ -FCFLAGS = @FCFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ +FFLAGS = @FCFLAGS@ +LDFLAGS = @LDFLAGS@ @LIBS@ + SRC_DIRS = @SRC_DIRS@ +# Gather modulefiles +TMPFILES = $(wildcard *.mod) -include Makefile.dep - -# Generate Makefile from template -Makefile: @srcdir@/ac/Makefile.in config.status - ./config.status - - -# Generate dependencies .PHONY: depend -depend: Makefile.dep -Makefile.dep: - $(MAKEDEP) -o Makefile.dep $(SRC_DIRS) - +depend: + ../../../ac/makedep -o Makefile.dep $(SRC_DIRS) # Delete any files associated with configuration (including the Makefile). .PHONY: distclean diff --git a/ac/configure.ac b/ac/configure.ac index 15a14708e0..02e39c63a0 100644 --- a/ac/configure.ac +++ b/ac/configure.ac @@ -223,20 +223,13 @@ AC_COMPILE_IFELSE( ] ) - -# Verify that makedep is available -AC_PATH_PROG([MAKEDEP], [makedep], [${srcdir}/ac/makedep]) -AC_SUBST([MAKEDEP]) - - -# Generate source list and configure dependency command -AC_SUBST([SRC_DIRS], - ["${srcdir}/src ${MODEL_FRAMEWORK} ${srcdir}/config_src/external ${DRIVER_DIR} ${MEM_LAYOUT}"] -) -AC_CONFIG_COMMANDS([Makefile.dep], [make depend]) +SRC_DIRS="${srcdir}/src ${MODEL_FRAMEWORK} ${srcdir}/config_src/external ${DRIVER_DIR} ${MEM_LAYOUT}" +AC_CONFIG_COMMANDS([Makefile.dep], + [make depend]) # Prepare output -AC_SUBST([CPPFLAGS]) +AC_SUBST(CPPFLAGS) +AC_SUBST(SRC_DIRS) AC_CONFIG_FILES([Makefile:${srcdir}/ac/Makefile.in]) AC_OUTPUT diff --git a/ac/deps/Makefile b/ac/deps/Makefile index af567f6a72..f56b762883 100644 --- a/ac/deps/Makefile +++ b/ac/deps/Makefile @@ -6,6 +6,7 @@ SHELL = bash # Disable implicit variables MAKEFLAGS += -R + # FMS framework FMS_URL ?= https://github.com/NOAA-GFDL/FMS.git FMS_COMMIT ?= 2019.01.03 @@ -25,8 +26,14 @@ FMS_SOURCE = $(call SOURCE,fms/src) # Rules .PHONY: all -all: lib/libFMS.a +all: bin/makedep lib/libFMS.a + +#--- +# makedep script +bin/makedep: ../../ac/makedep + mkdir -p $(@D) + cp $^ $@ #--- # FMS build @@ -38,7 +45,7 @@ all: lib/libFMS.a # TODO: track *.mod copy? -lib/libFMS.a: fms/build/libFMS.a +lib/libFMS.a: fms/build/libFMS.a fms/build/Makefile mkdir -p {lib,include} cp fms/build/libFMS.a lib/libFMS.a cp fms/build/*.mod include @@ -48,7 +55,7 @@ fms/build/libFMS.a: fms/build/Makefile make -C fms/build libFMS.a -fms/build/Makefile: Makefile.fms.in fms/src/configure +fms/build/Makefile: Makefile.fms.in fms/src/configure bin/makedep mkdir -p fms/build cp Makefile.fms.in fms/src/Makefile.in cd $(@D) && ../src/configure --srcdir=../src @@ -60,7 +67,6 @@ fms/src/configure: configure.fms.ac $(FMS_SOURCE) | fms/src cp -r m4 $(@D) cd $(@D) && autoreconf -i - fms/src: git clone $(FMS_URL) $@ git -C $@ checkout $(FMS_COMMIT) @@ -68,7 +74,7 @@ fms/src: .PHONY: clean clean: - rm -rf fms/build lib include + rm -rf fms/build lib include bin .PHONY: distclean distclean: clean diff --git a/ac/deps/Makefile.fms.in b/ac/deps/Makefile.fms.in index fc580a8c9e..499a1a6a72 100644 --- a/ac/deps/Makefile.fms.in +++ b/ac/deps/Makefile.fms.in @@ -1,25 +1,66 @@ -# Makefile template for FMS +# Makefile template for autoconf builds using mkmf # # Compiler flags are configured by autoconf's configure script. # -# Source code dependencies are configured by makedep and saved to Makefile.dep. +# Source code dependencies are configured by mkmf and list_paths, specified in +# the `Makefile.mkmf` file. +# +# mkmf conventions are close, but not identical, to autoconf. We attempt to +# map the autoconf variables to the mkmf variables. +# +# The following variables are used by Makefiles generated by mkmf. +# +# CC C compiler +# CXX C++ compiler +# FC Fortran compiler (f77 and f90) +# LD Linker +# AR Archiver +# +# CPPDEFS Preprocessor macros +# CPPFLAGS C preprocessing flags +# CXXFLAGS C++ preprocessing flags +# FPPFLAGS Fortran preprocessing flags +# +# CFLAGS C compiler flags +# FFLAGS Fortran compiler flags +# LDFLAGS Linker flags + libraries +# ARFLAGS Archiver flags +# +# OTHERFLAGS Additional flags for all languages (C, C++, Fortran) +# OTHER_CFLAGS Optional C flags +# OTHER_CXXFLAGS Optional C++ flags +# OTHER_FFLAGS Optional Fortran flags +# TMPFILES Placeholder for `make clean` deletion (as `make neat`). +# +# +# NOTES: +# - FPPFLAGS and FFLAGS always appear as a pair, and autoconf does not use +# FPPFLAGS, so FPPFLAGS does not serve much purpose. +# +# - mkmf's FFLAGS does not distinguish between autoconf's fixed-format +# FFLAGS and free-format FCFLAGS. +# +# - LDFLAGS does not distinguish between autoconf's LDFLAGS and LIBS. +# It also places both after the executable rather than just LIBS. CC = @CC@ FC = @FC@ LD = @FC@ AR = @AR@ -MAKEDEP = @MAKEDEP@ -DEFS = @DEFS@ +CPPDEFS = @DEFS@ CPPFLAGS = @CPPFLAGS@ -FCFLAGS = @FCFLAGS@ +FFLAGS = @FCFLAGS@ LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ ARFLAGS = @ARFLAGS@ +SRC_DIRS = @SRC_DIRS@ + +# Gather modulefiles +TMPFILES = $(wildcard *.mod) + -include Makefile.dep .PHONY: depend -depend: Makefile.dep -Makefile.dep: - $(MAKEDEP) -o Makefile.dep -x libFMS.a @srcdir@ +depend: + ../../bin/makedep -o Makefile.dep -f '$$(FC) $$(CPPFLAGS) $$(CPPDEFS) $$(FFLAGS) -c $$<' -x libFMS.a -d $(SRC_DIRS) diff --git a/ac/deps/configure.fms.ac b/ac/deps/configure.fms.ac index 4e0c0f1390..4dc1a6614f 100644 --- a/ac/deps/configure.fms.ac +++ b/ac/deps/configure.fms.ac @@ -158,26 +158,20 @@ AX_FC_ALLOW_ARG_MISMATCH FCFLAGS="$FCFLAGS $ALLOW_ARG_MISMATCH_FCFLAGS" -# Verify makedep -AC_PATH_PROGS([MAKEDEP], [makedep], [], ["${PATH}:${srcdir}/../../.."]) -AS_IF([test -n "${MAKEDEP}"], [ - AC_SUBST([MAKEDEP]) -], [ - AC_MSG_ERROR(["Could not find makedep."]) -]) - # Autoconf does not configure the archiver (ar), as it is handled by Automake. # TODO: Properly configure this tool. For now, we hard-set this to `ar`. AR=ar ARFLAGS=rv -AC_SUBST([AR]) -AC_SUBST([ARFLAGS]) - -AC_CONFIG_COMMANDS([Makefile.dep], [make depend]) +AC_SUBST(AR) +AC_SUBST(ARFLAGS) -AC_SUBST([CPPFLAGS]) +SRC_DIRS="../src" +AC_CONFIG_COMMANDS([Makefile.dep], + [make depend]) # Prepare output -AC_CONFIG_FILES([Makefile]) +AC_SUBST(CPPFLAGS) +AC_SUBST(SRC_DIRS) +AC_CONFIG_FILES(Makefile) AC_OUTPUT diff --git a/ac/makedep b/ac/makedep index 74d9200ce8..cb0a8896e3 100755 --- a/ac/makedep +++ b/ac/makedep @@ -16,7 +16,7 @@ usage() { echo " -x EXEC Name of executable to build. Fails if more than one" echo " is found. If EXEC ends in .a then a library is built." echo " -f CMD String to use in compile rule. Default is:" - echo " '$(FC) $(DEFS) $(FCFLAGS) $(CPPFLAGS) -c $<'" + echo " '$(FC) $(FFLAGS) $(CPPFLAGS) -c $<'" } # Defaults @@ -24,7 +24,7 @@ makefile=Makefile.dep debug=0 executable="" librarymode=0 -compile_line='$(FC) $(DEFS) $(FCFLAGS) $(CPPFLAGS) -c $<' +compile_line='$(FC) $(FFLAGS) $(CPPFLAGS) -c $<' while getopts dho:x:f: option do @@ -61,7 +61,7 @@ for F in ${A}; do # F is the relative path to source file u=`echo $u | sed s:$m::g` fi if [ ${#u} -ne 0 ]; then o2use["$o"]=$u; fi - H=$(cpp -E -MM $I $F | tr -d '\n' | sed 's:\\::g') # line of form a.o: a.F b.h c.h ... + H=$(/lib/cpp -E -MM $I $F | tr -d '\n' | sed 's:\\::g') # line of form a.o: a.F b.h c.h ... o2H["$o"]=$H h=`echo ${H} | cut -d\ -f3- ` # header files if [ ${#h} -ne 0 ]; then o2head["$o"]=$h; fi @@ -91,7 +91,7 @@ for F in ${A}; do # F is the relative path to source file f=`basename $F` # file name stripped of path o=${f/.c/}.o # object file name o2c["$o"]=$F - H=$(cpp -E -MM $I $F | tr -d '\n' | sed 's:\\::g') # line of form a.o: a.F b.h c.h ... + H=$(/lib/cpp -E -MM $I $F | tr -d '\n' | sed 's:\\::g') # line of form a.o: a.F b.h c.h ... o2H["$o"]=$H h=`echo ${H} | cut -d\ -f3- ` # header files if [ ${#h} -ne 0 ]; then o2head["$o"]=$h; fi @@ -189,7 +189,7 @@ for o in ${OC[@]}; do echo "# incpath:" $i >> ${makefile} fi echo $H ${U[@]} >> ${makefile} # a.mod a.o: a.F b.mod - echo -e '\t$(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS) -c $<' ${i} >> ${makefile} # compile rule + echo -e '\t$(CC) $(CPPDEFS) $(CPPFLAGS) $(CFLAGS) -c $<' ${i} >> ${makefile} # compile rule done if [ ${#lib} -ne 0 ]; then # rule to build library @@ -207,7 +207,7 @@ if [ ${#p2o[@]} -ne 0 ]; then # write rules for linking executables o=${p2o[$p]} l=$(make -f ${makefile} -B -n -t $o | egrep "\.o$" | sed 's:touch ::' | sort) echo $p: $l ${externals[@]} >> ${makefile} - echo -e '\t$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)' >> ${makefile} # link rule + echo -e '\t$(LD) -o $@ $^ $(LDFLAGS)' >> ${makefile} # link rule done elif [ -z "$lib" ]; then echo "Warning: no library target specified (with -x) and no programs found!"