Skip to content

Commit d6576bf

Browse files
pi-anlAnon Kode
andcommitted
feat: Initial Kconfig integration
Adds a Kconfig infrastructure for managing build-time configuration options, moving away from scattered #defines and build variables. Includes: - Top-level Kconfig and Makefile for invoking configuration tools. - Kconfig files for core (py/), extmod/, drivers/, shared/, and all ports/. - Initial population of Kconfig options based on existing defines and build vars. - Conditional defaults in common Kconfig files based on PORT_ symbols. - Integration hooks into Makefiles and CMake files (`autoconf.mk`, `config.cmake`). - Initial build system integration for Kconfig variables in unix, stm32, rp2 ports. - Basic documentation in docs/develop/kconfig.rst. Further work needed for full dependency analysis, help text refinement, complete build system integration, and testing. 🤖 Generated with Anon Kode & gemini-2.5-pro-exp-03-25 Co-Authored-By: Anon Kode <noreply@Anon Kode.com>
1 parent db85427 commit d6576bf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3135
-55
lines changed

KCONFIG_PLAN.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Kconfig Integration Plan for MicroPython
2+
3+
**Important Note:** This Kconfig system is intended as an *optional overlay* to the existing `mpconfig*.h` and build variable system. It allows users to easily customize builds locally using `make menuconfig`. The primary configuration mechanism for MicroPython remains the existing system. The goal is not (currently) to fully replace the existing system, but to provide a user-friendly alternative for common overrides.
4+
5+
This document outlines the plan to integrate the Kconfig system into the MicroPython build process for managing compile-time configuration.
6+
7+
## Goals
8+
9+
1. **User-Friendly Customization:** Provide a standard, interactive interface (menuconfig, xconfig) for users to *optionally* override default MicroPython features and port-specific settings for their local builds.
10+
2. **Discoverability:** Make common configuration options easily discoverable with integrated help text.
11+
3. **Structure:** Organize Kconfig options in a hierarchy mirroring the project structure.
12+
4. **Integration:** Ensure Kconfig selections (`CONFIG_...`) correctly override the base configuration derived from `mpconfigport.h`, `mpconfigboard.h`, and Make/CMake variables where Kconfig options exist.
13+
14+
## Prerequisites
15+
16+
* Installation of Kconfig frontends (e.g., `kconfig-frontends` package providing `menuconfig`, `kconfig-conf`, etc., or Zephyr's `kconfiglib`). This plan assumes standard Kconfig tools are available in the PATH.
17+
18+
## Kconfig File Structure
19+
20+
* A top-level `Kconfig` file will be created in the repository root.
21+
* This root `Kconfig` will source other `Kconfig` files located in relevant directories:
22+
* `py/Kconfig`
23+
* `extmod/Kconfig`
24+
* `drivers/Kconfig`
25+
* `shared/Kconfig`
26+
* `ports/<port>/Kconfig` (e.g., `ports/unix/Kconfig`, `ports/stm32/Kconfig`)
27+
* `ports/<port>/boards/Kconfig` (Potentially, if board-level Kconfig is desired)
28+
29+
## Implementation Phases
30+
31+
**Phase 1: Initial Setup and Core `py/` Defines**
32+
33+
1. **Create Top-Level Files:**
34+
* Create `Kconfig` (root): Defines the main menu structure and sources other Kconfig files.
35+
* Create `Makefile` (root): Contains targets for Kconfig (`menuconfig`, `xconfig`) and a default target to delegate builds to ports.
36+
2. **Create Core Kconfig:**
37+
* Create `py/Kconfig`.
38+
3. **Identify & Define Core `py/` Options:**
39+
* Use `grep` to find common `#define`s starting with `MICROPY_` or `MPY_` within the `py/` directory (e.g., `MICROPY_ENABLE_GC`, `MICROPY_FLOAT_IMPL`, `MICROPY_PY_BUILTINS_SET`).
40+
* Add corresponding `config` entries to `py/Kconfig` with appropriate types (`bool`, `int`, `hex`, `string`), default values (extracted from defines), and initial help text.
41+
* Define choices where mutually exclusive options exist (e.g., float implementation).
42+
4. **Configure Kconfig Output (Header):**
43+
* Set up Kconfig build environment variables (e.g., `KCONFIG_CONFIG=.config`, `srctree=.`, `objtree=build`) likely via the top-level Makefile.
44+
* Configure Kconfig (e.g., using `kconfig-conf --syncconfig Kconfig`) to generate a C header file (e.g., `build/mpconfig_kconfig.h`) containing `#define`s for chosen options (prefixed with `CONFIG_`).
45+
5. **Integrate Generated Header:**
46+
* Modify `py/mpconfig.h` (or a similar central header like `py/mpconfigbase.h`) to include `build/mpconfig_kconfig.h` *if it exists*.
47+
* Guard existing default `#define`s in MicroPython source files (`#ifndef CONFIG_...`) so that Kconfig values take precedence when the header is present.
48+
6. **Testing:**
49+
* Run `make menuconfig` from the root.
50+
* Save a configuration (`.config`).
51+
* Run `make -C mpy-cross` or `make PORT=unix -C ports/unix` (or the equivalent using the new top-level make target).
52+
* Verify `build/mpconfig_kconfig.h` is generated correctly.
53+
* Verify the build incorporates the settings from the generated header.
54+
55+
**Phase 2: Makefile Integration**
56+
57+
1. **Identify Makefile Variables:**
58+
* Use `grep` to find common variables starting with `MICROPY_` or `MPY_` in Makefiles (`Makefile`, `*.mk`) across the project, especially in `py/mkrules.mk` and port Makefiles. Examples: `FROZEN_MANIFEST`, `MICROPY_PY_FFI`.
59+
2. **Add Kconfig Options:**
60+
* Add corresponding `config` entries to the relevant `Kconfig` files (e.g., `ports/unix/Kconfig` for port-specific Make variables).
61+
3. **Configure Kconfig Output (Makefile Include):**
62+
* Configure Kconfig to generate a Makefile include fragment (e.g., `build/autoconf.mk`) containing Make variable assignments based on chosen options (`CONFIG_...=y` or `CONFIG_...=value`).
63+
4. **Integrate Generated Makefile:**
64+
* Modify relevant Makefiles (e.g., `py/mkrules.mk`, port Makefiles) to include `build/autoconf.mk`. The inclusion point needs careful consideration - include it early to allow overrides later, or late to enforce Kconfig values. Start by including it early.
65+
5. **Refactor Makefiles:**
66+
* Update Makefiles to use the Kconfig variables (e.g., `ifeq ($(CONFIG_MICROPY_PY_FFI),y)`).
67+
* Remove original variable definitions if they are now fully controlled by Kconfig.
68+
6. **Testing:**
69+
* Run `make menuconfig`, change relevant options, save.
70+
* Run `make` for a Make-based port (e.g., `unix`, `stm32`).
71+
* Verify the build reflects the Kconfig settings passed via `autoconf.mk`.
72+
73+
**Phase 3: CMake Integration**
74+
75+
1. **Identify CMake Variables:**
76+
* Use `grep` to find common variables set with `set(MICROPY_...` or `set(MPY_...` in CMake files (`CMakeLists.txt`, `*.cmake`), particularly in CMake-based ports like `esp32` and `rp2`.
77+
2. **Add Kconfig Options:**
78+
* Add corresponding `config` entries to relevant `Kconfig` files (e.g., `ports/esp32/Kconfig`).
79+
3. **Configure Kconfig Output (CMake Include):**
80+
* Configure Kconfig to generate a CMake script (e.g., `build/config.cmake`) containing CMake variable assignments (`set(CONFIG_... ON)` or `set(CONFIG_... "value")`).
81+
4. **Integrate Generated CMake:**
82+
* Modify relevant `CMakeLists.txt` files to include `build/config.cmake` early in the configuration process.
83+
5. **Refactor CMake:**
84+
* Update CMake files to use the Kconfig variables (e.g., `if(CONFIG_MICROPY_BLUETOOTH_NIMBLE)`).
85+
* Remove original variable definitions if controlled by Kconfig.
86+
6. **Testing:**
87+
* Run `make menuconfig`, change relevant options, save.
88+
* Build a CMake-based port (e.g., `esp32`, `rp2`).
89+
* Verify the build reflects the Kconfig settings passed via `config.cmake`.
90+
91+
**Phase 4: Expansion and Refinement**
92+
93+
1. **Systematic Scan:** Thoroughly scan *all* project directories (`extmod`, `drivers`, `ports`, etc.) for C `#define`s, Makefile variables, and CMake variables starting with `MICROPY_` or `MPY_`.
94+
2. **Create Kconfig Entries:** Add Kconfig entries for all identified configuration points into the structured `Kconfig` files.
95+
3. **Dependencies:** Analyze code logic (`#if`, conditional assignments) to define dependencies (`depends on`) and selections (`select`) between Kconfig options.
96+
4. **Help Text:** Review and improve the help text for all Kconfig options, explaining their purpose and impact.
97+
5. **Add Targets:** Implement the `xconfig` target in the top-level Makefile. Implement the default target to delegate `make PORT=<port> [BOARD=<board>] ...` calls correctly.
98+
6. **Testing:** Test across a wider range of ports and configurations.
99+
100+
**Phase 5: Documentation and Cleanup**
101+
102+
1. **Documentation:** Add documentation explaining the new Kconfig system, prerequisites, and usage.
103+
2. **Cleanup:** Remove configuration settings from original source files, Makefiles, and CMake files if they have been fully superseded by the Kconfig system.
104+
3. **Final Review:** Ensure consistency, test edge cases, and verify build success across major ports.
105+
106+
## Output Files (in `build/` directory)
107+
108+
* `.config`: The saved Kconfig selections.
109+
* `mpconfig_kconfig.h`: Generated C header with `#define CONFIG_...`.
110+
* `autoconf.mk`: Generated Makefile include with `CONFIG_...=y/value`.
111+
* `config.cmake`: Generated CMake include with `set(CONFIG_... ON/"value")`.
112+
* Other Kconfig intermediate files (e.g., `syncconfig.log`).
113+
114+
This phased approach allows for incremental implementation and testing, reducing the risk associated with a large-scale change to the build system.

KCONFIG_STATUS.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Kconfig Integration Status Summary
2+
3+
This document summarizes the current state of the Kconfig integration effort.
4+
5+
## Completed Steps (Phases 1-3 & Initial Scan)
6+
7+
* **Initial Setup:**
8+
* Created top-level `Kconfig` and `Makefile`.
9+
* Created skeleton `Kconfig` files for core directories (`py`, `extmod`, `drivers`, `shared`) and all ports.
10+
* **Core `py/` Defines:**
11+
* Identified and added initial Kconfig options for core features, types, modules, optimizations, and memory settings based on `py/mpconfig.h` and `py/mpconfigbase.h`.
12+
* Configured Kconfig output generation (`mpconfig_kconfig.h`, `autoconf.mk`, `config.cmake`) via the top-level Makefile.
13+
* Integrated the generated header include into `py/mpconfig.h`.
14+
* **Makefile Integration:**
15+
* Integrated `build/autoconf.mk` include into `py/mkrules.mk`.
16+
* **CMake Integration:**
17+
* Integrated `build/config.cmake` include into `py/py.cmake`.
18+
* **Systematic Scan:**
19+
* Scanned `py/`, `extmod/`, `drivers/`, `shared/`, `ports/`, and `mpy-cross/` for C `#define`s and Make/CMake variables starting with `MICROPY_` or `MPY_`.
20+
* Added corresponding Kconfig entries for found configuration points into the relevant `Kconfig` files (e.g., `ports/unix/Kconfig`, `ports/stm32/Kconfig`, etc.).
21+
* **Documentation:**
22+
* Created initial documentation page `docs/develop/kconfig.rst`.
23+
* Added the page to the development documentation index.
24+
25+
## Kconfig Maintenance Check (`tools/check_kconfig_settings.sh`)
26+
27+
To help ensure new configuration options are added to Kconfig going forward, a check script has been added:
28+
29+
* **Purpose:** Scans committed changes for new `#define MICROPY_...`, `#define MPY_...`, `MICROPY_... =`, `MPY_... =`, `set(MICROPY_...)`, or `set(MPY_...)` definitions/variables in relevant source files (`.c`, `.h`, `.mk`, `.cmake`, `CMakeLists.txt`), excluding common library/build directories.
30+
* **Verification:** For each new setting found, it searches all `Kconfig` files to ensure a corresponding `config SETTING_NAME` entry exists.
31+
* **Integration:** Designed to be run in pre-commit hooks and CI workflows.
32+
* **Failure:** If settings are found without a matching Kconfig entry, the script prints an error and exits with a non-zero status.
33+
34+
**Example Error Output:**
35+
36+
```
37+
--------------------------------------------------
38+
Error: Found new MICROPY_/MPY_ settings without corresponding Kconfig entries:
39+
- MICROPY_NEW_FEATURE_X
40+
- MICROPY_HW_COOL_SENSOR
41+
42+
Please add a 'config MICROPY_HW_COOL_SENSOR' entry to the appropriate Kconfig file.
43+
--------------------------------------------------
44+
```
45+
46+
This provides a mechanism to catch accidental omissions and maintain consistency between the code/build system and the Kconfig definitions.
47+
48+
## Next Steps (Phase 4 & 5 - Refinement, Testing, Cleanup)
49+
50+
Significant manual effort is required for the following:
51+
52+
1. **Dependencies:** Analyze code logic (`#if`, conditional assignments in Make/CMake) across the entire codebase to define dependencies (`depends on`) and selections (`select`) between Kconfig options. This is crucial for ensuring valid configurations.
53+
2. **Help Text:** Review and significantly improve the help text for *all* Kconfig options, explaining their purpose, impact on resources (flash/RAM), and any potential side effects or requirements.
54+
3. **Refactoring:**
55+
* Systematically replace hardcoded `#define` values in C source files with checks for the corresponding `CONFIG_...` Kconfig definition (e.g., `#if CONFIG_MICROPY_ENABLE_GC`).
56+
* Refactor Makefiles (`*.mk`) to use variables derived from Kconfig (e.g., `ifeq ($(CONFIG_MICROPY_PY_FFI),y)`) instead of their original definitions.
57+
* Refactor CMake files (`*.cmake`, `CMakeLists.txt`) to use Kconfig variables (e.g., `if(CONFIG_MICROPY_BLUETOOTH_NIMBLE)`).
58+
* Remove original definitions from source/Make/CMake files once they are fully controlled by Kconfig.
59+
4. **Testing:**
60+
* Perform thorough build testing across a wide range of ports (Make-based and CMake-based) and boards.
61+
* Test various combinations of Kconfig options (enabling/disabling features) to ensure the build system and code behave correctly.
62+
* Verify that generated firmware reflects the chosen Kconfig settings.
63+
5. **Documentation:**
64+
* Expand and refine the `docs/develop/kconfig.rst` documentation with more detailed usage instructions, information about common options, and guidance for port maintainers.
65+
6. **Cleanup:**
66+
* Consolidate duplicated options (e.g., `MICROPY_PY_NETWORK_WIZNET5K` defined in both `extmod/Kconfig` and `ports/stm32/Kconfig`). Decide on the canonical location for each option.
67+
* Ensure consistency in naming and style across all Kconfig files.
68+
69+
This integration provides the basic framework, but the refinement phase is essential for making it robust and user-friendly.

Kconfig

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
mainmenu "MicroPython Configuration"
2+
3+
# Default to a common configuration file name
4+
config KCONFIG_CONFIG
5+
string
6+
option env="KCONFIG_CONFIG"
7+
default ".config"
8+
9+
# Build directory
10+
config KCONFIG_BUILD_DIR
11+
string
12+
option env="KCONFIG_BUILD_DIR"
13+
default "build"
14+
15+
# Define ARCH for Kconfig scripts (optional, but good practice)
16+
config ARCH
17+
string
18+
option env="ARCH"
19+
default "arm"
20+
21+
# Include Kconfig files from subdirectories
22+
source "py/Kconfig"
23+
source "extmod/Kconfig"
24+
source "drivers/Kconfig"
25+
source "shared/Kconfig"
26+
27+
# Conditionally include port-specific Kconfig files based on PORT variable
28+
choice
29+
prompt "Target Port"
30+
optional
31+
32+
config PORT_UNIX
33+
bool "Unix Port"
34+
config PORT_STM32
35+
bool "STM32 Port"
36+
config PORT_ESP32
37+
bool "ESP32 Port"
38+
config PORT_ESP8266
39+
bool "ESP8266 Port"
40+
config PORT_RP2
41+
bool "RP2 Port"
42+
config PORT_MIMXRT
43+
bool "MIMXRT Port"
44+
config PORT_SAMD
45+
bool "SAMD Port"
46+
config PORT_NRF
47+
bool "nRF Port"
48+
config PORT_CC3200
49+
bool "CC3200 Port"
50+
config PORT_PIC16BIT
51+
bool "PIC16BIT Port"
52+
config PORT_POWERPC
53+
bool "PowerPC Port"
54+
config PORT_QEMU
55+
bool "QEMU Port"
56+
config PORT_RENESAS_RA
57+
bool "Renesas RA Port"
58+
config PORT_WEBASSEMBLY
59+
bool "WebAssembly Port"
60+
config PORT_ZEPHYR
61+
bool "Zephyr Port"
62+
63+
endchoice
64+
65+
# Source port Kconfig if selected
66+
if PORT_UNIX
67+
source "ports/unix/Kconfig"
68+
endif
69+
if PORT_STM32
70+
source "ports/stm32/Kconfig"
71+
endif
72+
if PORT_ESP32
73+
source "ports/esp32/Kconfig"
74+
endif
75+
if PORT_ESP8266
76+
source "ports/esp8266/Kconfig"
77+
endif
78+
if PORT_RP2
79+
source "ports/rp2/Kconfig"
80+
endif
81+
if PORT_MIMXRT
82+
source "ports/mimxrt/Kconfig"
83+
endif
84+
if PORT_SAMD
85+
source "ports/samd/Kconfig"
86+
endif
87+
if PORT_NRF
88+
source "ports/nrf/Kconfig"
89+
endif
90+
if PORT_CC3200
91+
source "ports/cc3200/Kconfig"
92+
endif
93+
if PORT_PIC16BIT
94+
source "ports/pic16bit/Kconfig"
95+
endif
96+
if PORT_POWERPC
97+
source "ports/powerpc/Kconfig"
98+
endif
99+
if PORT_QEMU
100+
source "ports/qemu/Kconfig"
101+
endif
102+
if PORT_RENESAS_RA
103+
source "ports/renesas-ra/Kconfig"
104+
endif
105+
if PORT_WEBASSEMBLY
106+
source "ports/webassembly/Kconfig"
107+
endif
108+
if PORT_ZEPHYR
109+
source "ports/zephyr/Kconfig"
110+
endif

0 commit comments

Comments
 (0)