mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/allow_multiple_fragment_definitions_for_library' into 'release/v3.3'
Combine definitions of multiple mapping fragments referring to the same library See merge request idf/esp-idf!4243
This commit is contained in:
commit
8c57aa0242
@ -333,34 +333,37 @@ class GenerationModel:
|
|||||||
all_mapping_rules = collections.defaultdict(list)
|
all_mapping_rules = collections.defaultdict(list)
|
||||||
|
|
||||||
# Generate rules based on mapping fragments
|
# Generate rules based on mapping fragments
|
||||||
for mapping in self.mappings.values():
|
for mapping_list in self.mappings.values():
|
||||||
for (condition, entries) in mapping.entries:
|
for mapping in mapping_list:
|
||||||
condition_true = False
|
for (condition, entries) in mapping.entries:
|
||||||
|
condition_true = False
|
||||||
|
|
||||||
# Only non-default condition are evaluated agains sdkconfig model
|
# Only non-default condition are evaluated agains sdkconfig model
|
||||||
if condition != Mapping.DEFAULT_CONDITION:
|
if condition != Mapping.DEFAULT_CONDITION:
|
||||||
try:
|
|
||||||
condition_true = sdkconfig.evaluate_expression(condition)
|
|
||||||
except Exception as e:
|
|
||||||
raise GenerationException(e.message, mapping)
|
|
||||||
else:
|
|
||||||
condition_true = True
|
|
||||||
|
|
||||||
if condition_true:
|
|
||||||
|
|
||||||
mapping_rules = list()
|
|
||||||
|
|
||||||
archive = mapping.archive
|
|
||||||
for (obj, symbol, scheme_name) in entries:
|
|
||||||
try:
|
try:
|
||||||
self._add_mapping_rules(archive, obj, symbol, scheme_name, scheme_dictionary, mapping_rules)
|
condition_true = sdkconfig.evaluate_expression(condition)
|
||||||
except KeyError:
|
except Exception as e:
|
||||||
message = GenerationException.UNDEFINED_REFERENCE + " to scheme '" + scheme_name + "'."
|
raise GenerationException(e.message, mapping)
|
||||||
raise GenerationException(message, mapping)
|
else:
|
||||||
|
condition_true = True
|
||||||
|
|
||||||
all_mapping_rules[mapping.name] = mapping_rules
|
if condition_true:
|
||||||
|
|
||||||
break # Exit on first condition that evaluates to true
|
mapping_rules = list()
|
||||||
|
|
||||||
|
archive = mapping.archive
|
||||||
|
for (obj, symbol, scheme_name) in entries:
|
||||||
|
try:
|
||||||
|
self._add_mapping_rules(archive, obj, symbol, scheme_name, scheme_dictionary, mapping_rules)
|
||||||
|
except KeyError:
|
||||||
|
message = GenerationException.UNDEFINED_REFERENCE + " to scheme '" + scheme_name + "'."
|
||||||
|
raise GenerationException(message, mapping)
|
||||||
|
|
||||||
|
for mapping_rule in mapping_rules:
|
||||||
|
if mapping_rule not in all_mapping_rules[mapping.name]:
|
||||||
|
all_mapping_rules[mapping.name].append(mapping_rule)
|
||||||
|
|
||||||
|
break # Exit on first condition that evaluates to true
|
||||||
|
|
||||||
# Detect rule conflicts
|
# Detect rule conflicts
|
||||||
for mapping_rules in all_mapping_rules.items():
|
for mapping_rules in all_mapping_rules.items():
|
||||||
@ -476,14 +479,23 @@ class GenerationModel:
|
|||||||
else:
|
else:
|
||||||
dict_to_append_to = self.mappings
|
dict_to_append_to = self.mappings
|
||||||
|
|
||||||
# Raise exception when the fragment of the same type is already in the stored fragments
|
if isinstance(fragment, Mapping):
|
||||||
if fragment.name in dict_to_append_to.keys():
|
try:
|
||||||
stored = dict_to_append_to[fragment.name].path
|
fragment_list = dict_to_append_to[fragment.name]
|
||||||
new = fragment.path
|
except KeyError:
|
||||||
message = "Duplicate definition of fragment '%s' found in %s and %s." % (fragment.name, stored, new)
|
fragment_list = list()
|
||||||
raise GenerationException(message)
|
dict_to_append_to[fragment.name] = fragment_list
|
||||||
|
|
||||||
dict_to_append_to[fragment.name] = fragment
|
fragment_list.append(fragment)
|
||||||
|
else:
|
||||||
|
# Raise exception when the fragment of the same type is already in the stored fragments
|
||||||
|
if fragment.name in dict_to_append_to.keys():
|
||||||
|
stored = dict_to_append_to[fragment.name].path
|
||||||
|
new = fragment.path
|
||||||
|
message = "Duplicate definition of fragment '%s' found in %s and %s." % (fragment.name, stored, new)
|
||||||
|
raise GenerationException(message)
|
||||||
|
|
||||||
|
dict_to_append_to[fragment.name] = fragment
|
||||||
|
|
||||||
|
|
||||||
class TemplateModel:
|
class TemplateModel:
|
||||||
|
@ -64,7 +64,12 @@ class GenerationModelTest(unittest.TestCase):
|
|||||||
def _add_mapping(self, text):
|
def _add_mapping(self, text):
|
||||||
parser = Mapping.get_fragment_grammar()
|
parser = Mapping.get_fragment_grammar()
|
||||||
fragment = parser.parseString(text, parseAll=True)
|
fragment = parser.parseString(text, parseAll=True)
|
||||||
self.model.mappings[fragment[0].name] = fragment[0]
|
try:
|
||||||
|
mappings = self.model.mappings[fragment[0].name]
|
||||||
|
except KeyError:
|
||||||
|
mappings = list()
|
||||||
|
self.model.mappings[fragment[0].name] = mappings
|
||||||
|
mappings.append(fragment[0])
|
||||||
|
|
||||||
def _add_sections(self, text):
|
def _add_sections(self, text):
|
||||||
parser = Sections.get_fragment_grammar()
|
parser = Sections.get_fragment_grammar()
|
||||||
@ -297,7 +302,6 @@ class GenerationModelTest(unittest.TestCase):
|
|||||||
self._add_mapping(normal)
|
self._add_mapping(normal)
|
||||||
|
|
||||||
actual = self.model.generate_rules(self.sdkconfig, self.sections_info)
|
actual = self.model.generate_rules(self.sdkconfig, self.sections_info)
|
||||||
|
|
||||||
expected = self._generate_default_rules()
|
expected = self._generate_default_rules()
|
||||||
|
|
||||||
flash_text_default = self._get_default("flash_text", expected)
|
flash_text_default = self._get_default("flash_text", expected)
|
||||||
@ -1120,6 +1124,58 @@ class GenerationModelTest(unittest.TestCase):
|
|||||||
|
|
||||||
self._compare_rules(expected, actual)
|
self._compare_rules(expected, actual)
|
||||||
|
|
||||||
|
def test_rule_generation_multiple_mapping_definitions(self):
|
||||||
|
generation_with_condition1 = """
|
||||||
|
[mapping]
|
||||||
|
archive: lib.a
|
||||||
|
entries:
|
||||||
|
: PERFORMANCE_LEVEL = 0
|
||||||
|
: PERFORMANCE_LEVEL = 1
|
||||||
|
obj1 (noflash)
|
||||||
|
: PERFORMANCE_LEVEL = 2
|
||||||
|
obj1 (noflash)
|
||||||
|
: PERFORMANCE_LEVEL = 3
|
||||||
|
obj1 (noflash)
|
||||||
|
"""
|
||||||
|
|
||||||
|
generation_with_condition2 = """
|
||||||
|
[mapping]
|
||||||
|
archive: lib.a
|
||||||
|
entries:
|
||||||
|
: PERFORMANCE_LEVEL = 1
|
||||||
|
obj1 (noflash) # ignore duplicate definition
|
||||||
|
: PERFORMANCE_LEVEL = 2
|
||||||
|
obj2 (noflash)
|
||||||
|
: PERFORMANCE_LEVEL = 3
|
||||||
|
obj2 (noflash)
|
||||||
|
obj3 (noflash)
|
||||||
|
"""
|
||||||
|
|
||||||
|
self._add_mapping(generation_with_condition1)
|
||||||
|
self._add_mapping(generation_with_condition2)
|
||||||
|
|
||||||
|
for perf_level in range(0, 4):
|
||||||
|
self.sdkconfig.config.syms["PERFORMANCE_LEVEL"].set_value(str(perf_level))
|
||||||
|
|
||||||
|
actual = self.model.generate_rules(self.sdkconfig, self.sections_info)
|
||||||
|
expected = self._generate_default_rules()
|
||||||
|
|
||||||
|
flash_text_default = self._get_default("flash_text", expected)
|
||||||
|
flash_rodata_default = self._get_default("flash_rodata", expected)
|
||||||
|
|
||||||
|
if perf_level < 4:
|
||||||
|
for append_no in range(1, perf_level + 1):
|
||||||
|
iram_rule = PlacementRule("lib.a", "obj" + str(append_no), None, self.model.sections["text"].entries, "iram0_text")
|
||||||
|
dram_rule = PlacementRule("lib.a", "obj" + str(append_no), None, self.model.sections["rodata"].entries, "dram0_data")
|
||||||
|
|
||||||
|
flash_text_default.add_exclusion(iram_rule)
|
||||||
|
flash_rodata_default.add_exclusion(dram_rule)
|
||||||
|
|
||||||
|
expected["iram0_text"].append(iram_rule)
|
||||||
|
expected["dram0_data"].append(dram_rule)
|
||||||
|
|
||||||
|
self._compare_rules(expected, actual)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user