Skip to content

Commit

Permalink
Makedep (#1)
Browse files Browse the repository at this point in the history
* Autoconf: Fix makedep path

The current path of makedep in the autoconf build assumes a directory tree as in .testing.  This patch uses the 
generalized @SrcDir@ to support more general autoconf builds.

Other minor changes:
* The `depend` rule was split into an explicit Makefile.dep rule and a phony rule to support `make depend`

* SRC_DIRS shell assignment is replaced with an Autoconf macro.

* A "self-generate" rule was added to `Makefile.in`, so that changes to `Makefile.in` do not trigger a full `./configure` run and regeneration of `.config.status`.

  This could possibly be extended to support `make depend` but let's first see how this one goes.

* Autoconf: makedep uses autoconf var conventions

This patch changes the makedep script to use autoconf environment variable conventions rather than mkmf ones:

* FCFLAGS in place of FFLAGS

* DEFS in place of CPPDEFS

* LDFLAGS and LIBS rather than just LDFLAGS
  (NOTE: This differs from Makefile's LDLFLAGS/LDLIBS)

This also allowed us to remove the custom build rule in the FMS build. Note that we now use an autoconf-friendly rule, rather than the default Makefile rule (which was arguably for fixed-format Fortran anyway).

The description of autoconf->mkmf translation from the Makefile templates has also been removed, since they're no longer relevant.

Some other minor changes in this build:

* The `make depend` rule was added to the FMS Makefile template.

* @SrcDir@ is directly passed to FMS makedep, rather than identically re-defining it in a variable.

* Testing: Resolve makedep paths

This patch resolves some issues relating to finding the path to makedep in both .testing and more generalized autoconf builds.

An explicit autoconf test for makedep has been added, with a default path which includes the `ac` directory relative to `deps`.

The .testing directory, which does not lie within `ac`, instead modifies the PATH to allow autoconf to find makedep.

The absolute path is determined and substituted into the appropriate Makefile.in template.

Some redundant operations in .testing/Makefile have been removed, but I suspect there are even more.  Much of the structure required to support mkmf and list_paths is probably no longer needed.
  • Loading branch information
marshallward committed Jun 17, 2022
1 parent 546312a commit 4bcc849
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 130 deletions.
3 changes: 1 addition & 2 deletions .testing/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ $(TARGET_CODEBASE):
# FMS

# Set up the FMS build environment variables
FMS_ENV = PATH="${PATH}:../../bin" FCFLAGS="$(FCFLAGS_DEBUG)"
FMS_ENV = PATH="${PATH}:$(realpath ../ac)" FCFLAGS="$(FCFLAGS_DEBUG)"

# TODO: *.mod dependencies?
$(DEPS)/lib/libFMS.a: $(DEPS)/fms/build/libFMS.a
Expand All @@ -335,7 +335,6 @@ $(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)
Expand Down
65 changes: 17 additions & 48 deletions ac/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,34 @@
#
# Compiler flags are configured by autoconf's configure script.
#
# 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.
# Source code dependencies are configured by makedep and saved to Makefile.dep.

FC = @FC@
LD = @FC@
MAKEDEP = @MAKEDEP@

CPPDEFS = @DEFS@
DEFS = @DEFS@
CPPFLAGS = @CPPFLAGS@
FFLAGS = @FCFLAGS@
LDFLAGS = @LDFLAGS@ @LIBS@

FCFLAGS = @FCFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @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:
../../../ac/makedep -o Makefile.dep $(SRC_DIRS)
depend: Makefile.dep
Makefile.dep:
$(MAKEDEP) -o Makefile.dep $(SRC_DIRS)


# Delete any files associated with configuration (including the Makefile).
.PHONY: distclean
Expand Down
17 changes: 12 additions & 5 deletions ac/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,20 @@ AC_COMPILE_IFELSE(
]
)

SRC_DIRS="${srcdir}/src ${MODEL_FRAMEWORK} ${srcdir}/config_src/external ${DRIVER_DIR} ${MEM_LAYOUT}"
AC_CONFIG_COMMANDS([Makefile.dep],
[make depend])

# 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])

# Prepare output
AC_SUBST(CPPFLAGS)
AC_SUBST(SRC_DIRS)
AC_SUBST([CPPFLAGS])
AC_CONFIG_FILES([Makefile:${srcdir}/ac/Makefile.in])
AC_OUTPUT

16 changes: 5 additions & 11 deletions ac/deps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ SHELL = bash
# Disable implicit variables
MAKEFLAGS += -R


# FMS framework
FMS_URL ?= https://github.com/NOAA-GFDL/FMS.git
FMS_COMMIT ?= 2019.01.03
Expand All @@ -26,14 +25,8 @@ FMS_SOURCE = $(call SOURCE,fms/src)
# Rules

.PHONY: all
all: bin/makedep lib/libFMS.a

#---
# makedep script
all: lib/libFMS.a

bin/makedep: ../../ac/makedep
mkdir -p $(@D)
cp $^ $@

#---
# FMS build
Expand All @@ -45,7 +38,7 @@ bin/makedep: ../../ac/makedep


# TODO: track *.mod copy?
lib/libFMS.a: fms/build/libFMS.a fms/build/Makefile
lib/libFMS.a: fms/build/libFMS.a
mkdir -p {lib,include}
cp fms/build/libFMS.a lib/libFMS.a
cp fms/build/*.mod include
Expand All @@ -55,7 +48,7 @@ fms/build/libFMS.a: fms/build/Makefile
make -C fms/build libFMS.a


fms/build/Makefile: Makefile.fms.in fms/src/configure bin/makedep
fms/build/Makefile: Makefile.fms.in fms/src/configure
mkdir -p fms/build
cp Makefile.fms.in fms/src/Makefile.in
cd $(@D) && ../src/configure --srcdir=../src
Expand All @@ -67,14 +60,15 @@ 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)


.PHONY: clean
clean:
rm -rf fms/build lib include bin
rm -rf fms/build lib include

.PHONY: distclean
distclean: clean
Expand Down
59 changes: 9 additions & 50 deletions ac/deps/Makefile.fms.in
Original file line number Diff line number Diff line change
@@ -1,66 +1,25 @@
# Makefile template for autoconf builds using mkmf
# Makefile template for FMS
#
# Compiler flags are configured by autoconf's configure script.
#
# 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.
# Source code dependencies are configured by makedep and saved to Makefile.dep.

CC = @CC@
FC = @FC@
LD = @FC@
AR = @AR@
MAKEDEP = @MAKEDEP@

CPPDEFS = @DEFS@
DEFS = @DEFS@
CPPFLAGS = @CPPFLAGS@
FFLAGS = @FCFLAGS@
FCFLAGS = @FCFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
ARFLAGS = @ARFLAGS@

SRC_DIRS = @SRC_DIRS@

# Gather modulefiles
TMPFILES = $(wildcard *.mod)

-include Makefile.dep

.PHONY: depend
depend:
../../bin/makedep -o Makefile.dep -f '$$(FC) $$(CPPFLAGS) $$(CPPDEFS) $$(FFLAGS) -c $$<' -x libFMS.a -d $(SRC_DIRS)
depend: Makefile.dep
Makefile.dep:
$(MAKEDEP) -o Makefile.dep -x libFMS.a @srcdir@
22 changes: 14 additions & 8 deletions ac/deps/configure.fms.ac
Original file line number Diff line number Diff line change
Expand Up @@ -158,20 +158,26 @@ 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_SUBST([AR])
AC_SUBST([ARFLAGS])

AC_CONFIG_COMMANDS([Makefile.dep], [make depend])

SRC_DIRS="../src"
AC_CONFIG_COMMANDS([Makefile.dep],
[make depend])
AC_SUBST([CPPFLAGS])

# Prepare output
AC_SUBST(CPPFLAGS)
AC_SUBST(SRC_DIRS)
AC_CONFIG_FILES(Makefile)
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
12 changes: 6 additions & 6 deletions ac/makedep
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ 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) $(FFLAGS) $(CPPFLAGS) -c $<'"
echo " '$(FC) $(DEFS) $(FCFLAGS) $(CPPFLAGS) -c $<'"
}

# Defaults
makefile=Makefile.dep
debug=0
executable=""
librarymode=0
compile_line='$(FC) $(FFLAGS) $(CPPFLAGS) -c $<'
compile_line='$(FC) $(DEFS) $(FCFLAGS) $(CPPFLAGS) -c $<'

while getopts dho:x:f: option
do
Expand Down Expand Up @@ -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=$(/lib/cpp -E -MM $I $F | tr -d '\n' | sed 's:\\::g') # line of form a.o: a.F b.h c.h ...
H=$(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
Expand Down Expand Up @@ -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=$(/lib/cpp -E -MM $I $F | tr -d '\n' | sed 's:\\::g') # line of form a.o: a.F b.h c.h ...
H=$(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
Expand Down Expand Up @@ -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) $(CPPDEFS) $(CPPFLAGS) $(CFLAGS) -c $<' ${i} >> ${makefile} # compile rule
echo -e '\t$(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS) -c $<' ${i} >> ${makefile} # compile rule
done

if [ ${#lib} -ne 0 ]; then # rule to build library
Expand All @@ -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) -o $@ $^ $(LDFLAGS)' >> ${makefile} # link rule
echo -e '\t$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)' >> ${makefile} # link rule
done
elif [ -z "$lib" ]; then
echo "Warning: no library target specified (with -x) and no programs found!"
Expand Down

0 comments on commit 4bcc849

Please sign in to comment.