Files
LEDMatrix/docs/DEVELOPMENT.md
T
ChuckandClaude Opus 5.5 d54a6c8545 docs(dev): correct the test-running and rgbmatrix build instructions
- HOW_TO_RUN_TESTS: coverage is not collected by a plain pytest run and
  pytest.ini has no threshold; the only one is --cov-fail-under=52 in the
  core unit-test job of .github/workflows/test.yml, which runs the whole
  test/ tree (not an allowlist). Almost no tests carry markers, so
  -m integration / -m slow select nothing; drop them and -m unit as the
  quick check. Replace the hardcoded /home/chuck path.
- DEVELOPMENT: the rgbmatrix package is built with pip install . from
  the submodule root (scikit-build-core + CMake + Ninja), as
  first_time_install.sh does; there is no make build-python /
  bindings/python step, and the build deps are python-dev-is-python3,
  cmake and ninja-build, not cython3/scons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-22 16:27:12 -04:00

5.9 KiB

Development Guide

This guide provides information for developers and contributors working on the LEDMatrix project.

Git Submodules

rpi-rgb-led-matrix-master Submodule

The rpi-rgb-led-matrix-master submodule is a foundational dependency located at the repository root (not in plugins/). This submodule provides the core hardware abstraction layer for controlling RGB LED matrices via the Raspberry Pi GPIO pins.

Architectural Rationale

Why at the root?

  • Core Dependency: Unlike plugins in the plugins/ directory, rpi-rgb-led-matrix-master is a foundational library required by the core LEDMatrix system, not an optional plugin
  • System-Level Integration: The rgbmatrix Python module (built from this submodule) is imported by src/display_manager.py, which is part of the core display system
  • Build Requirements: The submodule must be compiled to create the rgbmatrix Python bindings before the system can run
  • Separation of Concerns: Keeping core dependencies at the root level separates them from user-installable plugins, maintaining a clear architectural distinction

Why not in plugins/?

  • Plugins are optional, user-installable modules that depend on the core system
  • rpi-rgb-led-matrix-master is a required build dependency, not an optional plugin
  • The core system cannot function without this dependency

Initializing the Submodule

When cloning the repository, you must initialize the submodule:

First-time clone (recommended):

git clone --recurse-submodules https://github.com/ChuckBuilds/LEDMatrix.git
cd LEDMatrix

If you already cloned without submodules:

git submodule update --init --recursive

To initialize only the rpi-rgb-led-matrix-master submodule:

git submodule update --init --recursive rpi-rgb-led-matrix-master

Building the Submodule

After initializing the submodule, build and install the rgbmatrix Python package from the submodule root. Upstream's pyproject.toml builds it with scikit-build-core, CMake and Ninja; there is no separate make step:

cd rpi-rgb-led-matrix-master
python3 -m pip install --break-system-packages .

On a board with 1 GB of RAM or less, cap the compile so it doesn't run out of memory: CMAKE_BUILD_PARALLEL_LEVEL=1 python3 -m pip install --break-system-packages .

Note: The first_time_install.sh script automates this process during installation, including the parallelism cap and a temporary swapfile on low-memory boards.

Troubleshooting

Submodule appears empty: If the rpi-rgb-led-matrix-master directory exists but is empty or lacks a Makefile:

# Remove the empty directory
rm -rf rpi-rgb-led-matrix-master

# Re-initialize the submodule
git submodule update --init --recursive rpi-rgb-led-matrix-master

Build fails: Ensure you have the required build dependencies installed:

sudo apt install -y build-essential python-dev-is-python3 cmake ninja-build

Import error for rgbmatrix module:

  • Verify the submodule is initialized: ls rpi-rgb-led-matrix-master/Makefile
  • Ensure the Python bindings are built and installed (see "Building the Submodule" above)
  • Check that the module is installed: python3 -c "from rgbmatrix import RGBMatrix; print('OK')"

Submodule out of sync: If the submodule commit doesn't match what the main repository expects:

git submodule update --remote rpi-rgb-led-matrix-master

CI/CD Configuration

When setting up CI/CD pipelines, ensure submodules are initialized before building:

GitHub Actions Example:

- name: Checkout repository
  uses: actions/checkout@v3
  with:
    submodules: recursive

- name: Build rpi-rgb-led-matrix
  run: |
    cd rpi-rgb-led-matrix-master
    pip install .

GitLab CI Example:

variables:
  GIT_SUBMODULE_STRATEGY: recursive

build:
  script:
    - cd rpi-rgb-led-matrix-master
    - pip install .

Jenkins Example:

stage('Checkout') {
    checkout([
        $class: 'GitSCM',
        branches: [[name: '*/main']],
        doGenerateSubmoduleConfigurations: false,
        extensions: [[$class: 'SubmoduleOption',
                      disableSubmodules: false,
                      parentCredentials: true,
                      recursiveSubmodules: true,
                      reference: '',
                      trackingSubmodules: false]],
        userRemoteConfigs: [[url: 'https://github.com/ChuckBuilds/LEDMatrix.git']]
    ])
}

General CI/CD Checklist:

  • ✓ Use --recurse-submodules flag when cloning (or equivalent in your CI system)
  • ✓ Initialize submodules before any build steps
  • ✓ Build the Python bindings if your tests require the rgbmatrix module
  • ✓ Note: Emulator mode (using RGBMatrixEmulator) doesn't require the submodule to be built

Plugins

Plugins are not git submodules of this repository. The plugins directory (configured by plugin_system.plugins_directory in config/config.json, default plugin-repos/) is populated at install time by the plugin loader as users install plugins from the Plugin Store or from a GitHub URL via the web interface. Plugin source lives in a separate repository: ChuckBuilds/ledmatrix-plugins.

To work on a plugin locally without going through the Plugin Store, clone that repo and symlink (or copy) the plugin directory into your configured plugins directory — by default plugin-repos/<plugin-id>/. The plugin loader will pick it up on the next display restart. The directory name must match the plugin's id in manifest.json.

For more information, see: