Skip to content

package_core: deduplicate llext-edk headers in core packages - #694

Merged
pennam merged 6 commits into
arduino:mainfrom
pillo79:pr-merge-dirs
Oct 20, 2026
Merged

pennam merged 6 commits into
arduino:mainfrom
pillo79:pr-merge-dirs

Conversation

@pillo79

@pillo79 pillo79 commented Oct 13, 2026

Copy link
Copy Markdown

Every board variant ships its own llext-edk/include tree, and most of those headers are byte-identical across boards. This PR moves the shared headers into a single variants/include directory when packaging in CI, which makes each core package much smaller.

Changes

  • extra/dedupe_includes.py (new): takes two or more variant names and finds the files that are byte-identical at the same path in every variant's llext-edk/include. It moves one copy of each to variants/<common-dir> and deletes the duplicates. Each variant's includes.txt is updated to match:

    • an include directory that ends up empty is repointed to the common directory and removed;
    • an include directory that keeps some files gets an extra entry for the common directory, after the original, so the variant's own headers are still found first.

    --dry-run only reports what would be done.

  • extra/package_core.sh: runs the dedup on the included variants that have an EDK, then adds variants/include/ to the archive. It is skipped if fewer than 2 such variants are left. It only runs when GITHUB_ACTIONS is set, because it changes the working tree in place (each packaging job starts from a fresh checkout).

  • platform.txt: the -imacros files (zephyr/autoconf.h, zephyr/toolchain/zephyr_stdint.h) are now found through the include path instead of a fixed {build.variant.path}/llext-edk/... path. zephyr_stdint.h is the same on every board, so it gets moved. Every variant's includes.txt already has the right directories, so this works whether or not the headers were deduplicated.

Results (zephyr_unoq, 2 boards)

  • 2926 of about 3080 headers are shared, which removes about 24.8 MB of uncompressed duplicates.
  • Packaged archive: 10.6 MB.

Testing

  • Packaged zephyr_unoq with GITHUB_ACTIONS=1 and checked that every -iwithprefixbefore path in the unpacked package resolves.
  • Compiled a test sketch (Wire, SPI, GPIO) for UNO Q and Ventuno Q with both the deduplicated package and the normal working tree. The outputs are byte-identical, and the dependency files show autoconf.h coming from each variant's own directory.
  • Checked that a local run (no GITHUB_ACTIONS) leaves the working tree untouched.
  • Not tested: zephyr_main and zephyr_contrib packages, and boards other than the two Q boards.

pillo79 and others added 4 commits October 13, 2026 17:24
Finds files identical across a set of directories and mirrors one
canonical copy out, deleting the duplicates from the source dirs.
Useful for the generated llext-edk headers duplicated across board
variants.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
When applying (not --dry-run), repoint each affected -iwithprefixbefore
entry in a variant's includes.txt at the mirrored common directory:
fully-emptied entries get replaced (and their now-empty directory
removed from disk), partially-emptied entries get an extra entry
pointing at the common directory alongside the original.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Arguments are now variant names (a leading 'variants/' is ignored),
resolved to variants/<name>/llext-edk/include. --common-dir is also
a variant name, created at variants/<name>. Each variant's includes.txt
is always updated, replacing the old "variants/<board>/" path detection.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
When packaging in CI, move the llext-edk headers shared by all the
included variants into a 'variants/include' directory via
dedupe_includes.py, and add it to the archive. Only variants that
actually have an EDK are considered, and the step is skipped when
fewer than 2 remain.

This modifies the working tree, so it only runs when GITHUB_ACTIONS
is set (each packaging job uses a fresh checkout).

Since headers may now live outside the variant directory, platform.txt
looks up the -imacros files (autoconf.h and zephyr_stdint.h) via the
include path instead of a variant-relative path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@pillo79 pillo79 changed the title Deduplicate llext-edk headers in core packages package_core: deduplicate llext-edk headers in core packages Oct 13, 2026
@github-actions

Copy link
Copy Markdown

Built 1.0.1-0.pr.694.261013t1532z+gd1565126

CI run PASSED 🟢

