CIME.BuildTools package

Submodules

CIME.BuildTools.cmakemacroswriter module

Classes used to write build system files.

The classes here are used to write out settings for use by Makefile and CMake build systems. The two relevant classes are CMakeMacroWriter and MakeMacroWriter, which encapsulate the information necessary to write CMake and Makefile formatted text, respectively. See the docstrings for those classes for more.

class CIME.BuildTools.cmakemacroswriter.CMakeMacroWriter(output)[source]

Bases: CIME.BuildTools.macrowriterbase.MacroWriterBase

Macro writer for the CMake format.

For details on the provided methods, see MacroWriterBase, which this class inherits from.

end_ifeq()[source]

Write out a statement to end a block started with start_ifeq.

>>> import io
>>> s = io.StringIO()
>>> writer = CMakeMacroWriter(s)
>>> writer.start_ifeq("foo", "bar")
>>> writer.set_variable("foo2", "bar2")
>>> writer.end_ifeq()
>>> str(s.getvalue())
'if("foo" STREQUAL "bar")\n  set(foo2 "bar2")\nendif()\n'
environment_variable_string(name)[source]

Return an environment variable reference.

>>> import io
>>> s = io.StringIO()
>>> CMakeMacroWriter(s).environment_variable_string("foo")
'$ENV{foo}'
set_variable(name, value)[source]

Write out a statement setting a variable to some value.

>>> import io
>>> s = io.StringIO()
>>> CMakeMacroWriter(s).set_variable("foo", "bar")
>>> str(s.getvalue())
'set(foo "bar")\n'
shell_command_strings(command)[source]

Return strings used to get the output of a shell command.

>>> import io
>>> s = io.StringIO()
>>> set_up, inline, tear_down = CMakeMacroWriter(s).shell_command_strings("echo bar")
>>> set_up
'execute_process(COMMAND echo bar OUTPUT_VARIABLE CIME_TEMP_SHELL0 OUTPUT_STRIP_TRAILING_WHITESPACE)'
>>> inline
'${CIME_TEMP_SHELL0}'
>>> tear_down
'unset(CIME_TEMP_SHELL0)'
start_ifeq(left, right)[source]

Write out a statement to start a conditional block.

>>> import io
>>> s = io.StringIO()
>>> CMakeMacroWriter(s).start_ifeq("foo", "bar")
>>> str(s.getvalue())
'if("foo" STREQUAL "bar")\n'
variable_string(name)[source]

Return a string to refer to a variable with the given name.

>>> import io
>>> s = io.StringIO()
>>> CMakeMacroWriter(s).variable_string("foo")
'${foo}'

CIME.BuildTools.configure module

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.

class CIME.BuildTools.configure.FakeCase(compiler, mpilib, debug, comp_interface, threading=False)[source]

Bases: object

get_build_threaded()[source]
get_value(attrib)[source]
CIME.BuildTools.configure.configure(machobj, output_dir, macros_format, compiler, mpilib, debug, comp_interface, sysos, unit_testing=False, noenv=False, threaded=False, extra_machines_dir=None)[source]

Add Macros, Depends, and env_mach_specific files to a directory.

Arguments: machobj - Machines argument for this machine. output_dir - Directory in which to place output. macros_format - Container containing the string ‘Makefile’ to produce

Makefile Macros output, and/or ‘CMake’ for CMake output.

compiler - String containing the compiler vendor to configure for. mpilib - String containing the MPI implementation to configure for. debug - Boolean specifying whether debugging options are enabled. unit_testing - Boolean specifying whether we’re running unit tests (as

opposed to a system run)

extra_machines_dir - String giving path to an additional directory that will be

searched for a config_compilers.xml file.

CIME.BuildTools.configure.copy_depends_files(machine_name, machines_dir, output_dir, compiler)[source]

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

CIME.BuildTools.configure.generate_env_mach_specific(output_dir, machobj, compiler, mpilib, debug, comp_interface, sysos, unit_testing, threaded, noenv=False)[source]

env_mach_specific generation.

CIME.BuildTools.macroconditiontree module

class CIME.BuildTools.macroconditiontree.MacroConditionTree(name, settings)[source]

Bases: object

Tree containing the various possible settings of a specific macro.

Unlike the PossibleValues class, this class assumes that we have finished determining which settings could apply on a given machine. It also sorts the settings based on the conditions under which they take effect, in preparation for writing out the Macros file itself.

Public methods: merge write_out

merge(other)[source]

Merge another tree with this one.

This should be considered destructive to both trees. The only valid value is the one that’s returned.

write_out(writer)[source]

Write tree to file.

The writer argument is an object inheriting from MacroWriterBase. This function first writes out all the initial settings with appropriate conditionals, then the appending settings.

CIME.BuildTools.macroconditiontree.merge_optional_trees(tree, big_tree)[source]

Merge two MacroConditionTrees when one or both objects may be None.

CIME.BuildTools.macrowriterbase module

Classes used to write build system files.

The classes here are used to write out settings for use by Makefile and CMake build systems. The two relevant classes are CMakeMacroWriter and MakeMacroWriter, which encapsulate the information necessary to write CMake and Makefile formatted text, respectively. See the docstrings for those classes for more.

class CIME.BuildTools.macrowriterbase.MacroWriterBase(output)[source]

Bases: object

Abstract base class for macro file writers.

The methods here come in three flavors: 1. indent_left/indent_right change the level of indent used internally by

the class.

  1. The various methods ending in “_string” return strings relevant to the build system.

  2. The other methods write information to the file handle associated with an individual writer instance.

Public attributes: indent_increment - Number of spaces to indent if blocks (does not apply

to format-specific indentation, e.g. cases where Makefiles must use tabs).

output - File-like object that output is written to.

Public methods: indent_string indent_left indent_right write_line environment_variable_string shell_command_string variable_string set_variable append_variable start_ifeq end_ifeq

append_variable(name, value)[source]

Write out a statement appending a value to a string variable.

abstract end_ifeq()[source]

Write out a statement to end a block started with start_ifeq.

abstract environment_variable_string(name)[source]

Return an environment variable reference.

indent_increment = 2
indent_left()[source]

Decrease the amount of line indent.

indent_right()[source]

Increase the amount of line indent.

indent_string()[source]

Return an appropriate number of spaces for the indent.

abstract set_variable(name, value)[source]

Write out a statement setting a variable to some value.

abstract shell_command_strings(command)[source]

Return strings used to get the output of a shell command.

Implementations should return a tuple of three strings: 1. A line that is needed to get the output of the command (or None,

if a command can be run inline).

  1. A string that can be used within a line to refer to the output.

  2. A line that does any cleanup of temporary variables (or None, if no cleanup is necessary).

Example usage:

# Get strings and write initial command. (pre, var, post) = writer.shell_command_strings(command) if pre is not None:

writer.write(pre)

# Use the variable to write an if block. writer.start_ifeq(var, “TRUE”) writer.set_variable(“foo”, “bar”) writer.end_ifeq()

# Cleanup if post is not None:

writer.write(post)

abstract start_ifeq(left, right)[source]

Write out a statement to start a conditional block.

The arguments to this method are compared, and the block is entered only if they are equal.

abstract variable_string(name)[source]

Return a string to refer to a variable with the given name.

write_line(line)[source]

Write a single line of output, appropriately indented.

A trailing newline is added, whether or not the input has one.

CIME.BuildTools.makemacroswriter module

Classes used to write build system files.

The classes here are used to write out settings for use by Makefile and CMake build systems. The two relevant classes are CMakeMacroWriter and MakeMacroWriter, which encapsulate the information necessary to write CMake and Makefile formatted text, respectively. See the docstrings for those classes for more.

class CIME.BuildTools.makemacroswriter.MakeMacroWriter(output)[source]

Bases: CIME.BuildTools.macrowriterbase.MacroWriterBase

