From 1b74f380a616c3f5025056a60c577d30faad8264 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 27 Sep 2019 17:22:21 +0300 Subject: [PATCH] Refactor appending of debugging flags --- .isort.cfg | 2 +- platformio/builder/main.py | 7 +-- platformio/builder/tools/piomisc.py | 36 +++++++----- platformio/builder/tools/piosize.py | 77 +++++++++++--------------- platformio/builder/tools/platformio.py | 13 ++--- setup.py | 54 ++++++++++++------ 6 files changed, 99 insertions(+), 90 deletions(-) diff --git a/.isort.cfg b/.isort.cfg index 7e5d6e51..2270008c 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -1,3 +1,3 @@ [settings] line_length=88 -known_third_party=bottle,click,pytest,requests,SCons,semantic_version,serial,twisted,autobahn,jsonrpc,tabulate +known_third_party=SCons, twisted, autobahn, jsonrpc diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 95099b98..e0179bf4 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -194,10 +194,9 @@ if "idedata" in COMMAND_LINE_TARGETS: if "sizedata" in COMMAND_LINE_TARGETS: AlwaysBuild( env.Alias( - "sizedata", DEFAULT_TARGETS, - env.VerboseAction( - env.DumpSizeData, "Generating memory usage report...", - ) + "sizedata", + DEFAULT_TARGETS, + env.VerboseAction(env.DumpSizeData, "Generating memory usage report..."), ) ) diff --git a/platformio/builder/tools/piomisc.py b/platformio/builder/tools/piomisc.py index a1b564b9..5c3e414c 100644 --- a/platformio/builder/tools/piomisc.py +++ b/platformio/builder/tools/piomisc.py @@ -23,6 +23,7 @@ from tempfile import mkstemp from SCons.Action import Action # pylint: disable=import-error from SCons.Script import ARGUMENTS # pylint: disable=import-error +from SCons.Script import COMMAND_LINE_TARGETS # pylint: disable=import-error from platformio import fs, util from platformio.compat import get_file_contents, glob_escape @@ -294,32 +295,37 @@ def VerboseAction(_, act, actstr): def PioClean(env, clean_dir): if not isdir(clean_dir): - print ("Build environment is clean") + print("Build environment is clean") env.Exit(0) clean_rel_path = relpath(clean_dir) for root, _, files in walk(clean_dir): for f in files: dst = join(root, f) remove(dst) - print ( + print( "Removed %s" % (dst if clean_rel_path.startswith(".") else relpath(dst)) ) - print ("Done cleaning") + print("Done cleaning") fs.rmtree(clean_dir) env.Exit(0) -def ConfigureDebugTarget(env): - if not env.subst("$PIODEBUGFLAGS"): - env.Replace(PIODEBUGFLAGS=["-Og", "-g3", "-ggdb3"]) - env.Append( - BUILD_FLAGS=list(env["PIODEBUGFLAGS"]) + ["-D__PLATFORMIO_BUILD_DEBUG__"] - ) - unflags = ["-Os"] - for level in [0, 1, 2]: - for flag in ("O", "g", "ggdb"): - unflags.append("-%s%d" % (flag, level)) - env.Append(BUILD_UNFLAGS=unflags) +def ConfigureDebugFlags(env): + def _cleanup_debug_flags(scope): + if scope not in env: + return + unflags = ["-Os", "-g"] + for level in [0, 1, 2]: + for flag in ("O", "g", "ggdb"): + unflags.append("-%s%d" % (flag, level)) + env[scope] = [f for f in env.get(scope, []) if f not in unflags] + + env.Append(CPPDEFINES=["__PLATFORMIO_BUILD_DEBUG__"]) + + debug_flags = ["-Og", "-g3", "-ggdb3"] + for scope in ("ASFLAGS", "CCFLAGS", "LINKFLAGS"): + _cleanup_debug_flags(scope) + env.Append(**{scope: debug_flags}) def ConfigureTestTarget(env): @@ -361,7 +367,7 @@ def generate(env): env.AddMethod(GetActualLDScript) env.AddMethod(VerboseAction) env.AddMethod(PioClean) - env.AddMethod(ConfigureDebugTarget) + env.AddMethod(ConfigureDebugFlags) env.AddMethod(ConfigureTestTarget) env.AddMethod(GetExtraScripts) return env diff --git a/platformio/builder/tools/piosize.py b/platformio/builder/tools/piosize.py index b797509a..12303747 100644 --- a/platformio/builder/tools/piosize.py +++ b/platformio/builder/tools/piosize.py @@ -24,16 +24,14 @@ from platformio.proc import exec_command def _get_file_location(env, elf_path, addr, sysenv): - cmd = [env.subst("$CC").replace( - "-gcc", "-addr2line"), "-e", elf_path, hex(addr)] + cmd = [env.subst("$CC").replace("-gcc", "-addr2line"), "-e", elf_path, hex(addr)] result = exec_command(cmd, env=sysenv) - return result['out'].strip().replace("\\", "/") + return result["out"].strip().replace("\\", "/") def _determine_section(sections, symbol_addr): for section, info in sections.items(): - if symbol_addr in range(info['start_addr'], - info['start_addr'] + info['size']): + if symbol_addr in range(info["start_addr"], info["start_addr"] + info["size"]): return section return "unknown" @@ -41,20 +39,21 @@ def _determine_section(sections, symbol_addr): def _demangle_cpp_name(env, symbol_name, sysenv): cmd = [env.subst("$CC").replace("-gcc", "-c++filt"), symbol_name] result = exec_command(cmd, env=sysenv) - demangled_name = result['out'].strip() + demangled_name = result["out"].strip() if "(" in demangled_name: - demangled_name = demangled_name[0:demangled_name.find("(")] + demangled_name = demangled_name[0 : demangled_name.find("(")] return demangled_name def _is_ram_section(section): - return section.get("type", "") in ( - "SHT_NOBITS", "SHT_PROGBITS") and section.get("flags", "") == "WA" + return ( + section.get("type", "") in ("SHT_NOBITS", "SHT_PROGBITS") + and section.get("flags", "") == "WA" + ) def _is_flash_section(section): - return section.get("type") == "SHT_PROGBITS" and "A" in section.get( - "flags") + return section.get("type") == "SHT_PROGBITS" and "A" in section.get("flags") def _is_valid_symbol(symbol_name, symbol_type, symbol_address): @@ -67,15 +66,15 @@ def _collect_sections_info(elffile): if section.is_null(): continue - section_type = section['sh_type'] - section_flags = describe_sh_flags(section['sh_flags']) + section_type = section["sh_type"] + section_flags = describe_sh_flags(section["sh_flags"]) section_size = section.data_size sections[section.name] = { "size": section_size, - "start_addr": section['sh_addr'], + "start_addr": section["sh_addr"], "type": section_type, - "flags": section_flags + "flags": section_flags, } return sections @@ -84,7 +83,7 @@ def _collect_sections_info(elffile): def _collect_symbols_info(env, elffile, elf_path, sections): symbols = [] - symbol_section = elffile.get_section_by_name('.symtab') + symbol_section = elffile.get_section_by_name(".symtab") if symbol_section.is_null(): sys.stderr.write("Couldn't find symbol table. Is ELF file stripped?") env.Exit(1) @@ -93,26 +92,26 @@ def _collect_symbols_info(env, elffile, elf_path, sections): sysenv["PATH"] = str(env["ENV"]["PATH"]) for s in symbol_section.iter_symbols(): - symbol_info = s.entry['st_info'] - symbol_addr = s['st_value'] - symbol_size = s['st_size'] - symbol_type = symbol_info['type'] + symbol_info = s.entry["st_info"] + symbol_addr = s["st_value"] + symbol_size = s["st_size"] + symbol_type = symbol_info["type"] if not _is_valid_symbol(s.name, symbol_type, symbol_addr): continue symbol = { "addr": symbol_addr, - "bind": symbol_info['bind'], + "bind": symbol_info["bind"], "location": _get_file_location(env, elf_path, symbol_addr, sysenv), "name": s.name, "type": symbol_type, "size": symbol_size, - "section": _determine_section(sections, symbol_addr) + "section": _determine_section(sections, symbol_addr), } if s.name.startswith("_Z"): - symbol['demangled_name'] = _demangle_cpp_name(env, s.name, sysenv) + symbol["demangled_name"] = _demangle_cpp_name(env, s.name, sysenv) symbols.append(symbol) @@ -130,11 +129,8 @@ def _calculate_firmware_size(sections): return ram_size, flash_size -def DumpSizeData(_, target, source, env): - data = { - "memory": {}, - "version": 1 - } +def DumpSizeData(_, target, source, env): # pylint: disable=unused-argument + data = {"memory": {}, "version": 1} elf_path = env.subst("$PIOMAINPROG") @@ -147,10 +143,10 @@ def DumpSizeData(_, target, source, env): sections = _collect_sections_info(elffile) firmware_ram, firmware_flash = _calculate_firmware_size(sections) - data['memory']['total'] = { + data["memory"]["total"] = { "ram_size": firmware_ram, "flash_size": firmware_flash, - "sections": sections + "sections": sections, } files = dict() @@ -160,38 +156,27 @@ def DumpSizeData(_, target, source, env): file_path = "unknown" if not files.get(file_path, {}): - files[file_path] = { - "symbols": [], - "ram_size": 0, - "flash_size": 0 - } + files[file_path] = {"symbols": [], "ram_size": 0, "flash_size": 0} symbol_size = symbol.get("size", 0) section = sections.get(symbol.get("section", ""), {}) if _is_ram_section(section): - files[file_path]['ram_size'] += symbol_size + files[file_path]["ram_size"] += symbol_size if _is_flash_section(section): - files[file_path]['flash_size'] += symbol_size + files[file_path]["flash_size"] += symbol_size - files[file_path]['symbols'].append(symbol) + files[file_path]["symbols"].append(symbol) - data['memory']['files'] = files + data["memory"]["files"] = files with open(join(env.subst("$BUILD_DIR"), "sizedata.json"), "w") as fp: fp.write(dump_json_to_unicode(data)) -def ConfigureSizeDataTarget(env): - for flags_section in ("ASFLAGS", "CCFLAGS", "LINKFLAGS"): - if not any("-g" in f for f in env.get(flags_section, [])): - env.Prepend(**{flags_section: ["-g"]}) - - def exists(_): return True def generate(env): env.AddMethod(DumpSizeData) - env.AddMethod(ConfigureSizeDataTarget) return env diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index 2f689b92..f032be94 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -103,9 +103,6 @@ def BuildProgram(env): if not Util.case_sensitive_suffixes(".s", ".S"): env.Replace(AS="$CC", ASCOM="$ASPPCOM") - if "debug" in COMMAND_LINE_TARGETS or env.GetProjectOption("build_type") == "debug": - env.ConfigureDebugTarget() - # process extra flags from board if "BOARD" in env and "build.extra_flags" in env.BoardConfig(): env.ProcessFlags(env.BoardConfig().get("build.extra_flags")) @@ -116,8 +113,11 @@ def BuildProgram(env): # process framework scripts env.BuildFrameworks(env.get("PIOFRAMEWORK")) - # restore PIO macros if it was deleted by framework - _append_pio_macros() + if ( + set(["debug", "sizedata"]) & set(COMMAND_LINE_TARGETS) + or env.GetProjectOption("build_type") == "debug" + ): + env.ConfigureDebugFlags() # remove specified flags env.ProcessUnFlags(env.get("BUILD_UNFLAGS")) @@ -125,9 +125,6 @@ def BuildProgram(env): if "__test" in COMMAND_LINE_TARGETS: env.ConfigureTestTarget() - if "sizedata" in COMMAND_LINE_TARGETS: - env.ConfigureSizeDataTarget() - # build project with dependencies _build_project_deps(env) diff --git a/setup.py b/setup.py index 7d37ad42..60b0a115 100644 --- a/setup.py +++ b/setup.py @@ -14,8 +14,15 @@ from setuptools import find_packages, setup -from platformio import (__author__, __description__, __email__, __license__, - __title__, __url__, __version__) +from platformio import ( + __author__, + __description__, + __email__, + __license__, + __title__, + __url__, + __version__, +) install_requires = [ "bottle<0.13", @@ -24,7 +31,8 @@ install_requires = [ "pyserial>=3,<4,!=3.3", "requests>=2.4.0,<3", "semantic_version>=2.8.1,<3", - "tabulate>=0.8.3,<1" + "tabulate>=0.8.3,<1", + "pyelftools>=0.25,<1", ] setup( @@ -36,8 +44,9 @@ setup( author_email=__email__, url=__url__, license=__license__, - python_requires=", ".join([ - ">=2.7", "!=3.0.*", "!=3.1.*", "!=3.2.*", "!=3.3.*", "!=3.4.*"]), + python_requires=", ".join( + [">=2.7", "!=3.0.*", "!=3.1.*", "!=3.2.*", "!=3.3.*", "!=3.4.*"] + ), install_requires=install_requires, packages=find_packages() + ["scripts"], package_data={ @@ -45,17 +54,15 @@ setup( "ide/tpls/*/.*.tpl", "ide/tpls/*/*.tpl", "ide/tpls/*/*/*.tpl", - "ide/tpls/*/.*/*.tpl" + "ide/tpls/*/.*/*.tpl", ], - "scripts": [ - "99-platformio-udev.rules" - ] + "scripts": ["99-platformio-udev.rules"], }, entry_points={ "console_scripts": [ + "platformio = platformio.__main__:main", "pio = platformio.__main__:main", "piodebuggdb = platformio.__main__:debug_gdb_main", - "platformio = platformio.__main__:main" ] }, classifiers=[ @@ -70,11 +77,26 @@ setup( "Programming Language :: Python :: 3", "Topic :: Software Development", "Topic :: Software Development :: Build Tools", - "Topic :: Software Development :: Compilers" + "Topic :: Software Development :: Compilers", ], keywords=[ - "iot", "embedded", "arduino", "mbed", "esp8266", "esp32", "fpga", - "firmware", "continuous-integration", "cloud-ide", "avr", "arm", - "ide", "unit-testing", "hardware", "verilog", "microcontroller", - "debug" - ]) + "iot", + "embedded", + "arduino", + "mbed", + "esp8266", + "esp32", + "fpga", + "firmware", + "continuous-integration", + "cloud-ide", + "avr", + "arm", + "ide", + "unit-testing", + "hardware", + "verilog", + "microcontroller", + "debug", + ], +)