#!/usr/bin/env python3
"""This script writes CIME build information to a directory.
The pieces of information that will be written include:
1. Machine-specific build settings (i.e. the "Macros" file).
2. File-specific build settings (i.e. "Depends" files).
3. Environment variable loads (i.e. the env_mach_specific files).
The .env_mach_specific.sh and .env_mach_specific.csh files are specific to a
given compiler, MPI library, and DEBUG setting. By default, these will be the
machine's default compiler, the machine's default MPI library, and FALSE,
respectively. These can be changed by setting the environment variables
COMPILER, MPILIB, and DEBUG, respectively.
"""
from CIME.XML.standard_module_setup import *
from CIME.utils import (
expect,
safe_copy,
get_model,
get_src_root,
stringify_bool,
copy_local_macros_to_dir,
)
from CIME.XML.env_mach_specific import EnvMachSpecific
from CIME.XML.files import Files
from CIME.build import CmakeTmpBuildDir
import shutil, glob
logger = logging.getLogger(__name__)
[docs]
def copy_depends_files(machine_name, machines_dir, output_dir, compiler):
"""
Copy any system or compiler Depends files if they do not exist in the output directory
If there is a match for Depends.machine_name.compiler copy that and ignore the others
"""
# Note, the cmake build system does not stop if Depends.mach.compiler.cmake is found
makefiles_done = False
both = "{}.{}".format(machine_name, compiler)
for suffix in [both, machine_name, compiler]:
for extra_suffix in ["", ".cmake"]:
if extra_suffix == "" and makefiles_done:
continue
basename = "Depends.{}{}".format(suffix, extra_suffix)
dfile = os.path.join(machines_dir, basename)
outputdfile = os.path.join(output_dir, basename)
if os.path.isfile(dfile):
if suffix == both and extra_suffix == "":
makefiles_done = True
if not os.path.exists(outputdfile):
safe_copy(dfile, outputdfile)
[docs]
class FakeCase(object):
def __init__(self, compiler, mpilib, debug, comp_interface, threading=False):
# PIO_VERSION is needed to parse config_machines.xml but isn't otherwise used
# by FakeCase
self._vals = {
"COMPILER": compiler,
"MPILIB": mpilib,
"DEBUG": debug,
"COMP_INTERFACE": comp_interface,
"PIO_VERSION": 2,
"BUILD_THREADED": threading,
"MODEL": get_model(),
"SRCROOT": get_src_root(),
}
[docs]
def get_build_threaded(self):
return self.get_value("BUILD_THREADED")
[docs]
def get_case_root(self):
"""Returns the root directory for this case."""
return self.get_value("CASEROOT")
[docs]
def get_value(self, attrib):
expect(
attrib in self._vals,
"FakeCase does not support getting value of '%s'" % attrib,
)
return self._vals[attrib]
[docs]
def set_value(self, attrib, value):
"""Sets a given variable value for the case"""
self._vals[attrib] = value
[docs]
def generate_env_mach_specific(
output_dir,
machobj,
compiler,
mpilib,
debug,
comp_interface,
sysos,
unit_testing,
threaded,
noenv=False,
):
"""
env_mach_specific generation.
"""
ems_path = os.path.join(output_dir, "env_mach_specific.xml")
if os.path.exists(ems_path):
logger.warning("{} already exists, delete to replace".format(ems_path))
return
ems_file = EnvMachSpecific(
output_dir, unit_testing=unit_testing, standalone_configure=True
)
ems_file.populate(
machobj,
attributes={"mpilib": mpilib, "compiler": compiler, "threaded": threaded},
)
ems_file.write()
if noenv:
return
fake_case = FakeCase(compiler, mpilib, debug, comp_interface)
ems_file.load_env(fake_case)
for shell in ("sh", "csh"):
ems_file.make_env_mach_specific_file(shell, fake_case, output_dir=output_dir)
shell_path = os.path.join(output_dir, ".env_mach_specific." + shell)
with open(shell_path, "a") as shell_file:
if shell == "sh":
shell_file.write("\nexport COMPILER={}\n".format(compiler))
shell_file.write("export MPILIB={}\n".format(mpilib))
shell_file.write("export DEBUG={}\n".format(repr(debug).upper()))
shell_file.write("export OS={}\n".format(sysos))
else:
shell_file.write("\nsetenv COMPILER {}\n".format(compiler))
shell_file.write("setenv MPILIB {}\n".format(mpilib))
shell_file.write("setenv DEBUG {}\n".format(repr(debug).upper()))
shell_file.write("setenv OS {}\n".format(sysos))