esp-bmgr-assist

[中文]

esp-bmgr-assist is BMGR’s Python helper package (source code located at tools/esp_bmgr_assist/ in the repository). It hooks into the idf.py startup process via a .pth hook, automatically discovers the esp_board_manager component used by the current project, and adds it to IDF_EXTRA_ACTIONS_PATH, making the idf.py bmgr command directly available without manual environment variable configuration.

It does not replace the esp_board_manager component and does not generate board-level code; board-level code is still generated by gen_bmgr_config_codes.py inside the component.

Installation

Activate the ESP-IDF Python environment first (run ./install.sh and . ./export.sh in the IDF directory), then execute:

pip install esp-bmgr-assist

Upgrade:

pip install --upgrade esp-bmgr-assist

Install from local source in the repository:

pip install --no-build-isolation ./tools/esp_bmgr_assist

Re-installation is required after switching to a new ESP-IDF Python environment.

Auto-Discovery Rules

esp-bmgr-assist searches for the esp_board_manager component in the current project in the following order:

  • components/esp_board_manager

  • components/espressif__esp_board_manager

  • managed_components/espressif__esp_board_manager

  • Local component pointed to by override_path / path in idf_component.yml

  • esp_board_manager resolved from dependencies.lock

  • espressif/esp_board_manager as a direct or indirect dependency in the project dependency graph

Only a directory that simultaneously contains idf_ext.py, idf_component.yml, and gen_bmgr_config_codes.py is recognized as a valid component directory.

When idf.py bmgr ... is executed for the first time and the managed component has not yet been downloaded, the helper tool triggers dependency resolution and downloads esp_board_manager, then loads the Board Manager action after the download completes.

Pre-Build Checks

When commands such as idf.py build are executed, esp-bmgr-assist first checks:

  • Whether the generated artifacts in components/gen_bmgr_codes/* are missing.

  • Whether CONFIG_IDF_TARGET in sdkconfig and gen_bmgr_codes/board_manager.defaults are inconsistent.

By default, the command is aborted when an issue is detected. Adjust the severity level via a parameter or environment variable:

idf.py --bmgr-preflight-level warning build   # print warning only
idf.py --bmgr-preflight-level silent build    # skip

export ESP_BMGR_ASSIST_PREFLIGHT=warning      # equivalent environment variable

Supported levels: error / abort (default), warning / warn, silent / off. The pre-build check only applies to build-type commands and does not interfere with interactive or configuration commands such as set-target, menuconfig, or confserver.

Debugging and Fallback

Debug the auto-discovery process:

export ESP_BMGR_DEBUG=1
idf.py bmgr -l

Fallback: when esp-bmgr-assist is not installed or auto-discovery fails, manually set IDF_EXTRA_ACTIONS_PATH to point to the esp_board_manager component directory (separate multiple paths with ;, not :).

Known Issues

Falling Back to esp32 Target on Indirect Dependencies

If esp_board_manager is introduced indirectly through an upstream component (i.e., not declared directly in main/idf_component.yml), the helper tool needs to resolve the full dependency graph and relies on IDF_TARGET to produce correct results. When it cannot be read, it falls back to esp32, which may cause dependency resolution failures for components that only support specific targets.

Workaround:

  1. Run idf.py set-target <target> to fetch the ESP Board Manager component.

  2. Or temporarily specify the target when running Board Manager commands:

IDF_TARGET=esp32s3 idf.py bmgr -l
ESP_BMGR_BOOTSTRAP_TARGET=esp32p4 idf.py bmgr -b <board>

When the project declares espressif/esp_board_manager directly in main/idf_component.yml, the minimal download path is used and this issue typically does not occur.

Command Appears to Hang While Waiting for Bootstrap Lock

esp-bmgr-assist uses a .esp_bmgr_py.lock file in the project directory to serialize the bootstrap process between multiple idf.py processes, preventing concurrent component downloads. If another idf.py command in the same project directory is currently bootstrapping or downloading components, the new command waits for this lock first.

When waiting starts, a message is printed, for example:

[esp-bmgr-assist] Waiting for board manager bootstrap lock.
lock: /path/to/project/.esp_bmgr_py.lock
timeout: 60s
If this waits unexpectedly, check the process holding the lock:
  lsof /path/to/project/.esp_bmgr_py.lock
  fuser -v /path/to/project/.esp_bmgr_py.lock

The default timeout is 60 seconds. After the timeout, Timed out waiting for board manager bootstrap lock. is printed and the command is aborted. The lsof / fuser -v commands shown in the message apply to Linux and macOS. Windows users refer to the platform-specific troubleshooting steps below.

Troubleshooting steps:

  1. Confirm whether a real idf.py / python process is holding the lock.

    Linux / macOS:

    lsof /path/to/project/.esp_bmgr_py.lock
    fuser -v /path/to/project/.esp_bmgr_py.lock
    

    Windows: use Sysinternals handle.exe, or open Task Manager / Resource Monitor (resmon.exe), go to CPU > Associated Handles, and search for the lock file name:

    handle.exe \path\to\project\.esp_bmgr_py.lock
    
  2. If no process is holding the lock (for example, the lock file was left behind by a killed command), delete the lock file manually and retry:

    Linux / macOS:

    rm /path/to/project/.esp_bmgr_py.lock
    

    Windows (cmd):

    del \path\to\project\.esp_bmgr_py.lock
    

    Windows (PowerShell):

    Remove-Item \path\to\project\.esp_bmgr_py.lock
    
  3. When the project directory is not writable, the lock file falls back to esp_bmgr_py_locks/<digest>.lock in the system temporary directory (typically /tmp/ on Linux/macOS, %TEMP% on Windows). The message shows the exact path.

  4. To allow a longer wait window (for example, when fetching the component for the first time is slow), adjust the timeout:

    Linux / macOS:

    export ESP_BMGR_LOCK_TIMEOUT=120
    

    Windows (cmd):

    set ESP_BMGR_LOCK_TIMEOUT=120
    

    Windows (PowerShell):

    $env:ESP_BMGR_LOCK_TIMEOUT = "120"
    

Full documentation: esp_board_manager/docs/esp_bmgr_assist_cn.md.

Options Not Recognized After Switching IDF Versions

After switching to a different IDF version, idf.py bmgr may report unrecognized options, for example:

>> idf.py bmgr -l
Usage: idf.py bmgr [OPTIONS]
Try 'idf.py bmgr --help' for help.

Error: No such option: -l

Each ESP-IDF version uses an isolated Python virtual environment. After switching versions, esp-bmgr-assist may not be installed in the new environment.

Resolution:

  1. Check whether the package is present in the current IDF Python environment:

    pip show esp-bmgr-assist
    
  2. If no package information is shown, reinstall or upgrade it in the current IDF environment:

    python3 -m pip install --upgrade esp-bmgr-assist
    

Was this page helpful?