ArtifactBoardCoreTestsRAMSketchesWarningsErrors
✅ zephyr_contrib ek_ra8d1 1 🏷️ ✅

12.0%

2--
frdm_mcxn947 7 🏷️ ✅

53.4%

2--
frdm_rw612 3 🏷️ ✅

76.5%

2--
✅* zephyr_main giga 10 🏷️ ✅*

45.9%

862-
nano33ble 6 🏷️ ✅

78.8%

44--
nano_connect 5 🏷️ ✅*

68.9%

386-
nano_matter 4 🏷️ ✅

⚠️ 86.5%

22--
nicla_sense 4 🏷️ ✅

⚠️ 88.5%

18--
nicla_vision 11 🏷️ ✅

40.3%

68--
opta 11 🏷️ ✅

42.3%

76--
portentac33 6 🏷️ ✅

⚠️ 100.0%

72--
portentah7 10 🏷️ ✅*

51.2%

1028-
✅ zephyr_unoq unoq 2 🏷️ ✅

43.5%

56--
ventunoq 5 🏷️ ✅

23.7%

48--
Legend

BoardTestStatus description
🔥 🔥 Test run failed to complete.
❌ 🔴 Test completed with unexpected errors.
⁉️ ⁉️ Test was expected to fail but passed; exception entry is outdated.
✔️* 🚫 Test completed with errors, but all are known/expected.
✅* 🟡 Test completed with some warnings; no errors detected.
✅ 🟢 Test passed successfully, with no warnings or errors.
🌑 🌑 Test was skipped.

pennam and others added 2 commits October 16, 2026 13:53
Entries like '.../loader/ota/../../libraries/OTA/src' or
'.../kernel_service/thread/../' were not normalized, since pathlib keeps
'..' components. They never matched the deduplicated files, so no entry
for the common directory was added and headers such as ota.h and
kernel_shell.h could no longer be found (e.g. in zephyr_contrib).

Normalizing the entries also makes the deepest-first sort use the real
directory depth.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The sync-zephyr-artifacts tool copies the deduplicated 'variants/include'
folder from the downloaded core into the working tree:
- ignore it in git, so it is not committed by mistake;
- remove it in the sync tool before copying, so stale headers from a
  previous sync do not stay reachable through includes.txt;
- add it to the archive in package_core.sh whenever it exists, so local
  packages built from a synced tree are not missing headers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

Built 1.0.1-0.pr.694.261016t1253z+g68223d14

CI run PASSED 🟢

ArtifactBoardCoreTestsRAMSketchesWarningsErrors
✅ zephyr_contrib ek_ra8d1 1 🏷️ ✅

12.0%

2--
frdm_mcxn947 7 🏷️ ✅

53.4%

2--
frdm_rw612 3 🏷️ ✅

76.5%

2--
✅* zephyr_main giga 10 🏷️ ✅*

45.9%

862-
nano33ble 6 🏷️ ✅

78.8%

44--
nano_connect 5 🏷️ ✅

68.9%

38--
nano_matter 4 🏷️ ✅

⚠️ 86.5%

22--
nicla_sense 4 🏷️ ✅

⚠️ 88.5%

18--
nicla_vision 11 🏷️ ✅

40.4%

68--
opta 11 🏷️ ✅

42.3%

76--
portentac33 6 🏷️ ✅

⚠️ 100.0%

72--
portentah7 10 🏷️ ✅*

51.2%

1022-
✅ zephyr_unoq unoq 2 🏷️ ✅

43.5%

56--
ventunoq 5 🏷️ ✅

23.7%

48--
Legend

BoardTestStatus description
🔥 🔥 Test run failed to complete.
❌ 🔴 Test completed with unexpected errors.
⁉️ ⁉️ Test was expected to fail but passed; exception entry is outdated.
✔️* 🚫 Test completed with errors, but all are known/expected.
✅* 🟡 Test completed with some warnings; no errors detected.
✅ 🟢 Test passed successfully, with no warnings or errors.
🌑 🌑 Test was skipped.

@pennam
pennam merged commit e377350 into arduino:main Oct 20, 2026
68 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants