From 6db069f9464de3245b0392797195f43f713ee14f Mon Sep 17 00:00:00 2001 From: MacDada Date: Sun, 18 Jun 2023 04:25:29 +0200 Subject: [PATCH] ``-Wpedantic` for `native` and `nodemcu` envs * not enabling for `native_arduino` -> as I'm getting lots of shit from `ArduinoFake` * marking framework packages as "system" to disable checking for them -> as they also throw a lot of shit * I have a little amount of shit in my code -> to be fixed https://github.com/platformio/platformio-core/issues/4667 --- config/common.ini | 4 +- config/native.ini | 2 + config/native_arduino.ini | 13 ++++ config/nodemcu.ini | 14 ++++ scripts/pio_extra_script_helper.py | 117 +++++++++++++++++++++++++++++ scripts/pio_post_extra_script.py | 15 +++- scripts/utils.py | 14 ++++ 7 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 scripts/pio_extra_script_helper.py create mode 100644 scripts/utils.py diff --git a/config/common.ini b/config/common.ini index 0eb3ee5..ca97e18 100644 --- a/config/common.ini +++ b/config/common.ini @@ -57,7 +57,9 @@ build_flags = ; List of flags that I want to be applied to _my_ code, ; while I don't want them for the external libraries (dependencies). ; -; Despite the name, it applies also to files in `lib` and `test`. +; Despite the name and the docs, it applies also to files in `lib` and `test`, +; and apparently even for external libs… +; https://github.com/platformio/platformio-core/issues/4667 ; ; -> Mostly because the external libs are not / will not be fixed, ; and I don't want them to pollute my build results. diff --git a/config/native.ini b/config/native.ini index 3fc68a1..e104f01 100644 --- a/config/native.ini +++ b/config/native.ini @@ -31,6 +31,8 @@ build_flags = build_src_flags = ${common.build_src_flags} + -Wpedantic + ; https://docs.platformio.org/en/latest/projectconf/section_env_build.html#build-src-filter build_src_filter = "+" diff --git a/config/native_arduino.ini b/config/native_arduino.ini index 660414f..0c5c2f8 100644 --- a/config/native_arduino.ini +++ b/config/native_arduino.ini @@ -16,6 +16,19 @@ lib_extra_dirs = arduino native_arduino +; https://docs.platformio.org/en/latest/projectconf/sections/env/options/build/build_src_flags.html +; https://docs.platformio.org/en/latest/projectconf/sections/env/options/build/build_flags.html +build_src_flags = + ${common.build_src_flags} + + ; todo: enable when issues disappear + ; * There is quite a few in `ArduinoFake` lib. + ; * `ArduinoFake` is a library, not package -> so `custom_system_packages` does not help. + ; * PIO apparently applies these flags to dependencies as well… :/ + ; https://github.com/platformio/platformio-core/issues/4667 + ; * Instead of enabling exactly here, I could just reuse `native` config, ofc. + ;-Wpedantic + ; https://docs.platformio.org/en/latest/projectconf/section_env_test.html#test-filter test_filter = ${env:native.test_filter} diff --git a/config/nodemcu.ini b/config/nodemcu.ini index 3ab6659..31a8b40 100644 --- a/config/nodemcu.ini +++ b/config/nodemcu.ini @@ -92,6 +92,8 @@ build_flags = build_src_flags = ${common.build_src_flags} + -Wpedantic + ; https://docs.platformio.org/en/latest/projectconf/section_env_library.html#lib-deps lib_deps = ${common.lib_deps} @@ -124,3 +126,15 @@ test_filter = embedded/* ; https://docs.platformio.org/en/latest/scripting/actions.html extra_scripts = post:scripts/pio_post_extra_script.py + +custom_system_packages = + ; Silencing warnings from the (framework) dependencies. + ; + ; Without it, there is a lot of issues, like: + ; .platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src/ + ; WiFiServerSecureBearSSL.h:88:2: + ; warning: extra ';' [-Wpedantic] + ; 88 | }; + ; | ^ + ; todo: report/fix the issues in the framework + framework-arduinoespressif8266 diff --git a/scripts/pio_extra_script_helper.py b/scripts/pio_extra_script_helper.py new file mode 100644 index 0000000..f549106 --- /dev/null +++ b/scripts/pio_extra_script_helper.py @@ -0,0 +1,117 @@ +from SCons.Script.SConscript import SConsEnvironment +from pathlib import Path +from platformio.platform.base import PlatformBase +from utils import partition + + +class PackageNotAvailableError(ValueError): + pass + + +class Helper: + def __init__(self, script_globals: dict): + """ + :param script_globals: Pass in `globals()` and let the magic do its job… + """ + + # global env + self.default_env: SConsEnvironment = script_globals['DefaultEnvironment']() + + # project env + self.default_env.Import('projenv') + self.projenv: SConsEnvironment = script_globals['projenv'] + + # current working env + self.default_env.Import('env') + self.env: SConsEnvironment = script_globals['env'] + + self.envs = [ + self.default_env, + self.projenv, + self.env, + ] + + def get_config_value(self, name: str, default: str = ''): + return self.env.GetProjectOption(name, default=default) + + def get_platform(self) -> PlatformBase: + """ + The platform is the same for all the envs. + """ + return self.env.PioPlatform() + + def list_available_packages(self) -> list: + return [ + package.metadata.name + for package + in self.get_platform().get_installed_packages() + ] + + def list_used_packages(self) -> list: + return [ + package['name'] + for package + in self.get_platform().dump_used_packages() + ] + + def mark_packages_as_system(self, packages: list[str]) -> None: + """ + See :meth:`~pio_extra_script_helper.Helper.mark_package_as_system` + """ + for package in packages: + self.mark_package_as_system(package) + + def mark_package_as_system(self, package: str) -> None: + """ + Adds `-isystem` flag to the specified package. + + As the result, most of the warnings – for this package – will be silenced. + + https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html + https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Options-for-Directory-Search + + Inspiration: + https://community.platformio.org/t/silence-warnings-for-dependencies-external-libraries/33387/8 + """ + + try: + package_to_mark_as_system_path: Path = self.get_path_of_package(package) + except PackageNotAvailableError as e: + raise PackageNotAvailableError( + f'Could not mark the package "{package}" as system – it is not available. ' + f'See :meth:`~pio_extra_script_helper.Helper.list_available_packages`' + ) from e + + for env in self.envs: + system_paths, not_system_paths = partition( + lambda path_from_env: package_to_mark_as_system_path in Path(path_from_env).parents, + env['CPPPATH'] + ) + + # `CPPPATH` – paths containing both `C` and `C++` files + # https://scons.org/doc/4.5.2/HTML/scons-user/apa.html#cv-CPPPATH + env.Replace(CPPPATH=not_system_paths) + + # `CCFLAGS` – options for both C and C++ compilers + # https://scons.org/doc/4.5.2/HTML/scons-user/apa.html#cv-CCFLAGS + # + # Not using `CXXFLAGS` as the `CPPPATH` apparently contains files for both `C` and `C++`: + # https://community.platformio.org/t/silence-warnings-for-dependencies-external-libraries/33387/11 + env.Append(CCFLAGS=[ + ('-isystem', system_path) + for system_path + in system_paths + ]) + + def get_path_of_package(self, package: str) -> Path: + platform: PlatformBase = self.get_platform() + + try: + package_dir: str = platform.get_package_dir(package) + except KeyError as e: + raise PackageNotAvailableError( + f'Could not get path of the package "{package}" – it is not available. ' + f'See :meth:`~pio_extra_script_helper.Helper.list_available_packages`' + ) from e + + return Path(package_dir) diff --git a/scripts/pio_post_extra_script.py b/scripts/pio_post_extra_script.py index 0d65b43..c047e6d 100644 --- a/scripts/pio_post_extra_script.py +++ b/scripts/pio_post_extra_script.py @@ -3,7 +3,9 @@ # https://docs.platformio.org/en/latest/projectconf/sections/env/options/advanced/extra_scripts.html # https://docs.platformio.org/en/latest/scripting/actions.html -Import("env") +from pio_extra_script_helper import Helper + +helper = Helper(globals()) # Silencing `volatile` warnings # @@ -39,4 +41,13 @@ # Using `env` as it applies to everything, including the external libraries, # while `projenv` would apply only to _my_ code, # https://github.com/platformio/platformio-core/issues/1728#issuecomment-403297776 -env.Append(CXXFLAGS=["-Wno-volatile"]) +helper.env.Append(CXXFLAGS=['-Wno-volatile']) + +helper.mark_packages_as_system([ + package + for package + # todo: why it returns string instead of a list? + # for example `build_src_flags` returns a list… + in helper.get_config_value('custom_system_packages').split('\n') + if package != '' +]) diff --git a/scripts/utils.py b/scripts/utils.py new file mode 100644 index 0000000..4617eb4 --- /dev/null +++ b/scripts/utils.py @@ -0,0 +1,14 @@ +def partition(predicate, iterable): + """ + https://stackoverflow.com/a/4578605/666907 + """ + trues = [] + falses = [] + + for item in iterable: + if predicate(item): + trues.append(item) + else: + falses.append(item) + + return trues, falses