Skip to content

Commit

Permalink
Fix usermod libArchive setting
Browse files Browse the repository at this point in the history
Monkey-patch PlatformIO to intercept the build process after library
dependencies are loaded, but before the build is fully analyzed.  This
lets us enforce libArchive=False for usermods without making that
setting global across all libraries.

The rest of the fixup code is integrated at the same call site for
simplicity.
  • Loading branch information
willmmiles committed Jan 14, 2025
1 parent 869e275 commit 0b8721c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 25 deletions.
17 changes: 0 additions & 17 deletions pio-scripts/fixup_usermods.py

This file was deleted.

44 changes: 37 additions & 7 deletions pio-scripts/load_usermods.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
Import('env')
import os
from pathlib import Path # For OS-agnostic path manipulation

def find_usermod(mod_dir: str, mod: str):
usermod_dir = Path(env["PROJECT_DIR"]) / "usermods"

def find_usermod(mod: str):
"""Locate this library in the usermods folder.
We do this to avoid needing to rename a bunch of folders;
this could be removed later
"""
# Check name match
mp = f"{mod_dir}/{mod}"
if os.path.exists(mp):
mp = usermod_dir / mod
if mp.exists():
return mp
mp = f"{mod_dir}/usermod_v2_{mod}"
if os.path.exists(mp):
mp = usermod_dir / f"usermod_v2_{mod}"
if mp.exists():
return mp
raise RuntimeError(f"Couldn't locate module {mod} in usermods directory!")

Expand All @@ -21,6 +23,34 @@ def find_usermod(mod_dir: str, mod: str):
deps = env.GetProjectOption('lib_deps')
src_dir = proj.get("platformio", "src_dir")
src_dir = src_dir.replace('\\','/')
mod_paths = {mod: find_usermod(f"{src_dir}/../usermods", mod) for mod in usermods.split(" ")}
mod_paths = {mod: find_usermod(mod) for mod in usermods.split(" ")}
usermods = [f"{mod} = symlink://{path}" for mod, path in mod_paths.items()]
proj.set("env:" + env['PIOENV'], 'lib_deps', deps + usermods)


# Monkey-patch ConfigureProjectLibBuilder to mark up the dependencies
# Save the old value
cpl = env.ConfigureProjectLibBuilder
# Our new wrapper
def cpl_wrapper(env):
result = cpl.clone(env)()
# Update usermod properties
lib_builders = env.GetLibBuilders()
um_deps = [dep for dep in lib_builders if usermod_dir in Path(dep.src_dir).parents]
other_deps = [dep for dep in lib_builders if usermod_dir not in Path(dep.src_dir).parents]
for um in um_deps:
# Add include paths for all non-usermod dependencies
for dep in other_deps:
for dir in dep.get_include_dirs():
um.env.PrependUnique(CPPPATH=dir)
# Add the wled folder to the include path
um.env.PrependUnique(CPPPATH=env["PROJECT_SRC_DIR"])
# Make sure we link directly, not through an archive
# Archives drop the .dtor table section we need
build = um._manifest.get("build", {})
build["libArchive"] = False
um._manifest["build"] = build
return result

# Replace the old one with ours
env.AddMethod(cpl_wrapper, "ConfigureProjectLibBuilder")
1 change: 0 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ extra_scripts =
post:pio-scripts/strip-floats.py
pre:pio-scripts/user_config_copy.py
pre:pio-scripts/load_usermods.py
post:pio-scripts/fixup_usermods.py
pre:pio-scripts/build_ui.py
; post:pio-scripts/obj-dump.py ;; convenience script to create a disassembly dump of the firmware (hardcore debugging)

Expand Down

0 comments on commit 0b8721c

Please sign in to comment.