mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
ldgen: allow multiple mapping fragments to map same library
This commit is contained in:
parent
87aa341e97
commit
8ee90ee2f1
@ -279,6 +279,7 @@ class Mapping(Fragment):
|
||||
def __init__(self):
|
||||
Fragment.__init__(self)
|
||||
self.entries = set()
|
||||
self.deprecated = False
|
||||
|
||||
def set_key_value(self, key, parse_results):
|
||||
if key == "archive":
|
||||
@ -382,6 +383,7 @@ class DeprecatedMapping():
|
||||
fragment = Mapping()
|
||||
fragment.archive = toks[0].archive
|
||||
fragment.name = re.sub(r"[^0-9a-zA-Z]+", "_", fragment.archive)
|
||||
fragment.deprecated = True
|
||||
|
||||
fragment.entries = set()
|
||||
condition_true = False
|
||||
|
@ -334,8 +334,8 @@ class GenerationModel:
|
||||
|
||||
# Generate rules based on mapping fragments
|
||||
for mapping in self.mappings.values():
|
||||
mapping_rules = list()
|
||||
archive = mapping.archive
|
||||
mapping_rules = all_mapping_rules[archive]
|
||||
for (obj, symbol, scheme_name) in mapping.entries:
|
||||
try:
|
||||
if not (obj == Mapping.MAPPING_ALL_OBJECTS and symbol is None and
|
||||
@ -345,8 +345,6 @@ class GenerationModel:
|
||||
message = GenerationException.UNDEFINED_REFERENCE + " to scheme '" + scheme_name + "'."
|
||||
raise GenerationException(message, mapping)
|
||||
|
||||
all_mapping_rules[mapping.archive] = mapping_rules
|
||||
|
||||
# Detect rule conflicts
|
||||
for mapping_rules in all_mapping_rules.items():
|
||||
self._detect_conflicts(mapping_rules)
|
||||
@ -453,21 +451,24 @@ class GenerationModel:
|
||||
for fragment in fragment_file.fragments:
|
||||
dict_to_append_to = None
|
||||
|
||||
if isinstance(fragment, Scheme):
|
||||
dict_to_append_to = self.schemes
|
||||
elif isinstance(fragment, Sections):
|
||||
dict_to_append_to = self.sections
|
||||
if isinstance(fragment, Mapping) and fragment.deprecated and fragment.name in self.mappings.keys():
|
||||
self.mappings[fragment.name].entries |= fragment.entries
|
||||
else:
|
||||
dict_to_append_to = self.mappings
|
||||
if isinstance(fragment, Scheme):
|
||||
dict_to_append_to = self.schemes
|
||||
elif isinstance(fragment, Sections):
|
||||
dict_to_append_to = self.sections
|
||||
else:
|
||||
dict_to_append_to = self.mappings
|
||||
|
||||
# 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)
|
||||
# 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
|
||||
dict_to_append_to[fragment.name] = fragment
|
||||
|
||||
|
||||
class TemplateModel:
|
||||
|
@ -1246,6 +1246,109 @@ entries:
|
||||
|
||||
self.compare_rules(expected, actual)
|
||||
|
||||
def test_rule_generation_multiple_deprecated_mapping_definitions(self):
|
||||
multiple_deprecated_definitions = u"""
|
||||
[mapping]
|
||||
archive: lib.a
|
||||
entries:
|
||||
: PERFORMANCE_LEVEL = 0
|
||||
: PERFORMANCE_LEVEL = 1
|
||||
obj1 (noflash)
|
||||
: PERFORMANCE_LEVEL = 2
|
||||
obj1 (noflash)
|
||||
: PERFORMANCE_LEVEL = 3
|
||||
obj1 (noflash)
|
||||
|
||||
[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)
|
||||
"""
|
||||
|
||||
for perf_level in range(0, 4):
|
||||
self.sdkconfig.config.syms["PERFORMANCE_LEVEL"].set_value(str(perf_level))
|
||||
|
||||
self.model.mappings = {}
|
||||
self.add_fragments(multiple_deprecated_definitions)
|
||||
|
||||
actual = self.model.generate_rules(self.sections_info)
|
||||
expected = self.generate_default_rules()
|
||||
|
||||
if perf_level < 4:
|
||||
for append_no in range(1, perf_level + 1):
|
||||
flash_text_default = self.get_default("flash_text", expected)
|
||||
flash_rodata_default = self.get_default("flash_rodata", expected)
|
||||
|
||||
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)
|
||||
|
||||
def test_rule_generation_multiple_mapping_definitions(self):
|
||||
multiple_deprecated_definitions = u"""
|
||||
[mapping:base]
|
||||
archive: lib.a
|
||||
entries:
|
||||
if PERFORMANCE_LEVEL = 1:
|
||||
obj1 (noflash)
|
||||
elif PERFORMANCE_LEVEL = 2:
|
||||
obj1 (noflash)
|
||||
elif PERFORMANCE_LEVEL = 3:
|
||||
obj1 (noflash)
|
||||
else:
|
||||
* (default)
|
||||
|
||||
[mapping:extra]
|
||||
archive: lib.a
|
||||
entries:
|
||||
if PERFORMANCE_LEVEL = 1:
|
||||
obj1 (noflash) # ignore duplicate definition
|
||||
elif PERFORMANCE_LEVEL = 2:
|
||||
obj2 (noflash)
|
||||
elif PERFORMANCE_LEVEL = 3:
|
||||
obj2 (noflash)
|
||||
obj3 (noflash)
|
||||
else:
|
||||
* (default)
|
||||
"""
|
||||
|
||||
for perf_level in range(0, 4):
|
||||
self.sdkconfig.config.syms["PERFORMANCE_LEVEL"].set_value(str(perf_level))
|
||||
|
||||
self.model.mappings = {}
|
||||
self.add_fragments(multiple_deprecated_definitions)
|
||||
|
||||
actual = self.model.generate_rules(self.sections_info)
|
||||
expected = self.generate_default_rules()
|
||||
|
||||
if perf_level < 4:
|
||||
for append_no in range(1, perf_level + 1):
|
||||
flash_text_default = self.get_default("flash_text", expected)
|
||||
flash_rodata_default = self.get_default("flash_rodata", expected)
|
||||
|
||||
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__":
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user