198 lines
7.8 KiB
Python
198 lines
7.8 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""
|
|
build ctsm library
|
|
"""
|
|
import sys, os
|
|
|
|
_CIMEROOT = os.environ.get("CIMEROOT")
|
|
if _CIMEROOT is None:
|
|
raise SystemExit("ERROR: must set CIMEROOT environment variable")
|
|
|
|
_LIBDIR = os.path.join(_CIMEROOT, "CIME", "Tools")
|
|
sys.path.append(_LIBDIR)
|
|
|
|
from standard_script_setup import *
|
|
from CIME.buildlib import parse_input
|
|
from CIME.build import get_standard_makefile_args
|
|
from CIME.case import Case
|
|
from CIME.utils import run_cmd, expect
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
###############################################################################
|
|
def _write_ctsm_mk(gmake, gmake_opts, makefile, exeroot, libroot):
|
|
"""Writes a ctsm.mk file in exeroot.
|
|
|
|
This file can be included by atmosphere model builds outside of cime.
|
|
"""
|
|
|
|
cime_output_file = os.path.join(exeroot, "cime_variables.mk")
|
|
# Set COMP_NAME=driver because some link flags are set differently when COMP_NAME=driver, and
|
|
# those are the ones we want here.
|
|
cmd = (
|
|
"{gmake} write_include_and_link_flags OUTPUT_FILE={cime_output_file} "
|
|
"COMP_NAME=driver {gmake_opts} -f {makefile} "
|
|
).format(
|
|
gmake=gmake,
|
|
cime_output_file=cime_output_file,
|
|
gmake_opts=gmake_opts,
|
|
makefile=makefile,
|
|
)
|
|
rc, out, err = run_cmd(cmd)
|
|
logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n" % (cmd, out, err))
|
|
expect(rc == 0, "Command %s failed with rc=%s" % (cmd, rc))
|
|
|
|
ctsm_mk_path = os.path.join(exeroot, "ctsm.mk")
|
|
with open(ctsm_mk_path, "w") as ctsm_mk:
|
|
ctsm_mk.write(
|
|
"""
|
|
# ======================================================================
|
|
# Include this file to get makefile variables needed to include / link
|
|
# LILAC/CTSM in an atmosphere model's build
|
|
#
|
|
# Variables of interest are:
|
|
# - CTSM_INCLUDES: add this to the compilation line
|
|
# - CTSM_LIBS: add this to the link line
|
|
# ======================================================================
|
|
|
|
# ======================================================================
|
|
# The following CIME variables are meant for internal use, and generally
|
|
# should not be included directly in an atmosphere model's build.
|
|
# ======================================================================
|
|
|
|
"""
|
|
)
|
|
with open(cime_output_file) as infile:
|
|
ctsm_mk.write(infile.read())
|
|
|
|
ctsm_bld_dir = os.path.abspath(os.path.join(libroot, os.pardir))
|
|
with open(ctsm_mk_path, "a") as ctsm_mk:
|
|
ctsm_mk.write(
|
|
"""
|
|
# ======================================================================
|
|
# The following settings are meant for internal use, and generally
|
|
# should not be included directly in an atmosphere model's build.
|
|
# NOTE: clm library name and subdirectory will eventually need to
|
|
# be updated to ctsm.
|
|
# ======================================================================
|
|
|
|
CTSM_BLD_DIR = {ctsm_bld_dir}
|
|
CTSM_INC = $(CTSM_BLD_DIR)/clm/obj
|
|
|
|
# ======================================================================
|
|
# The following settings should be included in an atmosphere model's build.
|
|
# ======================================================================
|
|
|
|
CTSM_INCLUDES = $(CIME_ESMF_F90COMPILEPATHS) -I$(CIME_CSM_SHR_INCLUDE) -I$(CTSM_INC)
|
|
CTSM_LIBS = -L$(CTSM_BLD_DIR)/lib -lclm $(CIME_ULIBS) $(CIME_SLIBS) $(CIME_MLIBS) $(CIME_F90_LDFLAGS)
|
|
""".format(
|
|
ctsm_bld_dir=ctsm_bld_dir
|
|
)
|
|
)
|
|
|
|
|
|
###############################################################################
|
|
def _main_func():
|
|
###############################################################################
|
|
|
|
caseroot, libroot, bldroot = parse_input(sys.argv)
|
|
|
|
with Case(caseroot) as case:
|
|
|
|
casetools = case.get_value("CASETOOLS")
|
|
makefile = os.path.join(casetools, "Makefile")
|
|
lnd_root = case.get_value("COMP_ROOT_DIR_LND")
|
|
gmake_j = case.get_value("GMAKE_J")
|
|
gmake = case.get_value("GMAKE")
|
|
gmake_opts = get_standard_makefile_args(case)
|
|
driver = case.get_value("COMP_INTERFACE").lower()
|
|
lilac_mode = case.get_value("LILAC_MODE")
|
|
|
|
if lilac_mode == "on":
|
|
driver = "lilac"
|
|
|
|
# -------------------------------------------------------
|
|
# create Filepath file
|
|
# -------------------------------------------------------
|
|
compname = case.get_value("COMP_LND")
|
|
filepath_file = os.path.join(bldroot, "Filepath")
|
|
if not os.path.isfile(filepath_file):
|
|
caseroot = case.get_value("CASEROOT")
|
|
expect(
|
|
((compname == "clm") or (compname == "ctsm")),
|
|
"Unexpected COMP_LND name: %s" % (compname),
|
|
)
|
|
|
|
paths = [
|
|
os.path.join(caseroot, "SourceMods", "src." + compname),
|
|
os.path.join(lnd_root, "src", "cpl", driver),
|
|
os.path.join(lnd_root, "src", "main"),
|
|
os.path.join(lnd_root, "src", "biogeophys"),
|
|
os.path.join(lnd_root, "src", "biogeochem"),
|
|
os.path.join(lnd_root, "src", "soilbiogeochem"),
|
|
os.path.join(lnd_root, "src", "dyn_subgrid"),
|
|
os.path.join(lnd_root, "src", "init_interp"),
|
|
os.path.join(lnd_root, "src", "self_tests"),
|
|
os.path.join(lnd_root, "src", "fates"),
|
|
os.path.join(lnd_root, "src", "fates", "main"),
|
|
os.path.join(lnd_root, "src", "fates", "biogeophys"),
|
|
os.path.join(lnd_root, "src", "fates", "biogeochem"),
|
|
os.path.join(lnd_root, "src", "fates", "fire"),
|
|
os.path.join(lnd_root, "src", "fates", "parteh"),
|
|
os.path.join(lnd_root, "src", "fates", "radiation"),
|
|
os.path.join(lnd_root, "src", "utils"),
|
|
os.path.join(lnd_root, "src", "cpl"),
|
|
os.path.join(lnd_root, "src", "cpl", "utils"),
|
|
]
|
|
|
|
if lilac_mode == "on":
|
|
paths.append(os.path.join(lnd_root, "lilac", "src"))
|
|
# If we want to build with a real river model (e.g., MOSART), we'll need
|
|
# to use its directories in place of stub_rof
|
|
paths.append(os.path.join(lnd_root, "lilac", "stub_rof"))
|
|
|
|
if driver == "lilac" or driver == "nuopc":
|
|
paths.append(os.path.join(lnd_root, "src", "cpl", "share_esmf"))
|
|
|
|
with open(filepath_file, "w") as filepath:
|
|
filepath.write("\n".join(paths))
|
|
filepath.write("\n")
|
|
|
|
# -------------------------------------------------------
|
|
# create the library in libroot
|
|
# -------------------------------------------------------
|
|
|
|
complib = os.path.join(libroot, "lib%s.a" % (compname))
|
|
|
|
cmd = "{} complib -j {} COMP_NAME={} COMPLIB={} -f {} {}".format(
|
|
gmake, gmake_j, compname, complib, makefile, gmake_opts
|
|
)
|
|
|
|
rc, out, err = run_cmd(cmd)
|
|
logger.info("%s: \n\n output:\n %s \n\n err:\n\n%s\n" % (cmd, out, err))
|
|
expect(rc == 0, "Command %s failed with rc=%s" % (cmd, rc))
|
|
|
|
# ------------------------------------------------------------------------
|
|
# for lilac usage, we need a file containing some Makefile variables (for the atmosphere model's build)
|
|
# ------------------------------------------------------------------------
|
|
|
|
if lilac_mode == "on":
|
|
_write_ctsm_mk(
|
|
gmake=gmake,
|
|
gmake_opts=gmake_opts,
|
|
makefile=makefile,
|
|
exeroot=case.get_value("EXEROOT"),
|
|
libroot=libroot,
|
|
)
|
|
|
|
|
|
###############################################################################
|
|
|
|
if __name__ == "__main__":
|
|
logger.warning(
|
|
"WARNING: buildlib is being called as a program rather than a subroutine as "
|
|
+ "it is expected to be in the CESM context"
|
|
)
|
|
_main_func()
|