Merge branch 'refactor/change_idf_size_type_to_pep-484' into 'master'

Refactor/change idf_size.py type to pep-484

See merge request espressif/esp-idf!15184
This commit is contained in:
Roland Dobai 2021-09-24 10:23:53 +00:00
commit 50dc76f388
3 changed files with 131 additions and 151 deletions

View File

@ -4148,7 +4148,6 @@ tools/idf_py_actions/global_options.py
tools/idf_py_actions/serial_ext.py tools/idf_py_actions/serial_ext.py
tools/idf_py_actions/tools.py tools/idf_py_actions/tools.py
tools/idf_py_actions/uf2_ext.py tools/idf_py_actions/uf2_ext.py
tools/idf_size.py
tools/kconfig/conf.c tools/kconfig/conf.c
tools/kconfig/confdata.c tools/kconfig/confdata.c
tools/kconfig/expand_env.c tools/kconfig/expand_env.c

View File

@ -6,19 +6,8 @@
# Includes information which is not shown in "xtensa-esp32-elf-size", # Includes information which is not shown in "xtensa-esp32-elf-size",
# or easy to parse from "xtensa-esp32-elf-objdump" or raw map files. # or easy to parse from "xtensa-esp32-elf-objdump" or raw map files.
# #
# Copyright 2017-2021 Espressif Systems (Shanghai) CO LTD # SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
# # SPDX-License-Identifier: Apache-2.0
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# #
from __future__ import division, print_function, unicode_literals from __future__ import division, print_function, unicode_literals
@ -28,15 +17,13 @@ import json
import os.path import os.path
import re import re
import sys import sys
from typing import Any, Callable, Collection, Dict, Iterable, List, Optional, TextIO, Tuple, Union
from future.utils import iteritems from future.utils import iteritems
try:
from typing import Any, Callable, Collection, Dict, Iterable, List, Optional, TextIO, Tuple, Union
Section = Dict[str, Union[str, int]] Section = Dict[str, Union[str, int]]
SectionDict = Dict[str, Section] SectionDict = Dict[str, Section]
except ImportError:
pass
try: try:
basestring basestring
@ -50,7 +37,6 @@ GLOBAL_JSON_SEPARATORS = (',', ': ')
class MemRegions(object): class MemRegions(object):
# Regions determined by the chip target. # Regions determined by the chip target.
# DIRAM is not added here. The DIRAM is indicated by the `secondary_addr` of each MemRegDef # DIRAM is not added here. The DIRAM is indicated by the `secondary_addr` of each MemRegDef
(DRAM_ID, IRAM_ID, CACHE_D_ID, CACHE_I_ID, RTC_FAST_D_ID, RTC_FAST_I_ID, RTC_SLOW_D_ID) = range(7) (DRAM_ID, IRAM_ID, CACHE_D_ID, CACHE_I_ID, RTC_FAST_D_ID, RTC_FAST_I_ID, RTC_SLOW_D_ID) = range(7)
@ -59,15 +45,14 @@ class MemRegions(object):
class Region(object): class Region(object):
# Helper class to store region information # Helper class to store region information
def __init__(self, start, length, region, section=None): def __init__(self, start: int, length: int, region: 'MemRegions.MemRegDef', section: Optional[str]=None) -> None:
# type: (MemRegions.Region, int, int, MemRegions.MemRegDef, Optional[str]) -> None
self.start = start self.start = start
self.len = length self.len = length
self.region = region self.region = region
self.section = section self.section = section
@staticmethod @staticmethod
def get_mem_regions(target): # type: (str) -> List def get_mem_regions(target: str) -> List:
# The target specific memory structure is deduced from soc_memory_types defined in # The target specific memory structure is deduced from soc_memory_types defined in
# $IDF_PATH/components/soc/**/soc_memory_layout.c files. # $IDF_PATH/components/soc/**/soc_memory_layout.c files.
@ -124,13 +109,12 @@ class MemRegions(object):
else: else:
raise RuntimeError('Target not detected.') raise RuntimeError('Target not detected.')
def __init__(self, target): # type: (MemRegions, str) -> None def __init__(self, target: str) -> None:
self.chip_mem_regions = self.get_mem_regions(target) self.chip_mem_regions = self.get_mem_regions(target)
if not self.chip_mem_regions: if not self.chip_mem_regions:
raise RuntimeError('Target {} is not implemented in idf_size'.format(target)) raise RuntimeError('Target {} is not implemented in idf_size'.format(target))
def _get_first_region(self, start, length): def _get_first_region(self, start: int, length: int) -> Tuple[Union['MemRegions.MemRegDef', None], int]:
# type: (int, int) -> Tuple[Union[MemRegions.MemRegDef, None], int]
for region in self.chip_mem_regions: # type: ignore for region in self.chip_mem_regions: # type: ignore
if region.primary_addr <= start < region.primary_addr + region.length: if region.primary_addr <= start < region.primary_addr + region.length:
return (region, length) return (region, length)
@ -140,7 +124,7 @@ class MemRegions(object):
print('Check whether the LD file is compatible with the definitions in get_mem_regions in idf_size.py') print('Check whether the LD file is compatible with the definitions in get_mem_regions in idf_size.py')
return (None, length) return (None, length)
def _get_regions(self, start, length, name=None): # type: (int, int, Optional[str]) -> List def _get_regions(self, start: int, length: int, name: Optional[str]=None) -> List:
ret = [] ret = []
while length > 0: while length > 0:
(region, cur_len) = self._get_first_region(start, length) (region, cur_len) = self._get_first_region(start, length)
@ -155,7 +139,7 @@ class MemRegions(object):
return ret return ret
def fit_segments_into_regions(self, segments): # type: (MemRegions, Dict) -> List def fit_segments_into_regions(self, segments: Dict) -> List:
region_list = [] region_list = []
for segment in segments.values(): for segment in segments.values():
@ -164,7 +148,7 @@ class MemRegions(object):
return region_list return region_list
def fit_sections_into_regions(self, sections): # type: (MemRegions, Dict) -> List def fit_sections_into_regions(self, sections: Dict) -> List:
region_list = [] region_list = []
for section in sections.values(): for section in sections.values():
@ -187,7 +171,7 @@ class LinkingSections(object):
}.items()} }.items()}
@staticmethod @staticmethod
def in_section(section, section_name_or_list): # type: (str, Union[str, Iterable]) -> bool def in_section(section: str, section_name_or_list: Union[str, Iterable]) -> bool:
if isinstance(section_name_or_list, basestring): if isinstance(section_name_or_list, basestring):
section_name_or_list = [section_name_or_list] section_name_or_list = [section_name_or_list]
@ -197,18 +181,18 @@ class LinkingSections(object):
return False return False
@staticmethod @staticmethod
def filter_sections(sections): # type: (Dict) -> Dict def filter_sections(sections: Dict) -> Dict:
return {k: v for k, v in sections.items() return {k: v for k, v in sections.items()
if LinkingSections.in_section(k, LinkingSections._section_type_dict.keys())} if LinkingSections.in_section(k, LinkingSections._section_type_dict.keys())}
@staticmethod @staticmethod
def get_display_name_order(section_name_list): # type: (List[str]) -> Tuple[List[str], List[str]] def get_display_name_order(section_name_list: List[str]) -> Tuple[List[str], List[str]]:
''' '''
Return two lists, in the suggested display order. Return two lists, in the suggested display order.
First list is the reordered section_name_list, second list is the suggested display name, corresponding to the first list First list is the reordered section_name_list, second list is the suggested display name, corresponding to the first list
''' '''
def get_name_score(name): # type: (str) -> int def get_name_score(name: str) -> int:
score_dict = { score_dict = {
'.dram': 30, '.dram': 30,
'.iram': 20, '.iram': 20,
@ -241,6 +225,7 @@ class LinkingSections(object):
continue continue
memory_name = '' memory_name = ''
split_name = section.split('.') split_name = section.split('.')
if len(split_name) > 1: if len(split_name) > 1:
# If the section has a memory type, update the type and try to display the type properly # If the section has a memory type, update the type and try to display the type properly
@ -261,7 +246,7 @@ class LinkingSections(object):
return ordered_name_list, display_name_list return ordered_name_list, display_name_list
def scan_to_header(f, header_line): # type: (Iterable, str) -> None def scan_to_header(f: Iterable, header_line: str) -> None:
""" Scan forward in a file until you reach 'header_line', then return """ """ Scan forward in a file until you reach 'header_line', then return """
for line in f: for line in f:
if line.strip() == header_line: if line.strip() == header_line:
@ -269,14 +254,14 @@ def scan_to_header(f, header_line): # type: (Iterable, str) -> None
raise RuntimeError("Didn't find line '%s' in file" % header_line) raise RuntimeError("Didn't find line '%s' in file" % header_line)
def format_json(json_object): # type: (Dict) -> str def format_json(json_object: Dict) -> str:
return json.dumps(json_object, return json.dumps(json_object,
allow_nan=True, allow_nan=True,
indent=GLOBAL_JSON_INDENT, indent=GLOBAL_JSON_INDENT,
separators=GLOBAL_JSON_SEPARATORS) + os.linesep separators=GLOBAL_JSON_SEPARATORS) + os.linesep
def load_map_data(map_file): # type: (TextIO) -> Tuple[str, Dict, Dict] def load_map_data(map_file: TextIO) -> Tuple[str, Dict, Dict]:
segments = load_segments(map_file) segments = load_segments(map_file)
detected_chip = detect_target_chip(map_file) detected_chip = detect_target_chip(map_file)
sections = load_sections(map_file) sections = load_sections(map_file)
@ -289,7 +274,7 @@ def load_map_data(map_file): # type: (TextIO) -> Tuple[str, Dict, Dict]
return detected_chip, segments, sections return detected_chip, segments, sections
def load_segments(map_file): # type: (TextIO) -> Dict def load_segments(map_file: TextIO) -> Dict:
""" Memory Configuration section is the total size of each segment """ """ Memory Configuration section is the total size of each segment """
result = {} # type: Dict[Any, Dict] result = {} # type: Dict[Any, Dict]
scan_to_header(map_file, 'Memory Configuration') scan_to_header(map_file, 'Memory Configuration')
@ -312,7 +297,7 @@ def load_segments(map_file): # type: (TextIO) -> Dict
raise RuntimeError('End of file while scanning memory configuration?') raise RuntimeError('End of file while scanning memory configuration?')
def detect_target_chip(map_file): # type: (Iterable) -> str def detect_target_chip(map_file: Iterable) -> str:
''' Detect target chip based on the target archive name in the linker script part of the MAP file ''' ''' Detect target chip based on the target archive name in the linker script part of the MAP file '''
scan_to_header(map_file, 'Linker script and memory map') scan_to_header(map_file, 'Linker script and memory map')
@ -340,7 +325,7 @@ def detect_target_chip(map_file): # type: (Iterable) -> str
raise RuntimeError('Target not detected') raise RuntimeError('Target not detected')
def load_sections(map_file): # type: (TextIO) -> Dict def load_sections(map_file: TextIO) -> Dict:
""" Load section size information from the MAP file. """ Load section size information from the MAP file.
Returns a dict of 'sections', where each key is a section name and the value Returns a dict of 'sections', where each key is a section name and the value
@ -372,7 +357,7 @@ def load_sections(map_file): # type: (TextIO) -> Dict
# Extract archive and object_file from the file_info field # Extract archive and object_file from the file_info field
RE_FILE = re.compile(r'((?P<archive>[^ ]+\.a)?\(?(?P<object_file>[^ ]+\.(o|obj))\)?)') RE_FILE = re.compile(r'((?P<archive>[^ ]+\.a)?\(?(?P<object_file>[^ ]+\.(o|obj))\)?)')
def dump_src_line(src): # type: (Dict) -> str def dump_src_line(src: Dict) -> str:
return '%s(%s) addr: 0x%08x, size: 0x%x+%d' % (src['sym_name'], src['file'], src['address'], src['size'], src['fill']) return '%s(%s) addr: 0x%08x, size: 0x%x+%d' % (src['sym_name'], src['file'], src['address'], src['size'], src['fill'])
sections = {} # type: Dict[Any, Dict] sections = {} # type: Dict[Any, Dict]
@ -481,13 +466,13 @@ def load_sections(map_file): # type: (TextIO) -> Dict
return sections return sections
def check_target(target, map_file): # type: (str, TextIO) -> None def check_target(target: str, map_file: TextIO) -> None:
if target is None: if target is None:
raise RuntimeError('The target chip cannot be detected for {}. ' raise RuntimeError('The target chip cannot be detected for {}. '
'Please report the issue.'.format(map_file.name)) 'Please report the issue.'.format(map_file.name))
def main(): # type: () -> None def main() -> None:
parser = argparse.ArgumentParser(description='idf_size - a tool to print size information from an IDF MAP file') parser = argparse.ArgumentParser(description='idf_size - a tool to print size information from an IDF MAP file')
parser.add_argument( parser.add_argument(
@ -576,7 +561,7 @@ class StructureForSummary(object):
used_diram_ratio = 0. used_diram_ratio = 0.
used_flash_text, used_flash_rodata, used_flash_other, used_flash, total_size = (0, ) * 5 used_flash_text, used_flash_rodata, used_flash_other, used_flash, total_size = (0, ) * 5
def __sub__(self, rhs): # type: (StructureForSummary) -> StructureForSummary def __sub__(self, rhs: 'StructureForSummary') -> 'StructureForSummary':
assert isinstance(rhs, StructureForSummary) assert isinstance(rhs, StructureForSummary)
ret = self ret = self
for key in StructureForSummary.get_required_items(): for key in StructureForSummary.get_required_items():
@ -584,33 +569,33 @@ class StructureForSummary(object):
return ret return ret
def get_dram_overflowed(self): # type: (StructureForSummary) -> bool def get_dram_overflowed(self) -> bool:
return self.used_dram_ratio > 1.0 return self.used_dram_ratio > 1.0
def get_iram_overflowed(self): # type: (StructureForSummary) -> bool def get_iram_overflowed(self) -> bool:
return self.used_iram_ratio > 1.0 return self.used_iram_ratio > 1.0
def get_diram_overflowed(self): # type: (StructureForSummary) -> bool def get_diram_overflowed(self) -> bool:
return self.used_diram_ratio > 1.0 return self.used_diram_ratio > 1.0
@classmethod @classmethod
def get_required_items(cls): # type: (Any) -> List def get_required_items(cls: Any) -> List:
whole_list = list(filter(lambda x: not (x.startswith('__') or x.endswith('__') or callable(getattr(cls, x))), dir(cls))) whole_list = list(filter(lambda x: not (x.startswith('__') or x.endswith('__') or callable(getattr(cls, x))), dir(cls)))
return whole_list return whole_list
@staticmethod @staticmethod
def get(segments, sections): # type: (List, List) -> StructureForSummary def get(segments: List, sections: List) -> 'StructureForSummary':
def get_size(sections): # type: (Iterable) -> int def get_size(sections: Iterable) -> int:
return sum([x.len for x in sections]) return sum([x.len for x in sections])
def in_diram(x): # type: (MemRegions.Region) -> bool def in_diram(x: MemRegions.Region) -> bool:
return x.region.type in (MemRegions.DRAM_ID, MemRegions.IRAM_ID) and x.region.secondary_addr > 0 return x.region.type in (MemRegions.DRAM_ID, MemRegions.IRAM_ID) and x.region.secondary_addr > 0
def in_dram(x): # type: (MemRegions.Region) -> bool def in_dram(x: MemRegions.Region) -> bool:
return x.region.type == MemRegions.DRAM_ID and x.region.secondary_addr == 0 # type: ignore return x.region.type == MemRegions.DRAM_ID and x.region.secondary_addr == 0 # type: ignore
def in_iram(x): # type: (MemRegions.Region) -> bool def in_iram(x: MemRegions.Region) -> bool:
return x.region.type == MemRegions.IRAM_ID and x.region.secondary_addr == 0 # type: ignore return x.region.type == MemRegions.IRAM_ID and x.region.secondary_addr == 0 # type: ignore
r = StructureForSummary() r = StructureForSummary()
@ -626,7 +611,7 @@ class StructureForSummary(object):
if r.diram_total == 0: if r.diram_total == 0:
r.diram_total = r.dram_total + r.iram_total r.diram_total = r.dram_total + r.iram_total
def filter_in_section(sections, section_to_check): # type: (Iterable[MemRegions.Region], str) -> List[MemRegions.Region] def filter_in_section(sections: Iterable[MemRegions.Region], section_to_check: str) -> List[MemRegions.Region]:
return list(filter(lambda x: LinkingSections.in_section(x.section, section_to_check), sections)) # type: ignore return list(filter(lambda x: LinkingSections.in_section(x.section, section_to_check), sections)) # type: ignore
dram_sections = list(filter(in_dram, sections)) dram_sections = list(filter(in_dram, sections))
@ -700,7 +685,7 @@ class StructureForSummary(object):
r.total_size = r.used_dram - r.used_dram_bss + r.used_iram + r.used_diram - r.used_diram_bss + r.used_flash r.total_size = r.used_dram - r.used_dram_bss + r.used_iram + r.used_diram - r.used_diram_bss + r.used_flash
return r return r
def get_json_dic(self): # type: (StructureForSummary) -> collections.OrderedDict def get_json_dic(self) -> collections.OrderedDict:
ret = collections.OrderedDict([ ret = collections.OrderedDict([
('dram_data', self.used_dram_data), ('dram_data', self.used_dram_data),
('dram_bss', self.used_dram_bss), ('dram_bss', self.used_dram_bss),
@ -741,7 +726,7 @@ class StructureForSummary(object):
return ret return ret
def get_structure_for_target(segments, sections, target): # type: (Dict, Dict, str) -> StructureForSummary def get_structure_for_target(segments: Dict, sections: Dict, target: str) -> StructureForSummary:
""" """
Return StructureForSummary for spasific target Return StructureForSummary for spasific target
""" """
@ -752,10 +737,10 @@ def get_structure_for_target(segments, sections, target): # type: (Dict, Dict,
return current return current
def get_summary(path, segments, sections, target, def get_summary(path: str, segments: Dict, sections: Dict, target: str,
as_json=False, as_json: bool=False,
path_diff='', segments_diff=None, sections_diff=None, target_diff='', print_suggestions=True): path_diff: str='', segments_diff: Optional[Dict]=None, sections_diff: Optional[Dict]=None,
# type: (str, Dict, Dict, str, bool, str, Optional[Dict], Optional[Dict], str, bool) -> str target_diff: str='', print_suggestions: bool=True) -> str:
if segments_diff is None: if segments_diff is None:
segments_diff = {} segments_diff = {}
if sections_diff is None: if sections_diff is None:
@ -790,11 +775,11 @@ def get_summary(path, segments, sections, target,
title = '' title = ''
name = '' name = ''
def __init__(self, title, name): # type: (LineDef, str, str) -> None def __init__(self, title: str, name: str) -> None:
self.title = title self.title = title
self.name = name self.name = name
def format_line(self): # type: (LineDef) -> Tuple[str, str, str, str] def format_line(self) -> Tuple[str, str, str, str]:
return (self.title + ': {%s:>7} bytes' % self.name, return (self.title + ': {%s:>7} bytes' % self.name,
'{%s:>7}' % self.name, '{%s:>7}' % self.name,
'{%s:+}' % self.name, '{%s:+}' % self.name,
@ -806,14 +791,14 @@ def get_summary(path, segments, sections, target,
total = '' total = ''
warning_message = '' warning_message = ''
def __init__(self, title, name, remain, ratio, total, warning_message): # type: (HeadLineDef, str, str, str, str, str, str) -> None def __init__(self, title: str, name: str, remain: str, ratio: str, total: str, warning_message: str) -> None:
super(HeadLineDef, self).__init__(title, name) super(HeadLineDef, self).__init__(title, name)
self.remain = remain self.remain = remain
self.ratio = ratio self.ratio = ratio
self.total = total self.total = total
self.warning_message = warning_message self.warning_message = warning_message
def format_line(self): # type: (HeadLineDef) -> Tuple[str, str, str, str] def format_line(self) -> Tuple[str, str, str, str]:
return ('%s: {%s:>7} bytes ({%s:>7} remain, {%s:.1%%} used)%s' % (self.title, self.name, self.remain, self.ratio, self.warning_message), return ('%s: {%s:>7} bytes ({%s:>7} remain, {%s:.1%%} used)%s' % (self.title, self.name, self.remain, self.ratio, self.warning_message),
'{%s:>7}' % self.name, '{%s:>7}' % self.name,
'{%s:+}' % self.name, '{%s:+}' % self.name,
@ -821,7 +806,7 @@ def get_summary(path, segments, sections, target,
class TotalLineDef(LineDef): class TotalLineDef(LineDef):
def format_line(self): # type: (TotalLineDef) -> Tuple[str, str, str, str] def format_line(self) -> Tuple[str, str, str, str]:
return (self.title + ': {%s:>7} bytes (.bin may be padded larger)' % self.name, return (self.title + ': {%s:>7} bytes (.bin may be padded larger)' % self.name,
'{%s:>7}' % self.name, '{%s:>7}' % self.name,
'{%s:+}' % self.name, '{%s:+}' % self.name,
@ -858,7 +843,7 @@ def get_summary(path, segments, sections, target,
TotalLineDef('Total image size', 'total_size') TotalLineDef('Total image size', 'total_size')
] ]
def convert_to_fmt_dict(summary, suffix=''): # type: (StructureForSummary, str) -> Dict def convert_to_fmt_dict(summary: StructureForSummary, suffix: str='') -> Dict:
required_items = StructureForSummary.get_required_items() required_items = StructureForSummary.get_required_items()
return dict([(key + suffix, getattr(summary, key)) for key in required_items]) return dict([(key + suffix, getattr(summary, key)) for key in required_items])
@ -869,8 +854,7 @@ def get_summary(path, segments, sections, target,
lf = '{:60}{:>15}{:>15} {}' # Width for a, b, c, d columns lf = '{:60}{:>15}{:>15} {}' # Width for a, b, c, d columns
def print_in_columns(a, b='', c='', d=''): def print_in_columns(a: str, b: Optional[str]='', c: Optional[str]='', d: Optional[str]='') -> str:
# type: (str, Optional[str], Optional[str], Optional[str]) -> str
return lf.format(a, b, c, d).rstrip() + os.linesep return lf.format(a, b, c, d).rstrip() + os.linesep
output = '' output = ''
@ -900,7 +884,7 @@ def get_summary(path, segments, sections, target,
return output return output
def check_is_dict_sort(non_sort_list): # type: (List) -> List def check_is_dict_sort(non_sort_list: List) -> List:
''' '''
sort with keeping the order data, bss, other, iram, diram, ram_st_total, flash_text, flash_rodata, flash_total sort with keeping the order data, bss, other, iram, diram, ram_st_total, flash_text, flash_rodata, flash_total
''' '''
@ -924,7 +908,7 @@ def check_is_dict_sort(non_sort_list): # type: (List) -> List
class StructureForDetailedSizes(object): class StructureForDetailedSizes(object):
@staticmethod @staticmethod
def sizes_by_key(sections, key, include_padding=False): # type: (SectionDict, str, Optional[bool]) -> Dict[str, Dict[str, int]] def sizes_by_key(sections: SectionDict, key: str, include_padding: Optional[bool]=False) -> Dict[str, Dict[str, int]]:
""" Takes a dict of sections (from load_sections) and returns """ Takes a dict of sections (from load_sections) and returns
a dict keyed by 'key' with aggregate output size information. a dict keyed by 'key' with aggregate output size information.
@ -944,7 +928,7 @@ class StructureForDetailedSizes(object):
return result return result
@staticmethod @staticmethod
def get(sections, by_key): # type: (SectionDict, str) -> collections.OrderedDict def get(sections: SectionDict, by_key: str) -> collections.OrderedDict:
# Get the detailed structure before using the filter to remove undesired sections, # Get the detailed structure before using the filter to remove undesired sections,
# to show entries without desired sections # to show entries without desired sections
sizes = StructureForDetailedSizes.sizes_by_key(sections, by_key) sizes = StructureForDetailedSizes.sizes_by_key(sections, by_key)
@ -970,7 +954,7 @@ class StructureForDetailedSizes(object):
return collections.OrderedDict(s) return collections.OrderedDict(s)
def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None): # type: (Dict, str, str, bool, Dict) -> str def get_detailed_sizes(sections: Dict, key: str, header: str, as_json: bool=False, sections_diff: Dict=None) -> str:
key_name_set = set() key_name_set = set()
current = StructureForDetailedSizes.get(sections, key) current = StructureForDetailedSizes.get(sections, key)
@ -1004,13 +988,12 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None)
else: else:
output = format_json(current) output = format_json(current)
else: else:
def _get_header_format(disp_list=display_name_list): # type: (List) -> str def _get_header_format(disp_list: List=display_name_list) -> str:
len_list = [len(x) for x in disp_list] len_list = [len(x) for x in disp_list]
len_list.insert(0, 24) len_list.insert(0, 24)
return ' '.join(['{:>%d}' % x for x in len_list]) + os.linesep return ' '.join(['{:>%d}' % x for x in len_list]) + os.linesep
def _get_output(data, selection, key_list=ordered_key_list, disp_list=display_name_list): def _get_output(data: Dict[str, Dict[str, int]], selection: Collection, key_list: List=ordered_key_list, disp_list: List=display_name_list) -> str:
# type: (Dict[str, Dict[str, int]], Collection, List, List) -> str
header_format = _get_header_format(disp_list) header_format = _get_header_format(disp_list)
output = header_format.format(header, *disp_list) output = header_format.format(header, *disp_list)
@ -1025,14 +1008,14 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None)
# k remains the same # k remains the same
pass pass
def get_section_size(section_dict): # type: (Dict) -> Callable[[str], int] def get_section_size(section_dict: Dict) -> Callable[[str], int]:
return lambda x: section_dict.get(x, 0) return lambda x: section_dict.get(x, 0)
section_size_list = map(get_section_size(section_dict=v), key_list) section_size_list = map(get_section_size(section_dict=v), key_list)
output += header_format.format(k[:24], *(section_size_list)) output += header_format.format(k[:24], *(section_size_list))
return output return output
def _get_header_format_diff(disp_list=display_name_list, columns=False): # type: (List, bool) -> str def _get_header_format_diff(disp_list: List=display_name_list, columns: bool=False) -> str:
if columns: if columns:
len_list = (24, ) + (7, ) * 3 * len(disp_list) len_list = (24, ) + (7, ) * 3 * len(disp_list)
return '|'.join(['{:>%d}' % x for x in len_list]) + os.linesep return '|'.join(['{:>%d}' % x for x in len_list]) + os.linesep
@ -1040,8 +1023,7 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None)
len_list = (24, ) + (23, ) * len(disp_list) len_list = (24, ) + (23, ) * len(disp_list)
return ' '.join(['{:>%d}' % x for x in len_list]) + os.linesep return ' '.join(['{:>%d}' % x for x in len_list]) + os.linesep
def _get_output_diff(curr, ref, key_list=ordered_key_list, disp_list=display_name_list): def _get_output_diff(curr: Dict, ref: Dict, key_list: List=ordered_key_list, disp_list: List=display_name_list) -> str:
# type: (Dict, Dict, List, List) -> str
# First header without Current/Ref/Diff columns # First header without Current/Ref/Diff columns
header_format = _get_header_format_diff(columns=False) header_format = _get_header_format_diff(columns=False)
output = header_format.format(header, *disp_list) output = header_format.format(header, *disp_list)
@ -1069,8 +1051,7 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None)
# k remains the same # k remains the same
pass pass
def _get_items(name, section_dict=v, section_dict_ref=v2): def _get_items(name: str, section_dict: Dict=v, section_dict_ref: Dict=v2) -> Tuple[str, str, str]:
# type: (str, Dict, Dict) -> Tuple[str, str, str]
a = section_dict.get(name, 0) a = section_dict.get(name, 0)
b = section_dict_ref.get(name, 0) b = section_dict_ref.get(name, 0)
diff = a - b diff = a - b
@ -1110,7 +1091,7 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None)
class StructureForArchiveSymbols(object): class StructureForArchiveSymbols(object):
@staticmethod @staticmethod
def get(archive, sections): # type: (str, Dict) -> Dict def get(archive: str, sections: Dict) -> Dict:
interested_sections = LinkingSections.filter_sections(sections) interested_sections = LinkingSections.filter_sections(sections)
result = dict([(t, {}) for t in interested_sections]) # type: Dict[str, Dict[str, int]] result = dict([(t, {}) for t in interested_sections]) # type: Dict[str, Dict[str, int]]
@ -1135,7 +1116,7 @@ class StructureForArchiveSymbols(object):
return section_symbols return section_symbols
def get_archive_symbols(sections, archive, as_json=False, sections_diff=None): # type: (Dict, str, bool, Dict) -> str def get_archive_symbols(sections: Dict, archive: str, as_json: bool=False, sections_diff: Dict=None) -> str:
diff_en = sections_diff is not None diff_en = sections_diff is not None
current = StructureForArchiveSymbols.get(archive, sections) current = StructureForArchiveSymbols.get(archive, sections)
reference = StructureForArchiveSymbols.get(archive, sections_diff) if sections_diff else {} reference = StructureForArchiveSymbols.get(archive, sections_diff) if sections_diff else {}
@ -1157,10 +1138,10 @@ def get_archive_symbols(sections, archive, as_json=False, sections_diff=None):
else: else:
output = format_json(current) output = format_json(current)
else: else:
def _get_item_pairs(name, section): # type: (str, collections.OrderedDict) -> collections.OrderedDict def _get_item_pairs(name: str, section: collections.OrderedDict) -> collections.OrderedDict:
return collections.OrderedDict([(key.replace(name + '.', ''), val) for key, val in iteritems(section)]) return collections.OrderedDict([(key.replace(name + '.', ''), val) for key, val in iteritems(section)])
def _get_output(section_symbols): # type: (Dict) -> str def _get_output(section_symbols: Dict) -> str:
output = '' output = ''
for t, s in iteritems(section_symbols): for t, s in iteritems(section_symbols):
output += '{}Symbols from section: {}{}'.format(os.linesep, t, os.linesep) output += '{}Symbols from section: {}{}'.format(os.linesep, t, os.linesep)
@ -1175,8 +1156,7 @@ def get_archive_symbols(sections, archive, as_json=False, sections_diff=None):
output = 'Symbols within the archive: {} (Not all symbols may be reported){}'.format(archive, os.linesep) output = 'Symbols within the archive: {} (Not all symbols may be reported){}'.format(archive, os.linesep)
if diff_en: if diff_en:
def _generate_line_tuple(curr, ref, name): def _generate_line_tuple(curr: collections.OrderedDict, ref: collections.OrderedDict, name: str) -> Tuple[str, int, int, str]:
# type: (collections.OrderedDict, collections.OrderedDict, str) -> Tuple[str, int, int, str]
cur_val = curr.get(name, 0) cur_val = curr.get(name, 0)
ref_val = ref.get(name, 0) ref_val = ref.get(name, 0)
diff_val = cur_val - ref_val diff_val = cur_val - ref_val

View File

@ -1,129 +1,130 @@
#!/usr/bin/env bash #!/usr/bin/env bash
{ coverage debug sys \
&& coverage erase &> output \ { python -m coverage debug sys \
&& python -m coverage erase &> output \
&& echo -e "\n***\nRunning idf_size.py..." &>> output \ && echo -e "\n***\nRunning idf_size.py..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py on bootloader..." &>> output \ && echo -e "\n***\nRunning idf_size.py on bootloader..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py bootloader.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py bootloader.map &>> output \
&& echo -e "\n***\nRunning idf_size.py with overflow..." &>> output \ && echo -e "\n***\nRunning idf_size.py with overflow..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py overflow.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py overflow.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archives..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archives..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --archives app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --archives app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --files..." &>> output \ && echo -e "\n***\nRunning idf_size.py --files..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --files app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --files app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archive_details..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --archive_details libdriver.a app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --archive_details libdriver.a app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff with bootloader..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff with bootloader..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff bootloader.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff bootloader.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff with itself..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff with itself..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff with another app..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff with another app..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff with app in reverse order..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff with app in reverse order..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app2.map --diff app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app2.map --diff app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archives with bootloader..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archives with bootloader..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff bootloader.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff bootloader.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archives with itself..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archives with itself..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archives with another app..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archives with another app..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff app2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archives with app in reverse order..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archives with app in reverse order..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app2.map --archives --diff app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app2.map --archives --diff app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --files with bootloader..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --files with bootloader..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff bootloader.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff bootloader.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --files with itself..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --files with itself..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --files with another app..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --files with another app..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff app2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --files with app in reverse order..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --files with app in reverse order..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app2.map --files --diff app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app2.map --files --diff app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archive_details with bootloader..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with bootloader..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff bootloader.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff bootloader.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archive_details with bootloader..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with bootloader..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libc.a --diff bootloader.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libc.a --diff bootloader.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archive_details with itself..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with itself..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archive_details with another app..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with another app..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff app2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archive_details with app in reverse order..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with app in reverse order..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app2.map --archive_details libdriver.a --diff app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app2.map --archive_details libdriver.a --diff app.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff --archive_details with another app..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with another app..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libfreertos.a --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libfreertos.a --diff app2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32s2..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 app_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 app_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32s2 with overflow..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s2 with overflow..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 overflow_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 overflow_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32s2 (target autodetected)..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s2 (target autodetected)..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py on bootloader for esp32s2..." &>> output \ && echo -e "\n***\nRunning idf_size.py on bootloader for esp32s2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 bootloader_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 bootloader_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py on bootloader for esp32s2 (target autodetected)..." &>> output \ && echo -e "\n***\nRunning idf_size.py on bootloader for esp32s2 (target autodetected)..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py bootloader_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py bootloader_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archives for esp32s2..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archives for esp32s2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --archives app_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --archives app_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --files for esp32s2..." &>> output \ && echo -e "\n***\nRunning idf_size.py --files for esp32s2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --files app_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --files app_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archive_details for esp32s2..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details for esp32s2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --archive_details libdriver.a app_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --archive_details libdriver.a app_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py diff with another app (different target)..." &>> output \ && echo -e "\n***\nRunning idf_size.py diff with another app (different target)..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app_esp32s2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app_esp32s2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32h2..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32h2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 app_esp32h2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 app_esp32h2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32h2 (target autodetected)..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32h2 (target autodetected)..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app_esp32h2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app_esp32h2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archives for esp32h2..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archives for esp32h2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --archives app_esp32h2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --archives app_esp32h2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --files for esp32h2..." &>> output \ && echo -e "\n***\nRunning idf_size.py --files for esp32h2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --files app_esp32h2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --files app_esp32h2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archive_details for esp32h2..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details for esp32h2..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --archive_details libdriver.a app_esp32h2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --archive_details libdriver.a app_esp32h2.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32c3..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32c3..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 app_esp32c3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 app_esp32c3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32c3 with overflow..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32c3 with overflow..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 overflow_esp32c3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 overflow_esp32c3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32c3 (target autodetected)..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32c3 (target autodetected)..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app_esp32c3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app_esp32c3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archives for esp32c3..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archives for esp32c3..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --archives app_esp32c3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --archives app_esp32c3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --files for esp32c3..." &>> output \ && echo -e "\n***\nRunning idf_size.py --files for esp32c3..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --files app_esp32c3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --files app_esp32c3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archive_details for esp32c3..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details for esp32c3..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --archive_details libdriver.a app_esp32c3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --archive_details libdriver.a app_esp32c3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32s3..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s3..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 app_esp32s3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 app_esp32s3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32s3 with overflow..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s3 with overflow..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 overflow_esp32s3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 overflow_esp32s3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py for esp32s3 (target autodetected)..." &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s3 (target autodetected)..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py app_esp32s3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py app_esp32s3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archives for esp32s3..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archives for esp32s3..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --archives app_esp32s3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --archives app_esp32s3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --files for esp32s3..." &>> output \ && echo -e "\n***\nRunning idf_size.py --files for esp32s3..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --files app_esp32s3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --files app_esp32s3.map &>> output \
&& echo -e "\n***\nRunning idf_size.py --archive_details for esp32s3..." &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details for esp32s3..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --archive_details libdriver.a app_esp32s3.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --archive_details libdriver.a app_esp32s3.map &>> output \
&& echo -e "\n***\nProducing JSON output..." &>> output \ && echo -e "\n***\nProducing JSON output..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json app.map &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json app.map --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json app.map --diff app2.map &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map --diff app2.map &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map --diff app2.map &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map --diff app2.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map --diff app2.map &>> output \
&& echo -e "\n***\nProducing JSON file output..." &>> output \ && echo -e "\n***\nProducing JSON file output..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py --json --output-file output.json app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --output-file output.json app.map &>> output \
&& echo -e "\n***\nProducing text file output..." &>> output \ && echo -e "\n***\nProducing text file output..." &>> output \
&& coverage run -a $IDF_PATH/tools/idf_size.py -o output.txt app.map &>> output \ && python -m coverage run -a $IDF_PATH/tools/idf_size.py -o output.txt app.map &>> output \
&& echo -e "\n***\nRunning idf_size_tests.py..." &>> output \ && echo -e "\n***\nRunning idf_size_tests.py..." &>> output \
&& coverage run -a $IDF_PATH/tools/test_idf_size/test_idf_size.py &>> output \ && python -m coverage run -a $IDF_PATH/tools/test_idf_size/test_idf_size.py &>> output \
&& echo -e "\n\nComparing expected output..." \ && echo -e "\n\nComparing expected output..." \
&& diff -Z output expected_output \ && diff -Z output expected_output \
&& echo -e "\n\nComparing expected json output..." \ && echo -e "\n\nComparing expected json output..." \
&& diff -Z output.json expected_output.json \ && diff -Z output.json expected_output.json \
&& echo -e "\n\nComparing expected text output..." \ && echo -e "\n\nComparing expected text output..." \
&& diff -Z output.txt expected_output.txt \ && diff -Z output.txt expected_output.txt \
&& coverage report \ && python -m coverage report \
; } || { echo 'The test for idf_size has failed. Please examine the artifacts.' ; exit 1; } ; } || { echo 'The test for idf_size has failed. Please examine the artifacts.' ; exit 1; }
# Note: "diff -Z is used because some versions of Python print trailing whitespace for JSON pretty-printing, and some don't # Note: "diff -Z is used because some versions of Python print trailing whitespace for JSON pretty-printing, and some don't