Skip to content

Conversation

Jason2866
Copy link

@Jason2866 Jason2866 commented Sep 30, 2025

Description:

Refactor ESP-IDF version handling and new linker script preprocessing for IDF 6

Checklist:

  • The pull request is done against the latest develop branch
  • Only relevant files were touched
  • Only one feature/fix was added per PR, more changes are allowed when changing boards.json
  • I accept the CLA

Summary by CodeRabbit

  • New Features

    • Automatic ESP-IDF version detection and normalization, exported as an environment variable and version macros.
    • Added support for ESP-IDF 6.x linker script preprocessing alongside 5.x.
    • Direct preprocessing of .ld.in templates, with fallbacks for specific targets (e.g., ESP32P4).
  • Bug Fixes

    • More reliable linker script generation and handling of -T flags for both bootloader and main project.
    • Improved build stability across ESP-IDF versions by unifying version-aware linker and compiler flag processing.

Refactor ESP-IDF version handling and linker script preprocessing.
Copy link

coderabbitai bot commented Sep 30, 2025

Walkthrough

Adds version resolution via get_framework_version(), sets ESP_IDF_VERSION env/defines, normalizes version components, and revises linker script preprocessing with a new API supporting IDF 5.x and 6.x flows. Updates bootloader/main paths to preprocess .ld/.ld.in, restructure linker flags, and propagate version defines.

Changes

Cohort / File(s) Summary
ESP-IDF version detection and normalization
builder/frameworks/espidf.py
Introduced get_framework_version(); added normalization/coercion helpers; derived ESP_IDF_VERSION and major/minor components; propagated version defines (ESP_IDF_VERSION, ESP_IDF_VERSION_MAJOR, ESP_IDF_VERSION_MINOR).
Linker script preprocessing (IDF5 vs IDF6)
builder/frameworks/espidf.py
Expanded preprocess_linker_file(src, dst, config_dir=None, extra_include_dirs=None); added branching for IDF 5.x (linker_script_generator.cmake) vs 6.x (linker_script_preprocessor.cmake); built include paths/CFLAGS; handled .ld.in and fallbacks (incl. ESP32P4).
Bootloader and project integration
builder/frameworks/espidf.py
Updated generate_project_ld_script and build_bootloader to use version-aware flow; created processed_extra_flags; reworked -T linker script handling; wired preprocessed outputs into build.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Env as Build Env
  participant ESP as espidf.py
  participant Meta as Package Metadata
  participant FS as Filesystem
  participant CMake as CMake Scripts

  Note over ESP: Resolve ESP-IDF version
  Env->>ESP: Init build
  ESP->>Meta: Read package version
  alt Found in metadata
    Meta-->>ESP: Version string
  else Not in metadata
    ESP->>FS: Read framework cmake version file
    FS-->>ESP: Raw version
  end
  ESP->>ESP: Normalize/coerce (major/minor/patch, rc)
  ESP-->>Env: Set ESP_IDF_VERSION + defines
Loading
sequenceDiagram
  autonumber
  participant Build as Build Step
  participant ESP as preprocess_linker_file()
  participant FS as Filesystem
  participant CMake as CMake (IDF5/IDF6)

  Build->>ESP: src_ld, target_ld, config_dir, extra_includes
  ESP->>ESP: Detect IDF major version
  alt IDF 6.x path
    ESP->>ESP: Build include paths & CFLAGS
    ESP->>CMake: linker_script_preprocessor.cmake
    CMake-->>FS: Generated target_ld
  else IDF 5.x path
    ESP->>CMake: linker_script_generator.cmake
    CMake-->>FS: Generated target_ld
  end
  ESP-->>Build: target_ld for linker (-T)
  Note over Build: Used by bootloader and main project
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I twitch my ears at version lore,
From cmake whispers to metadata’s door.
I nibble flags, -T’s in line,
Preprocess scripts—how neat they shine!
With 5 or 6, I hop just right—
Linker paths aligned, builds take flight.
Thump-thump: green carrots tonight!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly indicates that the pull request prepares for IDF version 6 by adding updated linker script handling, which directly reflects the primary refactoring and feature addition described in the changeset. It is succinct, specific, and avoids irrelevant details or noise.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch prep_IDF6

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🧪 Early access (Sonnet 4.5): enabled

We are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience.

Note:

  • Public repositories are always opted into early access features.
  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.

Comment @coderabbitai help to get the list of available commands and usage tips.

@Jason2866
Copy link
Author

@coderabbitai full review

Copy link

coderabbitai bot commented Sep 30, 2025

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
builder/frameworks/espidf.py (1)

1532-1598: Consider using f-string conversion flags for consistency.

The implementation correctly handles both IDF 5.x and 6.x preprocessing paths. However, consider using explicit conversion flags in f-strings for consistency with PEP 498.

Apply this diff to improve f-string usage:

                " ".join([
                    f'"{CMAKE_DIR}"',
-                   f'-DCC="{fs.to_unix_path(str(Path(TOOLCHAIN_DIR) / "bin" / "$CC"))}"',
+                   f'-DCC="{fs.to_unix_path(Path(TOOLCHAIN_DIR) / "bin" / "$CC")!s}"',
                    f'-DSOURCE="{src_ld_script}"',
                    f'-DTARGET="{target_ld_script}"',
                    f'-DCFLAGS="{cflags_value}"',
                    "-P",
-                   f'"{fs.to_unix_path(str(Path(FRAMEWORK_DIR) / "tools" / "cmake" / "linker_script_preprocessor.cmake"))}"',
+                   f'"{fs.to_unix_path(Path(FRAMEWORK_DIR) / "tools" / "cmake" / "linker_script_preprocessor.cmake")!s}"',
                ]),
                "Generating LD script $TARGET",
            ),
        )
    else:
        # IDF 5.x: Use legacy linker_script_generator.cmake method
        return env.Command(
            target_ld_script,
            src_ld_script,
            env.VerboseAction(
                " ".join([
                    f'"{CMAKE_DIR}"',
-                   f'-DCC="{str(Path(TOOLCHAIN_DIR) / "bin" / "$CC")}"',
+                   f'-DCC="{Path(TOOLCHAIN_DIR) / "bin" / "$CC"!s}"',
                    "-DSOURCE=$SOURCE",
                    "-DTARGET=$TARGET",
                    f'-DCONFIG_DIR="{config_dir}"',
-                   f'-DLD_DIR="{str(Path(FRAMEWORK_DIR) / "components" / "esp_system" / "ld")}"',
+                   f'-DLD_DIR="{Path(FRAMEWORK_DIR) / "components" / "esp_system" / "ld"!s}"',
                    "-P",
-                   f'"{str(Path("$BUILD_DIR") / "esp-idf" / "esp_system" / "ld" / "linker_script_generator.cmake")}"',
+                   f'"{Path("$BUILD_DIR") / "esp-idf" / "esp_system" / "ld" / "linker_script_generator.cmake"!s}"',
                ]),
                "Generating LD script $TARGET",
            ),
        )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c22d9e and c8169f3.

📒 Files selected for processing (1)
  • builder/frameworks/espidf.py (6 hunks)
🧰 Additional context used
🪛 Ruff (0.13.1)
builder/frameworks/espidf.py

136-136: Consider moving this statement to an else block

(TRY300)


1588-1588: Use explicit conversion flag

Replace with conversion flag

(RUF010)


1592-1592: Use explicit conversion flag

Replace with conversion flag

(RUF010)


1594-1594: Use explicit conversion flag

Replace with conversion flag

(RUF010)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: build (macos-15, examples/espidf-blink)
  • GitHub Check: build (macos-15, examples/espidf-arduino-littlefs)
  • GitHub Check: build (macos-15, examples/espidf-arduino-C6-ULP-blink)
  • GitHub Check: build (windows-latest, examples/espidf-peripherals-uart)
  • GitHub Check: build (windows-latest, examples/espidf-storage-sdcard)
  • GitHub Check: build (macos-15, examples/arduino-wifiscan)
  • GitHub Check: build (macos-15, examples/arduino-blink)
  • GitHub Check: build (windows-latest, examples/arduino-usb-keyboard)
  • GitHub Check: build (windows-latest, examples/espidf-exceptions)
  • GitHub Check: build (windows-latest, examples/espidf-blink)
  • GitHub Check: build (ubuntu-latest, examples/espidf-ulp)
  • GitHub Check: build (windows-latest, examples/tasmota)
  • GitHub Check: build (windows-latest, examples/arduino-zigbee-light)
  • GitHub Check: build (windows-latest, examples/arduino-matter-light)
  • GitHub Check: build (windows-latest, examples/arduino-wifiscan)
  • GitHub Check: build (windows-latest, examples/espidf-hello-world)
  • GitHub Check: build (ubuntu-latest, examples/espidf-arduino-matter-light)
  • GitHub Check: build (ubuntu-latest, examples/tasmota)
  • GitHub Check: build (ubuntu-latest, examples/espidf-blink)
  • GitHub Check: build (ubuntu-latest, examples/arduino-wifiscan)
🔇 Additional comments (6)
builder/frameworks/espidf.py (6)

142-147: LGTM!

The framework version environment variable setup correctly extracts the major and minor version components and handles the edge case where the minor version might be missing.


1232-1234: LGTM!

Adding ESP-IDF version defines to the bootloader CMake configuration ensures version information is available during bootloader compilation, which is essential for version-aware build logic.


990-996: LGTM!

The version-aware linker script preprocessing for the main project correctly applies preprocessing only for IDF versions > 5.2, using appropriate defaults for the main project context.


1839-1847: LGTM!

The main linker script preprocessing follows the same version-aware pattern as the project LD script generation, ensuring consistent handling across the build system.


1275-1352: Complex linker script preprocessing logic – warn on silent fallback and verify upstream files

  • Emit a warning when neither an original nor a template .ld script is found, to avoid silently passing through an unprocessed file.
  • Manually verify in your ESP-IDF installation (e.g. $IDF_PATH/components/bootloader/subproject/main/ld/<variant>) that each supported variant has the required .ld or .ld.in scripts.

108-140: Verify regex fallback handles edge cases.

The version extraction logic is well-structured. However, the regex fallback at line 138 assumes a version string will always match the pattern (\d+)\.(\d+)\.(\d+). If semantic_version.Version.coerce() fails with a ValueError or TypeError, but the version string doesn't match the regex (e.g., "5.3", "6.0-dev"), this will return "0.0.0".

Consider testing with various version formats to ensure the fallback logic handles all expected cases:

@Jason2866 Jason2866 merged commit 1118ba0 into develop Sep 30, 2025
1 check passed
Jason2866 added a commit that referenced this pull request Oct 2, 2025
* prepare IDF 6: add changed linker script handling (#302)

Refactor ESP-IDF version handling and linker script preprocessing.

* use boards.json settings for HybridCompile

Refactor ESP-IDF configuration handling to support board-specific configurations and improve flash/PSRAM settings management.

* Settings for HybridCompile are choosen now from boards.json

Removed now unnecessary custom SDK configuration options for ESP32S3.

* Fix esp_idf_size command arguments

Remove unnecessary '--ng' argument from esp_idf_size command

* Update esp-idf-size package version to 2.0.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant