Skip to content

Commit

Permalink
Makefile now invokes submakefiles
Browse files Browse the repository at this point in the history
The top-level Makefile no longer attempts to emulate the MRS build
structure, and now simply invokes the Makefiles of each submodel.
It is no longer the point of reference for testing the suite, which
should now be handled by a parent repository (e.g. Gaea-stats).

The top Makefile is now the starting point for public usage.  As part of
this, the CM2-based models were removed from the default `all` rule.

Many changes were added to reliably track changes in the source code.

* A "FORCE" rule has been introduced to ensure that changes tracked by
  the submakes are also tracked by the top Makefile.  Similar changes
  have been applied to the relevant submakes.

* Library dependency is explicitly tracked inside of the rules, with
  `test .. -nt ...` conditionals.

  This was done because the top Makefile cannot reliably track the state
  of products from the submakes, but there may be a better way to do
  this.

* The MOM6 source was updated to use the latest version of makedep,
  which was required by AM2 to fix some errors in tracking source code
  dependencies.

Several minor fixes are outlined below.

* Many explicit CPPDEFS were removed, and the macros are set by
  autoconf's AC_DEFINE macro, and assigned to DEFS.

* LIBS ordering should now be correct on all systems.  FMS linking is
  once again tested.  GFDL dependencies are explicitly prepended to LIBS
  during autoconf setup.  (Someday, these should be replaced with
  proper tests for each library.)

  As part of this, the CM2-based and ice-ocean configure.ac files have
  been split.

* Minor issues around propagation of environment variables (FCFLAGS,
  etc) have been fixed.
  • Loading branch information
marshallward authored and adcroft committed Jan 31, 2024
1 parent 28768e8 commit 5395ce6
Show file tree
Hide file tree
Showing 10 changed files with 575 additions and 299 deletions.
218 changes: 59 additions & 159 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,131 +1,64 @@
# Test build
BUILD ?= build
MODELS = ocean_only ice_ocean_SIS2 coupled_AM2_LM3_SIS2
DEPS = AM2 atmos_null LM3 land_null ice_param icebergs

# Variable `export` replaces the default autoconf values with empty strings.
# This restores the default values.
CFLAGS ?= -g -O2
FCFLAGS ?= -g -O2

# Pass autoconf environment variables to submakes
export CPPFLAGS
export CC
export MPICC
export CFLAGS
export FC
export MPIFC
export FCFLAGS
export LDFLAGS
export LIBS
export PYTHON

# Disable builtin rules and variables
MAKEFLAGS += -rR

#---

# Public models
.PHONY: all
all: ocean_only ice_ocean_SIS2

# Models
MODELS=ocean_only ice_ocean_SIS2 coupled_AM2_LM3_SIS2
LIBS=AM2 atmos_null LM3 land_null icebergs ice_param fms
# GFDL-specific coupled models (requires access to GFDL intranet)
.PHONY: gfdl
gfdl: ocean_only ice_ocean_SIS2 coupled_AM2_LM3_SIS2

.PHONY: all
all: $(MODELS)

# ocean_only

.PHONY: ocean_only
ocean_only: ocean_only.symmetric ocean_only.asymmetric

.PHONY: ocean_only.symmetric
ocean_only.symmetric: fms
$(MAKE) -C ocean_only \
BUILD=../$(BUILD)/dynamic_symmetric/ocean_only \
FMS_BUILD=../$(BUILD)/fms

.PHONY: ocean_only.asymmetric
ocean_only.asymmetric: fms
$(MAKE) -C ocean_only \
BUILD=../$(BUILD)/dynamic_nonsymmetric/ocean_only \
FMS_BUILD=../$(BUILD)/fms \
MOM_MEMORY=../src/MOM6/config_src/memory/dynamic_nonsymmetric/MOM_memory.h


# ice_ocean_SIS2

.PHONY: ice_ocean_SIS2
ice_ocean_SIS2: ice_ocean_SIS2.symmetric ice_ocean_SIS2.asymmetric

.PHONY: ice_ocean_SIS2.symmetric
ice_ocean_SIS2.symmetric: fms atmos_null land_null ice_param icebergs
$(MAKE) -C ice_ocean_SIS2 \
BUILD=../$(BUILD)/dynamic_symmetric/ice_ocean_SIS2 \
FMS_BUILD=../$(BUILD)/fms \
ATMOS_BUILD=../$(BUILD)/atmos_null \
ICEBERGS_BUILD=../$(BUILD)/icebergs \
ICE_PARAM_BUILD=../$(BUILD)/ice_param \
LAND_BUILD=../$(BUILD)/land_null

.PHONY: ice_ocean_SIS2.asymmetric
ice_ocean_SIS2.asymmetric: fms atmos_null land_null ice_param icebergs
$(MAKE) -C ice_ocean_SIS2 \
BUILD=../$(BUILD)/dynamic_nonsymmetric/ice_ocean_SIS2 \
FMS_BUILD=../$(BUILD)/fms \
ATMOS_BUILD=../$(BUILD)/atmos_null \
ICEBERGS_BUILD=../$(BUILD)/icebergs \
ICE_PARAM_BUILD=../$(BUILD)/ice_param \
LAND_BUILD=../$(BUILD)/land_null \
MOM_MEMORY=../src/MOM6/config_src/memory/dynamic_nonsymmetric/MOM_memory.h \
SIS_MEMORY=../src/SIS2/config_src/dynamic/SIS2_memory.h


# Full coupled model

.PHONY: coupled_AM2_LM3_SIS2
coupled_AM2_LM3_SIS2: coupled_AM2_LM3_SIS2.symmetric coupled_AM2_LM3_SIS2.asymmetric

.PHONY: coupled_AM2_LM3_SIS2.symmetric
coupled_AM2_LM3_SIS2.symmetric: fms AM2 LM3 ice_param icebergs
$(MAKE) -C coupled_AM2_LM3_SIS2 \
BUILD=../$(BUILD)/dynamic_symmetric/coupled_AM2_LM3_SIS2 \
FMS_BUILD=../$(BUILD)/fms \
AM2_BUILD=../$(BUILD)/AM2 \
ICEBERGS_BUILD=../$(BUILD)/icebergs \
ICE_PARAM_BUILD=../$(BUILD)/ice_param \
LM3_BUILD=../$(BUILD)/LM3

.PHONY: coupled_AM2_LM3_SIS2.asymmetric
coupled_AM2_LM3_SIS2.asymmetric: fms AM2 LM3 ice_param icebergs
$(MAKE) -C coupled_AM2_LM3_SIS2 \
BUILD=../$(BUILD)/dynamic_nonsymmetric/coupled_AM2_LM3_SIS2 \
FMS_BUILD=../$(BUILD)/fms \
AM2_BUILD=../$(BUILD)/AM2 \
ICEBERGS_BUILD=../$(BUILD)/icebergs \
ICE_PARAM_BUILD=../$(BUILD)/ice_param \
LM3_BUILD=../$(BUILD)/LM3 \
MOM_MEMORY=../src/MOM6/config_src/memory/dynamic_nonsymmetric/MOM_memory.h \
SIS_MEMORY=../src/SIS2/config_src/dynamic/SIS2_memory.h

# TODO: Coupled asymmetric?

# Libraries

.PHONY: fms
fms:
$(MAKE) -C shared/fms \
BUILD=../../$(BUILD)/fms

.PHONY: atmos_null
atmos_null: fms
$(MAKE) -C shared/atmos_null \
BUILD=../../$(BUILD)/atmos_null \
FMS_BUILD=../../$(BUILD)/fms

.PHONY: AM2
AM2: fms
$(MAKE) -C shared/AM2 \
BUILD=../../$(BUILD)/AM2 \
FMS_BUILD=../../$(BUILD)/fms

.PHONY: land_null
land_null: fms
$(MAKE) -C shared/land_null \
BUILD=../../$(BUILD)/land_null \
FMS_BUILD=../../$(BUILD)/fms

.PHONY: LM3
LM3: fms
$(MAKE) -C shared/LM3 \
BUILD=../../$(BUILD)/LM3 \
FMS_BUILD=../../$(BUILD)/fms

.PHONY: ice_param
ice_param: fms
$(MAKE) -C shared/ice_param \
BUILD=../../$(BUILD)/ice_param \
FMS_BUILD=../../$(BUILD)/fms

.PHONY: icebergs
icebergs: fms
$(MAKE) -C shared/icebergs \
BUILD=../../$(BUILD)/icebergs \
FMS_BUILD=../../$(BUILD)/fms
# Dependencies
$(MODELS): fms
ice_ocean_SIS2 coupled_AM2_LM3_SIS2: ice_param icebergs
ice_ocean_SIS2: atmos_null land_null
coupled_AM2_LM3_SIS2: AM2 LM3
$(DEPS): fms

.PHONY: $(MODELS)
$(MODELS):
$(MAKE) -C $@


.PHONY: $(DEPS) fms
$(DEPS) fms:
$(MAKE) -C shared/$@


# Cleanup
.PHONY: clean
clean: $(foreach m,$(MODELS),$(m).clean) $(foreach d,$(DEPS),$(d).clean) fms.clean

.PHONY: $(foreach m,$(MODELS) $(DEPS) fms,$(m).clean)

$(foreach model,$(MODELS),$(model).clean):
$(MAKE) -C $(subst .clean,,$@) clean

$(foreach dep,$(DEPS) fms,$(dep).clean):
$(MAKE) -C shared/$(subst .clean,,$@) clean


# Runs
Expand Down Expand Up @@ -159,36 +92,3 @@ $(foreach e,$(call EXPT_DIRS,ocean_only),\

run.ocean_only: $(foreach e,$(call EXPT_DIRS,ocean_only),\
$(RUNDIR)/ocean_only/symmetric/$(e)/ocean.stats)


# Cleanup

clean: $(foreach model,$(MODELS),$(model).clean)
rm -rf build

define MODEL_CLEAN_RULE
.PHONY: $(1).clean
$(1).clean: $(1).symmetric.clean $(1).asymmetric.clean

.PHONY: $(1).symmetric.clean
$(1).symmetric.clean:
$(MAKE) -C $(1) \
BUILD=../$(BUILD)/dynamic_symmetric/$(1) \
clean

.PHONY: $(1).asymmetric.clean
$(1).asymmetric.clean:
$(MAKE) -C $(1) \
BUILD=../$(BUILD)/dynamic_nonsymmetric/$(1) \
clean
endef
$(foreach model,$(MODELS),$(eval $(call MODEL_CLEAN_RULE,$(model))))

define CLEAN_RULE
.PHONY: $(1).clean
$(1).clean:
$(MAKE) -C shared/$(1) \
BUILD=../../$(BUILD)/$(1) \
clean
endef
$(foreach lib,$(LIBS),$(eval $(call CLEAN_RULE,$(lib))))
48 changes: 24 additions & 24 deletions ac/configure.mom6sis2.ac → ac/configure.coupled.ac
Original file line number Diff line number Diff line change
Expand Up @@ -214,30 +214,18 @@ AX_FC_CHECK_MODULE([fms_mod], [], [
[-I${srcdir}/ac/deps/include])
])

# TODO: We cannot currently use this test, since it prepends -lFMS to LIBS.
# However, we need to append -lFMS, not prepend, since we are putting
# libraries in LIBS which depend on FMS, and some linkers can fail if in the
# wrong order (per POSIX convention).
#
# This could be resolved in a few different ways:
# * AX_FC_CHECK_LIB macros for each library
# * AX_FC_SEARCH_LIBS for FMS
# but there are issues with each of these options.
#
# For now, we remove the test and rely on LIBS, but should revisit this.
#
## Test for fms_init to verify FMS library linking
#AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod],
# [], [
# AS_UNSET([ax_fc_cv_lib_FMS_fms_init])
# AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod], [
# AC_SUBST([LDFLAGS], ["-L${srcdir}/ac/deps/lib $LDFLAGS"])
# AC_SUBST([LIBS], ["-lFMS $LIBS"])
# ],
# [AC_MSG_ERROR([Could not find FMS library.])],
# [-L${srcdir}/ac/deps/lib])
# ]
#)
# Test for fms_init to verify FMS library linking
AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod],
[], [
AS_UNSET([ax_fc_cv_lib_FMS_fms_init])
AX_FC_CHECK_LIB([FMS], [fms_init], [fms_mod], [
AC_SUBST([LDFLAGS], ["-L${srcdir}/ac/deps/lib $LDFLAGS"])
AC_SUBST([LIBS], ["-lFMS $LIBS"])
],
[AC_MSG_ERROR([Could not find FMS library.])],
[-L${srcdir}/ac/deps/lib])
]
)


# Verify that FMS is at least 2019.01.02
Expand Down Expand Up @@ -323,6 +311,18 @@ AC_CHECK_SIZEOF([sigjmp_buf], [], [#include <setjmp.h>])
AC_LANG_POP([C])


# Coupler macros
AC_DEFINE([use_AM3_physics])
AC_DEFINE([_USE_LEGACY_LAND_])


# TODO: We cannot currently provide tests for these libraries, and explicitly
# setting LIBS in the Makefile will append, rather than prepend, the flags,
# which would break the ordering.
# For now, we explicitly prepend these libraries, but this needs to be fixed.
LIBS="-licebergs -lice_param -lAM2 -lLM3 ${LIBS}"


# Prepare output
AC_SUBST([CPPFLAGS])
AC_CONFIG_FILES([Makefile:Makefile.in])
Expand Down
Loading

0 comments on commit 5395ce6

Please sign in to comment.