From 1abf8ddb306c498727030be54ac2db2e7e10e9fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Nov 2025 13:28:58 -0600 Subject: [PATCH 01/11] Update meshtastic/device-ui digest to 3bf3322 (#8814) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 1363a63fc..5b9d965ef 100644 --- a/platformio.ini +++ b/platformio.ini @@ -121,7 +121,7 @@ lib_deps = [device-ui_base] lib_deps = # renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master - https://github.com/meshtastic/device-ui/archive/28167c67dfd13015a0b5eef1828f95fe8e3ab7c3.zip + https://github.com/meshtastic/device-ui/archive/3bf332240416c5cb8c919fac2a0ec7260eb3be75.zip ; Common libs for environmental measurements in telemetry module [environmental_base] From 80e8745714663125e9cd7de8dd98c9d5cbc54787 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 06:14:46 -0600 Subject: [PATCH 02/11] Update XPowersLib to v0.3.2 (#8823) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- arch/esp32/esp32.ini | 2 +- arch/esp32/esp32c6.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index 810c9780e..08a547ca6 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -57,7 +57,7 @@ lib_deps = # renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip # renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib - https://github.com/lewisxhe/XPowersLib/archive/v0.3.1.zip + https://github.com/lewisxhe/XPowersLib/archive/v0.3.2.zip # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini index 7b06f4cd8..b07a2dcd4 100644 --- a/arch/esp32/esp32c6.ini +++ b/arch/esp32/esp32c6.ini @@ -28,7 +28,7 @@ lib_deps = ${environmental_extra.lib_deps} ${radiolib_base.lib_deps} # renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib - lewisxhe/XPowersLib@0.3.1 + lewisxhe/XPowersLib@0.3.2 # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto From eba6e4ed752df1457093f104a0279693b6f1af33 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 06:16:52 -0600 Subject: [PATCH 03/11] Upgrade trunk (#8822) Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com> --- .trunk/trunk.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 16bae762e..342d9d4a2 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -9,14 +9,14 @@ plugins: lint: enabled: - checkov@3.2.495 - - renovate@42.26.3 - - prettier@3.7.1 + - renovate@42.27.1 + - prettier@3.7.3 - trufflehog@3.91.1 - yamllint@1.37.1 - bandit@1.9.2 - trivy@0.67.2 - taplo@0.10.0 - - ruff@0.14.6 + - ruff@0.14.7 - isort@7.0.0 - markdownlint@0.46.0 - oxipng@9.1.5 From 0e653056e7661a11acb30faf63e6dee5e27f10e7 Mon Sep 17 00:00:00 2001 From: Austin Date: Mon, 1 Dec 2025 09:00:10 -0500 Subject: [PATCH 04/11] RPM: Fix broken builds (bad backmerge) (#8787) Co-authored-by: Ben Meadors --- meshtasticd.spec.rpkg | 1 - 1 file changed, 1 deletion(-) diff --git a/meshtasticd.spec.rpkg b/meshtasticd.spec.rpkg index b9152c4a3..e2da172c3 100644 --- a/meshtasticd.spec.rpkg +++ b/meshtasticd.spec.rpkg @@ -33,7 +33,6 @@ BuildRequires: python3dist(grpcio[protobuf]) BuildRequires: python3dist(grpcio-tools) BuildRequires: git-core BuildRequires: gcc-c++ -BuildRequires: (glibc-devel >= 2.38) or pkgconfig(libbsd-overlay) BuildRequires: pkgconfig(yaml-cpp) BuildRequires: pkgconfig(libgpiod) BuildRequires: pkgconfig(bluez) From a3d3e1c912694394f428937fd6e44e85c65d02d3 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 1 Dec 2025 15:34:05 -0600 Subject: [PATCH 05/11] =?UTF-8?q?Flags=20and=20scripts=20for=20size=20redu?= =?UTF-8?q?ction=20on=20NRF52=20->=20Currently=20targeting=20=E2=80=A6=20(?= =?UTF-8?q?#8825)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Flags and scripts for size reduction on NRF52 -> Currently targeting rak4631 * Changes from the other branch poluted it * Remove the stripper * No strip --- bin/analyze_map.py | 165 +++++++++++++++++++++++ variants/nrf52840/rak4631/platformio.ini | 21 ++- 2 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 bin/analyze_map.py diff --git a/bin/analyze_map.py b/bin/analyze_map.py new file mode 100644 index 000000000..99997c703 --- /dev/null +++ b/bin/analyze_map.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +"""Summarise linker map output to highlight heavy object files and libraries. + +Usage: + python bin/analyze_map.py --map .pio/build/rak4631/output.map --top 20 + +The script parses GNU ld map files and aggregates section sizes per object file +and per archive/library, then prints sortable tables that make it easy to spot +modules worth trimming or hiding behind feature flags. +""" +from __future__ import annotations + +import argparse +import collections +import os +import re +import sys +from typing import DefaultDict, Dict, Tuple + + +SECTION_LINE_RE = re.compile(r"^\s+(?P
\S+)\s+0x[0-9A-Fa-f]+\s+0x(?P[0-9A-Fa-f]+)\s+(?P.+)$") +ARCHIVE_MEMBER_RE = re.compile(r"^(?P.+)\((?P[^)]+)\)$") + + +def human_size(num_bytes: int) -> str: + """Return a friendly size string with one decimal place.""" + if num_bytes < 1024: + return f"{num_bytes:,} B" + num = float(num_bytes) + for unit in ("KB", "MB", "GB"): + num /= 1024.0 + if num < 1024.0: + return f"{num:.1f} {unit}" + return f"{num:.1f} TB" + + +def shorten_path(path: str, root: str) -> str: + """Prefer repository-relative paths for readability.""" + path = path.strip() + if not path: + return path + + # Normalise Windows archives (backslashes) to POSIX style for consistency. + path = path.replace("\\", "/") + + # Attempt to strip the root when an absolute path lives inside the repo. + if os.path.isabs(path): + try: + rel = os.path.relpath(path, root) + if not rel.startswith(".."): + return rel + except ValueError: + # relpath can fail on mixed drives on Windows; fall back to basename. + pass + return path + + +def describe_object(raw_object: str, root: str) -> Tuple[str, str]: + """Return a human friendly object label and the library it belongs to.""" + raw_object = raw_object.strip() + lib_label = "[app]" + match = ARCHIVE_MEMBER_RE.match(raw_object) + if match: + archive = shorten_path(match.group("archive"), root) + obj = match.group("object") + lib_label = os.path.basename(archive) or archive + label = f"{archive}:{obj}" + else: + label = shorten_path(raw_object, root) + # If the object lives under libs, hint at the containing directory. + parent = os.path.basename(os.path.dirname(label)) + if parent: + lib_label = parent + return label, lib_label + + +def parse_map(map_path: str, repo_root: str) -> Tuple[Dict[str, int], Dict[str, int], Dict[str, Dict[str, int]]]: + per_object: DefaultDict[str, int] = collections.defaultdict(int) + per_library: DefaultDict[str, int] = collections.defaultdict(int) + per_object_sections: DefaultDict[str, DefaultDict[str, int]] = collections.defaultdict(lambda: collections.defaultdict(int)) + + try: + with open(map_path, "r", encoding="utf-8", errors="ignore") as handle: + for line in handle: + match = SECTION_LINE_RE.match(line) + if not match: + continue + + section = match.group("section") + if section.startswith("*") or section in {"LOAD", "ORIGIN"}: + continue + + size = int(match.group("size"), 16) + if size == 0: + continue + + obj_token = match.group("object").strip() + if not obj_token or obj_token.startswith("*") or "load address" in obj_token: + continue + + label, lib_label = describe_object(obj_token, repo_root) + per_object[label] += size + per_library[lib_label] += size + per_object_sections[label][section] += size + except FileNotFoundError: + raise SystemExit(f"error: map file '{map_path}' not found. Run a build first.") + + return per_object, per_library, per_object_sections + + +def format_section_breakdown(section_sizes: Dict[str, int], total: int, limit: int = 3) -> str: + items = sorted(section_sizes.items(), key=lambda kv: kv[1], reverse=True) + parts = [] + for section, size in items[:limit]: + pct = (size / total) * 100 if total else 0 + parts.append(f"{section} {pct:.1f}%") + if len(items) > limit: + remainder = total - sum(size for _, size in items[:limit]) + pct = (remainder / total) * 100 if total else 0 + parts.append(f"other {pct:.1f}%") + return ", ".join(parts) + + +def print_report(map_path: str, top_n: int, per_object: Dict[str, int], per_library: Dict[str, int], per_object_sections: Dict[str, Dict[str, int]]): + total_bytes = sum(per_object.values()) + if total_bytes == 0: + print("No section data found in map file.") + return + + print(f"Map file: {map_path}") + print(f"Accounted size: {human_size(total_bytes)} across {len(per_object)} object files\n") + + sorted_objects = sorted(per_object.items(), key=lambda kv: kv[1], reverse=True) + print(f"Top {min(top_n, len(sorted_objects))} object files by linked size:") + for idx, (obj, size) in enumerate(sorted_objects[:top_n], 1): + pct = (size / total_bytes) * 100 + breakdown = format_section_breakdown(per_object_sections[obj], size) + print(f"{idx:2}. {human_size(size):>9} ({size:,} B, {pct:5.2f}% of linked size)") + print(f" {obj}") + if breakdown: + print(f" sections: {breakdown}") + print() + + sorted_libs = sorted(per_library.items(), key=lambda kv: kv[1], reverse=True) + print(f"Top {min(top_n, len(sorted_libs))} libraries or source roots:") + for idx, (lib, size) in enumerate(sorted_libs[:top_n], 1): + pct = (size / total_bytes) * 100 + print(f"{idx:2}. {human_size(size):>9} ({size:,} B, {pct:5.2f}% of linked size) {lib}") + + +def main() -> None: + parser = argparse.ArgumentParser(description="Highlight heavy object files from a GNU ld map file.") + parser.add_argument("--map", default=".pio/build/rak4631/output.map", help="Path to the map file (default: %(default)s)") + parser.add_argument("--top", type=int, default=20, help="Number of entries to display per table (default: %(default)s)") + args = parser.parse_args() + + map_path = os.path.abspath(args.map) + repo_root = os.path.abspath(os.getcwd()) + + per_object, per_library, per_object_sections = parse_map(map_path, repo_root) + print_report(os.path.relpath(map_path, repo_root), args.top, per_object, per_library, per_object_sections) + + +if __name__ == "__main__": + main() diff --git a/variants/nrf52840/rak4631/platformio.ini b/variants/nrf52840/rak4631/platformio.ini index 205966529..c95d477f9 100644 --- a/variants/nrf52840/rak4631/platformio.ini +++ b/variants/nrf52840/rak4631/platformio.ini @@ -4,16 +4,33 @@ extends = nrf52840_base board = wiscore_rak4631 board_level = pr board_check = true +build_type = release build_flags = ${nrf52840_base.build_flags} -I variants/nrf52840/rak4631 -D RAK_4631 -DEINK_DISPLAY_MODEL=GxEPD2_213_BN -DEINK_WIDTH=250 - -DEINK_HEIGHT=122 + -DEINK_HEIGHT=122 -DRADIOLIB_EXCLUDE_SX128X=1 -DRADIOLIB_EXCLUDE_SX127X=1 -DRADIOLIB_EXCLUDE_LR11X0=1 -build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/rak4631> + + + + -Os + -Wl,-Map=$BUILD_DIR/output.map +build_unflags = + -Ofast + -Og + -ggdb3 + -ggdb2 + -g3 + -g2 + -g + -g1 + -g0 +build_src_filter = ${nrf52_base.build_src_filter} \ + +<../variants/nrf52840/rak4631> \ + + \ + + \ + + lib_deps = ${nrf52840_base.lib_deps} ${nrf52_networking_base.lib_deps} From 8a437415894db7c186a90cdd0b149cbd8c2dc9ee Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 2 Dec 2025 05:48:19 -0600 Subject: [PATCH 06/11] Add 'cleanup' to required PR labels (#8835) --- .github/workflows/pr_enforce_labels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_enforce_labels.yml b/.github/workflows/pr_enforce_labels.yml index 543e23558..d60c9c8ca 100644 --- a/.github/workflows/pr_enforce_labels.yml +++ b/.github/workflows/pr_enforce_labels.yml @@ -17,7 +17,7 @@ jobs: with: script: | const labels = context.payload.pull_request.labels.map(label => label.name); - const requiredLabels = ['bugfix', 'enhancement', 'hardware-support', 'dependencies', 'submodules', 'github_actions', 'trunk']; + const requiredLabels = ['bugfix', 'enhancement', 'hardware-support', 'dependencies', 'submodules', 'github_actions', 'trunk', 'cleanup']; const hasRequiredLabel = labels.some(label => requiredLabels.includes(label)); if (!hasRequiredLabel) { core.setFailed(`PR must have at least one of the following labels before it can be merged: ${requiredLabels.join(', ')}.`); From 90584359e49e37c99b6132d95a0d5f87030c45a1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 05:48:36 -0600 Subject: [PATCH 07/11] Upgrade trunk (#8836) Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com> --- .trunk/trunk.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 342d9d4a2..d8fad73c6 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -9,7 +9,7 @@ plugins: lint: enabled: - checkov@3.2.495 - - renovate@42.27.1 + - renovate@42.29.4 - prettier@3.7.3 - trufflehog@3.91.1 - yamllint@1.37.1 From 0828c445fba9d7d287809bb3c52eac523a9e54fe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 05:39:31 -0600 Subject: [PATCH 08/11] Update actions/stale action to v10.1.1 (#8848) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/stale_bot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale_bot.yml b/.github/workflows/stale_bot.yml index 11ba59386..fc0702bd8 100644 --- a/.github/workflows/stale_bot.yml +++ b/.github/workflows/stale_bot.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Stale PR+Issues - uses: actions/stale@v10.1.0 + uses: actions/stale@v10.1.1 with: days-before-stale: 45 stale-issue-message: This issue has not had any comment or update in the last month. If it is still relevant, please post update comments. If no comments are made, this issue will be closed automagically in 7 days. From 1b4925bd07b52d3085c56b88831f9d9068fc1b37 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 07:50:50 -0600 Subject: [PATCH 09/11] Upgrade trunk (#8849) Co-authored-by: vidplace7 <1779290+vidplace7@users.noreply.github.com> --- .trunk/trunk.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index d8fad73c6..95e5b0dd2 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -9,9 +9,9 @@ plugins: lint: enabled: - checkov@3.2.495 - - renovate@42.29.4 - - prettier@3.7.3 - - trufflehog@3.91.1 + - renovate@42.30.4 + - prettier@3.7.4 + - trufflehog@3.91.2 - yamllint@1.37.1 - bandit@1.9.2 - trivy@0.67.2 From 3f4091622387ee64a08d0cce6ff5c393e713dda1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Dec 2025 15:30:09 -0600 Subject: [PATCH 10/11] Update alpine Docker tag to v3.23 (#8853) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- alpine.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alpine.Dockerfile b/alpine.Dockerfile index bdee57d79..b3b384101 100644 --- a/alpine.Dockerfile +++ b/alpine.Dockerfile @@ -28,7 +28,7 @@ RUN bash ./bin/build-native.sh "$PIO_ENV" && \ # ##### PRODUCTION BUILD ############# -FROM alpine:3.22 +FROM alpine:3.23 LABEL org.opencontainers.image.title="Meshtastic" \ org.opencontainers.image.description="Alpine Meshtastic daemon" \ org.opencontainers.image.url="https://meshtastic.org" \ From 6e9fd189b457434f6bbba9ba21469e58a9f429c6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 15:33:19 -0600 Subject: [PATCH 11/11] Update meshtastic/device-ui digest to 4fb5f24 (#8862) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 5b9d965ef..f560bd8f5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -121,7 +121,7 @@ lib_deps = [device-ui_base] lib_deps = # renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master - https://github.com/meshtastic/device-ui/archive/3bf332240416c5cb8c919fac2a0ec7260eb3be75.zip + https://github.com/meshtastic/device-ui/archive/4fb5f24787caa841b58dbf623a52c4c5861d6722.zip ; Common libs for environmental measurements in telemetry module [environmental_base]