Almost always rebuilds everything

TLDR; Details of my findings when PlatformIO goes in to “rebuild everything almost always”-mode…

Version: pio --version 6.1.4 (but has been present since quite a while).
Running: pio run -t upload -e myenv
Problem: Rebuilds everything regardless if source has changed or not…

This seems to be a fairly uncommon problem but when it starts (from what I’ve read and seen) it sticks.

My team has this problem on several projects but not all projects and not all the time.
These findings are based on clean environment, where the .pio folder was removed, Linux/Windows tested.

NOTE: Rebuild everything refers to everything outside the platformio/packages directories - that seems to rebuild as expected…

  1. First time, obviously rebuilds everything
  2. Second time, some projects just go through without rebuilding others rebuild

Projects that don’t rebuild will rebuild later - even if not touched. Taking a coffee break will basically trigger a rebuild.

To verify this a clean project (in VS Code) was set up.
This clean project has a dependency on an internal project with a custom pre_build script which filters the source-folders depending on custom options in platformio.ini (could be important - no clue).

Anyway, building this clean project twice directly (no delay in between builds) works as expected.
First is a full build, second just goes through without building any files.

Ways to trigger rebuild:

  1. Take a break
    Take a break from the computer (20-60min) - sit down. Run the build again: full rebuild…
    Note: I’ve tested 5min, 10min, 15min, 20min… 20min was the cut-off for me (i.e. when it started running full builds).

  2. Build another project
    Once a project is built. Build another then go back and rebuild - this will trigger a full rebuild on the first project. Without being touched.

NOTE: This is not 100% consistent between projects - several projects do behave as expected.

I have several (simple) projects with exactly the same dependencies behaving differently.
One project recompiles everything all the time.
The other project recompiles everything when there is a longer break in between runs.

Ini files for both projects are identical for all…

It seems two things trigger rebuilds

  1. Time, for whatever reason if the time between builds are “too” long, it rebuilds
  2. Global State, interchanging projects when building seems to trigger rebuild

Could you provide a simple project to reproduce this issue?

A simple project - no. I don’t see this issue on any simple project.

Having looked through it a bit more. It seems related to project dependencies (lib_deps) which use more advanced features from PlatformIO (custom options, pre_build scripts, modification of directory filtering, and so forth). As long as I use “simple” dependencies I don’t see this issue. But once I switch to an advanced dependency it pop’s up.

Also - it only rebuilds the advanced dependency…
Like, assume you are working on a project X (ESP32, Arduino framework - for sake of simplicity).
Project X depends on A and B (cloned in to Arduino/libraries). Where B is a complex dependency (custom options, pre_build scripts, etc…).

When the false rebuild kicks in, only B will be rebuilt. A will not be rebuilt.

Could also be related to the underlying build system (haven’t verified) - but my personal frustration is much lower when working with NRF52 using Zephyr as the framework (same dependencies). I don’t think I see the same rebuild behavior in that case (need to verify this though).

I’ll try to create some kind of workspace, or set of projects, that will trigger this issue.

There is a very simple solution to debug this issue. Please build your project in the verbose mode using pio run -v. Copy ALL output to file a.txt. Now, repeat pio run -v, and copy output to the b.txt. Compare both files with any tool. Do you see a difference?

Indeed, there are a few places that differ.
Assuming I can safely ignore any output, like: <SCons.Scanner.ScannerBase object at 0x0000021C6E5E99D0

There is one thing standing out.
The order of folders in the SRC_FILTER changes.
This order change also affects a few other things like CPPDefines

We have a prebuild scripts that do modify SRC_FILTER (optional modules in the library).
Could this SRC_FILTER change trigger a rebuild of the affected library?

Ok, so I managed to solve it.
It is related to SRC_FILTER (or CPP_DEFINES) ordering causing the rebuild.
Reason for more complex projects having a higher ratio of rebuilds is the fact that they use more modules and thus a higher chance of order difference between runs.

Sorting my internal structure (which I use to manipulate SRC_FILTER) solves the issue. For a particular project it stays between builds (unless changed) - which gives same behavior as changing platformio.ini

Thanks a bunch for the advise to check diff’s between verbose runs!

Perhaps worth noting in the doc’s somewhere under advanced scripting…

1 Like

The reason is very simple - different flags to a building environment means 100% rebuilding of the target and its dependencies.

1 Like