def test_no_match_attr(self): """best_match returns None when there are no attribute matches.""" self.assertTrue(best_match(self.xml_tree, "bar/data1") is None) self.assertTrue(best_match(self.xml_tree, "bar/data1", {"a": "1"}) is None)
def test_match_most_specific(self): """best_match returns the most specific match for each path.""" self.assertEqual( "generic", best_match(self.xml_tree, "foo/data1", {"a": "1", "b": "2"}).text ) self.assertEqual( "ab", best_match(self.xml_tree, "foo/data3", {"a": "1", "b": "2"}).text )
def test_match_most_specific(self): """best_match returns the most specific match for each path.""" self.assertEqual( "generic", best_match(self.xml_tree, "foo/data1", { "a": "1", "b": "2" }).text) self.assertEqual( "ab", best_match(self.xml_tree, "foo/data3", { "a": "1", "b": "2" }).text)
def test_match_with_attr(self): """best_match returns the only path match, with matching attribute.""" self.assertEqual( "abar", best_match(self.xml_tree, "bar/data1", {"a": "2"}).text )
def test_simple_match(self): """best_match can find the only match, when no attributes are used.""" self.assertEqual( "generic", best_match(self.xml_tree, "foo/data1").text )
def test_match_first(self): """best_match returns the first matching entry.""" self.assertEqual( "abar", best_match(self.xml_tree, "bar/data1", {"a": "2", "b": "1"}).text )
def test_match_with_attr(self): """best_match returns the only path match, with matching attribute.""" self.assertEqual( "abar", best_match(self.xml_tree, "bar/data1", { "a": "2" }).text)
def test_match_on_attr(self): """best_match returns the only path and attribute match.""" self.assertEqual( "b", best_match(self.xml_tree, "foo/data2", {"a": "2", "b": "2"}).text )
def test_match_first(self): """best_match returns the first matching entry.""" self.assertEqual( "abar", best_match(self.xml_tree, "bar/data1", { "a": "2", "b": "1" }).text)
def test_match_on_attr(self): """best_match returns the only path and attribute match.""" self.assertEqual( "b", best_match(self.xml_tree, "foo/data2", { "a": "2", "b": "2" }).text)
def compiler_xml_to_env(self, xml_path, var_name): """Look up a config_compilers entry and set a variable from it. Arguments: xml_path - Path within the xml file (e.g. "compiler/SFC"). var_name - Name of environment variable (e.g. "FC"). """ match = best_match(self.compiler_xml_tree, xml_path, self.machine_dict) assert match is not None, "Could not determine "+var_name+ \ " from compiler/machines xml file." environ[var_name] = match.text.strip()
def add_path(self, name, macros_printer): match = best_match(self.compiler_xml_tree, "compiler/" + name + "_PATH", self.machine_dict) if match is not None: macros_printer.print_header(name + " location.") libpath = match.text _make_env_re = re.compile( """\$\( # Initial "$" and brace (?P<name>[A-Za-z0-9_]+) # Variable name \) # Close brace""", re.X) libpath = _make_env_re.sub("$ENV{\g<name>}", libpath) print("libpath = " + libpath) macros_printer.print("list(APPEND CMAKE_PREFIX_PATH " + libpath + ")")
def add_path(self, name, macros_printer): match = best_match(self.compiler_xml_tree, "compiler/"+name+"_PATH", self.machine_dict) if match is not None: macros_printer.print_header(name + " location.") libpath = match.text _make_env_re = re.compile( """\$\( # Initial "$" and brace (?P<name>[A-Za-z0-9_]+) # Variable name \) # Close brace""", re.X) libpath = _make_env_re.sub( "$ENV{\g<name>}",libpath) print("libpath = "+libpath) macros_printer.print( "list(APPEND CMAKE_PREFIX_PATH "+libpath+")" )
def test_no_match(self): """best_match returns None when no paths match.""" self.assertTrue(best_match(self.xml_tree, "invalid") is None)
def test_simple_match(self): """best_match can find the only match, when no attributes are used.""" self.assertEqual("generic", best_match(self.xml_tree, "foo/data1").text)
def test_no_match_attr(self): """best_match returns None when there are no attribute matches.""" self.assertTrue(best_match(self.xml_tree, "bar/data1") is None) self.assertTrue( best_match(self.xml_tree, "bar/data1", {"a": "1"}) is None)
def write_cmake_macros(self, macros_file): """Write CMake macros file using config_compilers.xml Arguments: macros_file - File object to write to. """ # Print header to file. macros_printer = ScriptPrinter(macros_file) header_lines = [ "CESM build flags for:", " Compiler = " + self.machine_dict["COMPILER"], " Machine = " + self.machine_dict["MACH"], " OS = " + self.machine_dict["OS"], ] for line in header_lines: macros_printer.comment(line) # pFUnit location if it exists. match = best_match(self.compiler_xml_tree, "compiler/PFUNIT_PATH", self.machine_dict) if match is not None: macros_printer.print_header("pFUnit location.") macros_printer.print("list(APPEND CMAKE_PREFIX_PATH " + match.text + ")") # Normal and debug dictionaries for looking things up in # config_compilers. normal_dict = self.machine_dict.copy() normal_dict["DEBUG"] = "FALSE" debug_dict = self.machine_dict.copy() debug_dict["DEBUG"] = "TRUE" def add_formatted_flags(flags_name, format): """Print CMake flags using macros_printer. Arguments: flags_name - Name to search for in config_compilers. format - Function that takes a build type and flag match, and returns the string to print out. """ paths = ["compiler/" + flags_name, "compiler/ADD_" + flags_name] # This creates an iterable over elements in config_compilers # that match in non-debug mode. normal_matches = chain.from_iterable( all_matches(self.compiler_xml_tree, path, normal_dict) for path in paths) for match in normal_matches: macros_printer.print(format("CESM", match.text)) # Now the same for debug mode. debug_matches = chain.from_iterable( all_matches(self.compiler_xml_tree, path, debug_dict) for path in paths) for match in debug_matches: macros_printer.print(format("CESM_DEBUG", match.text)) # Below, we just use a bunch of lambda functions to describe how # the build type and a matching element (e.g. an FFLAGS entry) are # turned into a CMake function call. macros_printer.print_header("CPP definitions.") add_formatted_flags( "CPPDEFS", lambda b, m: "add_config_definitions(" + b + " " + m + ")") def format_contiguous(build_type, match): comma = "," if self.machine_dict["COMPILER"] != "ibm" else "\\\," contig_def = "contiguous" + comma if match == "TRUE" else "" return "add_config_definitions("+build_type+\ " -DUSE_CONTIGUOUS="+contig_def+")" add_formatted_flags("HAS_F2008_CONTIGUOUS", format_contiguous) macros_printer.print_header("Fortran flags.") add_formatted_flags( "FFLAGS", lambda b, m: "add_flags(CMAKE_Fortran_FLAGS_" + b + " " + m + ")") macros_printer.print_header("C flags.") add_formatted_flags( "CFLAGS", lambda b, m: "add_flags(CMAKE_C_FLAGS_" + b + " " + m + ")") macros_printer.print_header("Linker flags.") add_formatted_flags( "LDFLAGS", lambda b, m: "add_flags(CMAKE_EXE_LINKER_FLAGS_" + b + " " + m + ")")