Macro writer for the Makefile format.

For details on the provided methods, see MacroWriterBase, which this class inherits from.

end_ifeq()[source]

Write out a statement to end a block started with start_ifeq.

>>> import io
>>> s = io.StringIO()
>>> writer = MakeMacroWriter(s)
>>> writer.start_ifeq("foo", "bar")
>>> writer.set_variable("foo2", "bar2")
>>> writer.end_ifeq()
>>> str(s.getvalue())
'ifeq (foo,bar)\n  foo2 := bar2\nendif\n'
environment_variable_string(name)[source]

Return an environment variable reference.

>>> import io
>>> s = io.StringIO()
>>> MakeMacroWriter(s).environment_variable_string("foo")
'$(foo)'
set_variable(name, value)[source]

Write out a statement setting a variable to some value.

>>> import io
>>> s = io.StringIO()
>>> MakeMacroWriter(s).set_variable("foo", "bar")
>>> str(s.getvalue())
'foo := bar\n'
shell_command_strings(command)[source]

Return strings used to get the output of a shell command.

>>> import io
>>> s = io.StringIO()
>>> MakeMacroWriter(s).shell_command_strings("echo bar")
(None, '$(shell echo bar)', None)
start_ifeq(left, right)[source]

Write out a statement to start a conditional block.

>>> import io
>>> s = io.StringIO()
>>> MakeMacroWriter(s).start_ifeq("foo", "bar")
>>> str(s.getvalue())
'ifeq (foo,bar)\n'
variable_string(name)[source]

Return a string to refer to a variable with the given name.

>>> import io
>>> s = io.StringIO()
>>> MakeMacroWriter(s).variable_string("foo")
'$(foo)'

CIME.BuildTools.possiblevalues module

class CIME.BuildTools.possiblevalues.PossibleValues(name, setting, specificity, depends)[source]

Bases: object

Holds a list of settings for a single “Macros” variable.

This helper class takes in variable settings and, for each one, decides whether to throw it out, add it to the list of values, or replace the existing list of values with the new, more specific setting.

This class also performs ambiguity checking; if it is possible at build time for more than one setting to match the same variable, this is considered an error.

Public attributes: name - The name of the variable. settings - The current list of possible initial settings for the

variable.

append_settings - A dictionary of lists of possible appending settings

for the variable, with the specificity of each list as the associated dictionary key.

Public methods: add_setting ambiguity_check dependencies to_cond_trees

add_setting(setting, specificity, depends)[source]

Add a possible value for a variable.

Arguments: setting - A ValueSetting to start the list. specificity - An integer representing how specific the setting is.

Low-specificity settings that will never be used will be dropped from the list. The lowest allowed specificity is 0.

depends - A set of variable names, specifying the variables that

have to be set before this setting can be used (e.g. if SLIBS refers to NETCDF_PATH, then NETCDF_PATH has to be set first).

>>> from CIME.BuildTools.valuesetting import ValueSetting
>>> a = ValueSetting('foo', False, dict(), [], [])
>>> b = ValueSetting('bar', False, dict(), [], [])
>>> vals = PossibleValues('var', a, 0, {'dep1'})
>>> vals.add_setting(b, 1, {'dep2'})
>>> a not in vals.settings and b in vals.settings
True
>>> 'dep1' not in vals.dependencies() and 'dep2' in vals.dependencies()
True
>>> vals.add_setting(a, 1, {'dep1'})
>>> a in vals.settings and b in vals.settings
True
>>> 'dep1' in vals.dependencies() and 'dep2' in vals.dependencies()
True
ambiguity_check()[source]

Check the current list of settings for ambiguity.

This function raises an error if an ambiguity is found.

dependencies()[source]

Returns a set of names of variables needed to set this variable.

to_cond_trees()[source]

Convert this object to a pair of MacroConditionTree objects.

This represents the step where the list of possible values is frozen and we’re ready to convert it into an actual text file. This object is checked for ambiguities before conversion.

The return value is a tuple of two items. The first is a dict of condition trees containing all initial settings, with the specificities as the dictionary keys. The second is a single tree containing all appending settings. If the appending tree would be empty, None is returned instead.

CIME.BuildTools.valuesetting module

class CIME.BuildTools.valuesetting.ValueSetting(value, do_append, conditions, set_up, tear_down)[source]

Bases: object

Holds data about how a value can be assigned to a variable.

Note that this class doesn’t know or care which variable might be assigned in this way, only that there is a procedure to perform that operation

Public attributes: value - The actual value that will be set. do_append - Boolean describing whether the value should be

appended to the existing value of the variable rather than overwriting other settings.

conditions - Dictionary containing the set of values that different

variables have to have to use this setting (e.g. DEBUG=”TRUE” might be a condition on a debug flag).

set_up - List of any commands that have to be executed in the build

system before this setting can occur.

tear_down - List of any commands that should be executed to clean up

after setting the variable.

Public methods: is_ambiguous_with has_special_case

has_special_case(other)[source]

Check to see if another setting is a special case of this one.

The purpose of this routine is to see if one of the settings requires conditions that are a strict subset of another’s conditions. This is used to check whether a setting can be thrown out entirely in favor of a more general, but machine-specific setting.

>>> a = ValueSetting('foo', False, {"DEBUG": "TRUE"}, [], [])
>>> b = ValueSetting('bar', False, {"DEBUG": "TRUE", "MPILIB": "mpich2"}, [], [])
>>> c = ValueSetting('bar', False, {"DEBUG": "TRUE", "compile_threaded": "FALSE"}, [], [])
>>> d = ValueSetting('foo', False, {"DEBUG": "FALSE"}, [], [])
>>> a.has_special_case(b)
True
>>> b.has_special_case(a)
False
>>> a.has_special_case(c)
True
>>> c.has_special_case(a)
False
>>> b.has_special_case(c)
False
>>> c.has_special_case(b)
False
>>> a.has_special_case(a)
True
>>> d.has_special_case(a)
False
>>> d.has_special_case(b)
False
is_ambiguous_with(other)[source]

Check to see if this setting conflicts with another one.

The purpose of this routine is to see if two settings can coexist in the same Macros file, or if doing so would raise an ambiguity about which one should be preferred over the other. Note that this is a symmetric relation (this function returns the same value if self and other are swapped).

The rules to determine this are as follows:

  1. If one or both settings are appending to the value, there’s no ambiguity, because both can cooperate to set the value.

>>> a = ValueSetting('foo', True, dict(), [], [])
>>> b = ValueSetting('bar', False, dict(), [], [])
>>> a.is_ambiguous_with(b)
False
>>> b.is_ambiguous_with(a)
False
  1. If the two settings have conflicting conditions, then there is no ambiguity because they can’t both apply to the same build.

>>> a = ValueSetting('foo', False, {"DEBUG": "TRUE"}, [], [])
>>> b = ValueSetting('bar', False, {"DEBUG": "FALSE"}, [], [])
>>> a.is_ambiguous_with(b)
False
  1. If one setting is strictly more specific than the other, then there’s no ambiguity, because we prefer the more specific setting whenever both apply to a build.

>>> a = ValueSetting('foo', False, {"DEBUG": "TRUE"}, [], [])
>>> b = ValueSetting('bar', False, {"DEBUG": "TRUE", "MPILIB": "mpich2"}, [], [])
>>> a.is_ambiguous_with(b)
False
>>> b.is_ambiguous_with(a)
False
  1. All other cases are considered ambiguous.

>>> a = ValueSetting('foo', False, dict(), [], [])
>>> b = ValueSetting('bar', False, dict(), [], [])
>>> a.is_ambiguous_with(b)
True
>>> a = ValueSetting('foo', False, {"DEBUG": "TRUE"}, [], [])
>>> b = ValueSetting('bar', False, {"MPILIB": "mpich2"}, [], [])
>>> a.is_ambiguous_with(b)
True

Module contents