Skip to content

Each C module's sources come from its own directory - #124

Merged
bdbarnett merged 3 commits into
mainfrom
wrapup/vpath
Oct 19, 2026
Merged

bdbarnett merged 3 commits into
mainfrom
wrapup/vpath

Conversation

@bdbarnett

Copy link
Copy Markdown
Contributor

If you build with C modules from more than one place (say a module of your own, or one linked in from a checkout beside this repository), make could compile a file from the wrong directory without saying so. The make ports (unix, windows, webassembly) find a module's sources by searching the parent directory of every module in the build, in sorted order. If one of those parents also held a directory with the same name as one of the modules (an older checkout of it, for example), its copy of the file was the one compiled, linked against the module's current headers and other files. CMake ports (esp32, rp2) name sources by absolute path and were never affected.

After this change, each module's own directory is searched first, and build_mp.py checks every build: if any module's object was still compiled from somewhere else, it stops and names the file. A build directory made before the fix gets those objects compiled again automatically, so you don't need --clean.

What changed:

  • patches/micropython/0040 gives each user C module its own vpath directive in py/py.mk, ahead of the shared search list. A build whose modules all sit in one directory resolves exactly as it did before. audioif's own vpath line did the same for audioif alone, and it's gone now.
  • build_mp.py reads each object's dependency file after a make build and refuses one compiled from outside the build's modules. Before make runs, it drops objects that an older build compiled from a stray copy.
  • patches/apply_patches.py: preparing a checkout again after the overlay changes was refused once micropython-lib carried our patches, because git status --porcelain reports a submodule with local edits as " M", not the " m" the check looked for. git now leaves those submodules out itself.
  • test_build_mp.py tests the build check, and asks the unix port's Makefile where it finds a module's source when a stray copy sits beside another module. A new job in build-mp.yml prepares MicroPython at the pin so that test runs in CI instead of skipping.

How it was checked: the test fails on the overlay without 0040 (make picks the stray copy) and passes with it. A build with a stray displayif/ holding an #error, placed beside a stub module, failed on that file before the patch and builds after it. A full unix build with every module is green, and so is ESP32_GENERIC_S3.

make ports name a user C module's sources <module>/<file>.c and find them
through vpath, in the parent directory of every module, sorted. A module
linked in from elsewhere puts that elsewhere on the list, and when it also
holds a directory of the module's name (an older checkout of it), that
copy was compiled instead, silently. In a workspace with audiodsp beside
this repository, displayif's three unix objects came from an old
standalone displayif checkout.

The patch gives each module a vpath directive of its own, ahead of the
shared one. audioif's own vpath line, which did the same for audioif
alone, comes out.
…gain

prepare() meant to ignore a submodule with edits inside it by matching
" m" in git status, but --porcelain spells that " M", so a tree whose
overlay had changed was refused once micropython-lib carried our patches.
git now leaves those submodules out itself (--ignore-submodules=dirty); a
submodule moved to another commit still counts.
…ules

After a make build, each object's dependency file says which source the
compiler was handed; a module's object found under a directory that is
none of the build's modules stops the build, naming it. Before make runs,
objects a build made before overlay 0040 compiled from a stray copy are
dropped, so an existing build dir is compiled again from the modules
instead of being refused.

test_build_mp.py checks that, and asks the unix port's Makefile where it
finds a module's source with a stray copy beside another module; a new CI
job prepares MicroPython at the pin so that test runs there rather than
skipping.
@bdbarnett
bdbarnett merged commit 569873c into main Oct 19, 2026
16 checks passed
@bdbarnett
bdbarnett deleted the wrapup/vpath branch October 19, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant