mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'feat/generate_per_component_headers' into 'master'
feat(kconfig): add support for per option based build optimization Closes IDF-8957 See merge request espressif/esp-idf!41966
This commit is contained in:
@@ -8,6 +8,9 @@ set(ESP_MENUCONFIG_MIN_KCONFIG_VERSION "3.1.0")
|
||||
# (fused menuconfig + deprecated-options post-processing in a single invocation).
|
||||
set(MENUCONFIG_INLINE_MIN_KCONFIG_VERSION "3.9.0")
|
||||
|
||||
# Minimum esp-idf-kconfig version required for cdep_tree / configdep (--output cdep_tree)
|
||||
set(CONFIGDEP_MIN_KCONFIG_VERSION "3.6.0")
|
||||
|
||||
function(__kconfig_init)
|
||||
idf_build_get_property(idf_path IDF_PATH)
|
||||
|
||||
@@ -239,6 +242,12 @@ function(__kconfig_generate_config sdkconfig sdkconfig_defaults)
|
||||
if(output_sdkconfig)
|
||||
list(APPEND kconfgen_output_options --output config ${sdkconfig})
|
||||
endif()
|
||||
# If configdep feature is enabled in ESP-IDF and esp-idf-kconfig version supports cdep_tree,
|
||||
# add output option for configdep (requires esp-idf-kconfig >= CONFIGDEP_MIN_KCONFIG_VERSION)
|
||||
__check_python_package_min_version(${python} esp-idf-kconfig "${CONFIGDEP_MIN_KCONFIG_VERSION}" CONFIGDEP_SUPPORTED)
|
||||
if(CONFIGDEP_SUPPORTED AND CONFIGDEP_ENABLE)
|
||||
list(APPEND kconfgen_output_options --output cdep_tree ${config_dir})
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${prepare_kconfig_files_command})
|
||||
|
||||
@@ -608,16 +608,52 @@ macro(project project_name)
|
||||
|
||||
__target_set_toolchain()
|
||||
|
||||
# Build compiler launcher chain
|
||||
set(compiler_launcher_chain "")
|
||||
# Add custom wrapper if enabled (FIRST in chain)
|
||||
if(CONFIGDEP_ENABLE)
|
||||
# Check that esp-idf-kconfig >= CONFIGDEP_MIN_KCONFIG_VERSION is installed
|
||||
# (required for cdep_tree / configdep support; version is defined in kconfig.cmake)
|
||||
__check_python_package_min_version(${PYTHON} esp-idf-kconfig
|
||||
"${CONFIGDEP_MIN_KCONFIG_VERSION}" _kconfig_version_ok)
|
||||
if(_kconfig_version_ok)
|
||||
find_program(CONFIGDEP_FOUND esp-idf-configdep)
|
||||
if(CONFIGDEP_FOUND)
|
||||
message(STATUS "esp-idf-configdep will be used for faster recompilation")
|
||||
list(APPEND compiler_launcher_chain "esp-idf-configdep")
|
||||
else()
|
||||
message(WARNING "esp-idf-configdep enabled but not found. Re-run install and export scripts.")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "esp-idf-configdep not supported by esp-idf-kconfig "
|
||||
"(>= ${CONFIGDEP_MIN_KCONFIG_VERSION} required). Re-run install and export scripts.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Add ccache if enabled (SECOND in chain)
|
||||
if(CCACHE_ENABLE)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
message(STATUS "ccache will be used for faster recompilation")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
list(APPEND compiler_launcher_chain "ccache")
|
||||
else()
|
||||
message(WARNING "enabled ccache in build but ccache program not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Apply the launcher chain - CMake automatically creates semicolon-separated list
|
||||
if(compiler_launcher_chain)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER ${compiler_launcher_chain})
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER ${compiler_launcher_chain})
|
||||
set(CMAKE_ASM_COMPILER_LAUNCHER ${compiler_launcher_chain})
|
||||
|
||||
# Debug: show what the launcher chain looks like
|
||||
string(REPLACE ";" " -> " launcher_display "${compiler_launcher_chain}")
|
||||
message(STATUS "Compiler launcher chain: ${launcher_display}")
|
||||
else()
|
||||
message(STATUS "No compiler launcher chain will be used.")
|
||||
endif()
|
||||
|
||||
# The actual call to project()
|
||||
__project(${project_name} C CXX ASM)
|
||||
__linux_build_set_lang_version()
|
||||
|
||||
@@ -17,6 +17,11 @@ set(CMAKE_MODULE_PATH
|
||||
# for both cmakev1 and cmakev2.
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/version.cmake)
|
||||
|
||||
# Suppress CMake warning: "Manually-specified variables were not used by the project: CONFIGDEP_ENABLE"
|
||||
# (CONFIGDEP_ENABLE is passed by idf.py but only used in the cmake v1 project() flow in project.cmake)
|
||||
# FIXME: When cmakev2 will start supporting configdep, this can be removed.
|
||||
set(_idf_ignore_configdep_enable "${CONFIGDEP_ENABLE}")
|
||||
|
||||
# The gdbinit.cmake file from cmakev1 contains a single function,
|
||||
# __generate_gdbinit, which is used in the generation of
|
||||
# project_description.json.
|
||||
|
||||
@@ -530,6 +530,13 @@ def action_extensions(base_actions: dict, project_path: str) -> Any:
|
||||
'envvar': 'IDF_CCACHE_ENABLE',
|
||||
'default': False,
|
||||
},
|
||||
{
|
||||
'names': ['--configdep/--no-configdep'],
|
||||
'help': 'Use configdep wrapper to optimize rebuild process. Enabled by default.',
|
||||
'is_flag': True,
|
||||
'envvar': 'IDF_CONFIGDEP_ENABLE',
|
||||
'default': True,
|
||||
},
|
||||
{
|
||||
'names': ['-G', '--generator'],
|
||||
'help': 'CMake generator.',
|
||||
|
||||
@@ -788,6 +788,7 @@ def ensure_build_directory(
|
||||
cache = _parse_cmakecache(cache_path) if os.path.exists(cache_path) else {}
|
||||
|
||||
args.define_cache_entry.append(f'CCACHE_ENABLE={args.ccache}')
|
||||
args.define_cache_entry.append(f'CONFIGDEP_ENABLE={args.configdep}')
|
||||
|
||||
cache_cmdl = _parse_cmdl_cmakecache(args.define_cache_entry)
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# placeholder_before_include_project_cmake
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
# placeholder_after_include_project_cmake
|
||||
|
||||
project(configdep_test_app)
|
||||
@@ -0,0 +1,6 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
|
||||
|
||||
# Configdep test application
|
||||
|
||||
Minimal ESP-IDF project used by ``tools/test_build_system/test_configdep.py`` to exercise ``esp-idf-configdep`` selective rebuilds and to assert that the built firmware reflects Kconfig toggles (via strings embedded in the ELF).
|
||||
@@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "configdep_main.c" "unrelated.c"
|
||||
INCLUDE_DIRS "")
|
||||
@@ -0,0 +1,5 @@
|
||||
menu "Configdep Test"
|
||||
config TEST_CONFIGDEP_OPTION
|
||||
bool "Test configdep option"
|
||||
default y
|
||||
endmenu
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
extern void unrelated_function(void);
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
#if CONFIG_TEST_CONFIGDEP_OPTION
|
||||
printf("CONFIGDEP_OPTION: ENABLED\n");
|
||||
#else
|
||||
printf("CONFIGDEP_OPTION: DISABLED\n");
|
||||
#endif
|
||||
unrelated_function();
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* Second TU in ``main``: only uses CONFIG_IDF_TARGET from sdkconfig—no conditional
|
||||
* on the optional symbol defined for configdep_main.c (see ``Kconfig.projbuild``).
|
||||
* Used by tests to snapshot this ``.obj`` alongside ``configdep_main``.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
void unrelated_function(void)
|
||||
{
|
||||
printf("IDF target: %s\n", CONFIG_IDF_TARGET);
|
||||
}
|
||||
@@ -20,6 +20,8 @@ from .idf_utils import get_idf_build_env
|
||||
from .idf_utils import run_cmake
|
||||
from .idf_utils import run_cmake_and_build
|
||||
from .idf_utils import run_idf_py
|
||||
from .rebuild_utils import BUILD_SNAPSHOT_EXCLUDE
|
||||
from .rebuild_utils import rebuild_and_check
|
||||
from .snapshot import Snapshot
|
||||
from .snapshot import get_snapshot
|
||||
|
||||
@@ -46,4 +48,6 @@ __all__ = [
|
||||
'file_contains',
|
||||
'bin_file_contains',
|
||||
'bin_files_differ',
|
||||
'BUILD_SNAPSHOT_EXCLUDE',
|
||||
'rebuild_and_check',
|
||||
]
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
"""Shared helpers and constants for rebuild tests (test_rebuild*.py)."""
|
||||
|
||||
from .idf_utils import IdfPyFunc
|
||||
from .snapshot import get_snapshot
|
||||
|
||||
# Paths excluded from mtime snapshots (volatile or external-project stamps).
|
||||
BUILD_SNAPSHOT_EXCLUDE = [
|
||||
'build/log/*',
|
||||
'build/CMakeFiles/bootloader-complete',
|
||||
'build/bootloader-prefix/src/bootloader-stamp/bootloader-done',
|
||||
]
|
||||
|
||||
|
||||
def rebuild_and_check(
|
||||
idf_py: IdfPyFunc, should_be_rebuilt: str | list[str], should_not_be_rebuilt: str | list[str]
|
||||
) -> None:
|
||||
"""Assert that files matching *should_be_rebuilt* change and *should_not_be_rebuilt* stay the same after a build."""
|
||||
snapshot_should_be_rebuilt = get_snapshot(should_be_rebuilt)
|
||||
snapshot_should_not_be_rebuilt = get_snapshot(should_not_be_rebuilt)
|
||||
idf_py('build')
|
||||
snapshot_should_be_rebuilt.assert_different(get_snapshot(should_be_rebuilt))
|
||||
snapshot_should_not_be_rebuilt.assert_same(get_snapshot(should_not_be_rebuilt))
|
||||
@@ -0,0 +1,80 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from test_build_system_helpers import IdfPyFunc
|
||||
from test_build_system_helpers import append_to_file
|
||||
from test_build_system_helpers import bin_file_contains
|
||||
from test_build_system_helpers import get_snapshot
|
||||
from test_build_system_helpers import replace_in_file
|
||||
|
||||
CONFIGDEP_TEST_APP = 'tools/test_build_system/configdep_test_app'
|
||||
|
||||
_MAIN_OBJ_DIR = ('build', 'esp-idf', 'main', 'CMakeFiles', '__idf_main.dir')
|
||||
MAIN_OBJ = os.path.join(*_MAIN_OBJ_DIR, 'configdep_main.c.obj')
|
||||
UNRELATED_OBJ = os.path.join(*_MAIN_OBJ_DIR, 'unrelated.c.obj')
|
||||
CONFIGDEP_ELF = Path(os.path.join('build', 'configdep_test_app.elf'))
|
||||
|
||||
|
||||
@pytest.mark.test_app_copy(CONFIGDEP_TEST_APP)
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_configdep_selective_rebuild(idf_py: IdfPyFunc) -> None:
|
||||
"""Verify selective rebuild when a Kconfig option toggles.
|
||||
|
||||
``esp-idf-configdep`` scans each translation unit's source for ``CONFIG_*``
|
||||
tokens and appends matching ``.cdep`` stubs to the compiler depfile. Avoid
|
||||
spelling projbuild-only symbols (even in comments) in ``unrelated.c``, or the
|
||||
scanner adds a spurious ``option.cdep`` edge and Ninja rebuilds that ``.obj``.
|
||||
"""
|
||||
logging.info('initial build with configdep enabled (default)')
|
||||
idf_py('build')
|
||||
|
||||
logging.info('toggle CONFIG_TEST_CONFIGDEP_OPTION from y to n')
|
||||
replace_in_file('sdkconfig', 'CONFIG_TEST_CONFIGDEP_OPTION=y', '# CONFIG_TEST_CONFIGDEP_OPTION is not set')
|
||||
|
||||
snapshot_main = get_snapshot(MAIN_OBJ)
|
||||
snapshot_unrelated = get_snapshot(UNRELATED_OBJ)
|
||||
|
||||
logging.info('rebuild after config change')
|
||||
idf_py('build')
|
||||
|
||||
logging.info('configdep_main.c.obj must be rebuilt (references changed option)')
|
||||
snapshot_main.assert_different(get_snapshot(MAIN_OBJ))
|
||||
|
||||
logging.info('unrelated.c.obj must not be rebuilt (no CONFIG_* token for that option in source)')
|
||||
snapshot_unrelated.assert_same(get_snapshot(UNRELATED_OBJ))
|
||||
|
||||
|
||||
@pytest.mark.test_app_copy(CONFIGDEP_TEST_APP)
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_configdep_no_rebuild_without_change(idf_py: IdfPyFunc) -> None:
|
||||
logging.info('initial build with configdep enabled (default)')
|
||||
idf_py('build')
|
||||
|
||||
snapshot_main = get_snapshot(MAIN_OBJ)
|
||||
snapshot_unrelated = get_snapshot(UNRELATED_OBJ)
|
||||
|
||||
logging.info('rebuild with no config changes')
|
||||
idf_py('build')
|
||||
|
||||
logging.info('neither object file should be rebuilt')
|
||||
snapshot_main.assert_same(get_snapshot(MAIN_OBJ))
|
||||
snapshot_unrelated.assert_same(get_snapshot(UNRELATED_OBJ))
|
||||
|
||||
|
||||
@pytest.mark.test_app_copy(CONFIGDEP_TEST_APP)
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_configdep_elf_strings_track_sdkconfig_toggle(idf_py: IdfPyFunc) -> None:
|
||||
"""After rebuild, the firmware string matches the final Kconfig (host-side ELF check)."""
|
||||
idf_py('build')
|
||||
assert CONFIGDEP_ELF.is_file()
|
||||
assert bin_file_contains(CONFIGDEP_ELF, b'CONFIGDEP_OPTION: ENABLED')
|
||||
assert not bin_file_contains(CONFIGDEP_ELF, b'CONFIGDEP_OPTION: DISABLED')
|
||||
|
||||
append_to_file('sdkconfig', '\n# CONFIG_TEST_CONFIGDEP_OPTION is not set\n')
|
||||
idf_py('build')
|
||||
assert bin_file_contains(CONFIGDEP_ELF, b'CONFIGDEP_OPTION: DISABLED')
|
||||
assert not bin_file_contains(CONFIGDEP_ELF, b'CONFIGDEP_OPTION: ENABLED')
|
||||
@@ -1,20 +1,51 @@
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# These tests check whether the build system rebuilds some files or not
|
||||
# depending on the changes to the project.
|
||||
# depending on the changes to the project. Configdep is disabled here so
|
||||
# mtime assertions reflect CMake/Ninja only; see test_rebuild_configdep.py for
|
||||
# the same checks with configdep enabled (after settle builds).
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import cast
|
||||
|
||||
import pytest
|
||||
from test_build_system_helpers import ALL_ARTIFACTS_BUILDV1
|
||||
from test_build_system_helpers import ALL_ARTIFACTS_BUILDV2
|
||||
from test_build_system_helpers import APP_BINS
|
||||
from test_build_system_helpers import BOOTLOADER_BINS
|
||||
from test_build_system_helpers import BUILD_SNAPSHOT_EXCLUDE
|
||||
from test_build_system_helpers import PARTITION_BIN
|
||||
from test_build_system_helpers import IdfPyFunc
|
||||
from test_build_system_helpers import get_idf_build_env
|
||||
from test_build_system_helpers import get_snapshot
|
||||
from test_build_system_helpers import rebuild_and_check
|
||||
from test_build_system_helpers import replace_in_file
|
||||
from test_build_system_helpers import run_idf_py
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def idf_py(monkeypatch: pytest.MonkeyPatch) -> IdfPyFunc:
|
||||
"""Use ``idf.py`` with esp-idf-configdep disabled for this module.
|
||||
|
||||
These tests assert Ninja rebuild granularity via file mtimes. The
|
||||
``esp-idf-configdep`` wrapper can create per-option ``.cdep`` stubs after the
|
||||
real compiler has written ``.obj`` files, so on the next Ninja run inputs can
|
||||
look newer than outputs and trigger spurious rebuilds. That behavior is
|
||||
covered separately in ``test_rebuild_configdep.py`` with a settle-build
|
||||
pattern. Here we exercise the core CMake/Ninja dependency graph only.
|
||||
"""
|
||||
monkeypatch.setenv('IDF_CONFIGDEP_ENABLE', '0')
|
||||
env = get_idf_build_env(os.environ['IDF_PATH'])
|
||||
|
||||
def result(*args: str, check: bool = True, input_str: str | None = None) -> subprocess.CompletedProcess[str]:
|
||||
return cast(
|
||||
subprocess.CompletedProcess[str],
|
||||
run_idf_py(*args, env=env, workdir=os.getcwd(), check=check, input_str=input_str),
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
@@ -23,14 +54,7 @@ def test_rebuild_no_changes(idf_py: IdfPyFunc, request: pytest.FixtureRequest) -
|
||||
idf_py('build')
|
||||
logging.info('get the first snapshot')
|
||||
# excluding the 'log' subdirectory here since it changes after every build
|
||||
all_build_files = get_snapshot(
|
||||
'build/**/*',
|
||||
exclude_patterns=[
|
||||
'build/log/*',
|
||||
'build/CMakeFiles/bootloader-complete',
|
||||
'build/bootloader-prefix/src/bootloader-stamp/bootloader-done',
|
||||
],
|
||||
)
|
||||
all_build_files = get_snapshot('build/**/*', exclude_patterns=BUILD_SNAPSHOT_EXCLUDE)
|
||||
|
||||
logging.info('check that all build artifacts were generated')
|
||||
all_artifacts = ALL_ARTIFACTS_BUILDV2 if request.config.getoption('buildv2', False) else ALL_ARTIFACTS_BUILDV1
|
||||
@@ -40,33 +64,10 @@ def test_rebuild_no_changes(idf_py: IdfPyFunc, request: pytest.FixtureRequest) -
|
||||
logging.info('build again with no changes')
|
||||
idf_py('build')
|
||||
# if there are no changes, nothing gets rebuilt
|
||||
all_build_files_after_rebuild = get_snapshot(
|
||||
'build/**/*',
|
||||
exclude_patterns=[
|
||||
'build/log/*',
|
||||
'build/CMakeFiles/bootloader-complete',
|
||||
'build/bootloader-prefix/src/bootloader-stamp/bootloader-done',
|
||||
],
|
||||
)
|
||||
all_build_files_after_rebuild = get_snapshot('build/**/*', exclude_patterns=BUILD_SNAPSHOT_EXCLUDE)
|
||||
all_build_files_after_rebuild.assert_same(all_build_files)
|
||||
|
||||
|
||||
def rebuild_and_check(
|
||||
idf_py: IdfPyFunc, should_be_rebuilt: str | list[str], should_not_be_rebuilt: str | list[str]
|
||||
) -> None:
|
||||
"""
|
||||
Helper function for the test cases below.
|
||||
Asserts that the files matching 'should_be_rebuilt' patterns are rebuilt
|
||||
and files matching 'should_not_be_rebuilt' patterns aren't, after
|
||||
touching (updating the mtime) of the given 'file_to_touch' and rebuilding.
|
||||
"""
|
||||
snapshot_should_be_rebuilt = get_snapshot(should_be_rebuilt)
|
||||
snapshot_should_not_be_rebuilt = get_snapshot(should_not_be_rebuilt)
|
||||
idf_py('build')
|
||||
snapshot_should_be_rebuilt.assert_different(get_snapshot(should_be_rebuilt))
|
||||
snapshot_should_not_be_rebuilt.assert_same(get_snapshot(should_not_be_rebuilt))
|
||||
|
||||
|
||||
# For this and the following test function, there are actually multiple logical
|
||||
# tests in one test function. It would be better to have every check in a separate
|
||||
# test case, but that would mean doing a full clean build each time. Having a few
|
||||
@@ -104,7 +105,7 @@ def test_rebuild_source_files(idf_py: IdfPyFunc) -> None:
|
||||
# pick on .c, .cpp, .S file which includes sdkconfig.h:
|
||||
obj_files = [
|
||||
'build/esp-idf/esp_libc/CMakeFiles/__idf_esp_libc.dir/newlib_init.c.obj',
|
||||
'build/esp-idf/nvs_flash/CMakeFiles/__idf_nvs_flash.dir/src/nvs_api.cpp.obj'
|
||||
'build/esp-idf/nvs_flash/CMakeFiles/__idf_nvs_flash.dir/src/nvs_api.cpp.obj',
|
||||
'build/esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/arch/xtensa/panic_handler_asm.S.obj',
|
||||
]
|
||||
sdkconfig_files = ['build/config/sdkconfig.h', 'build/config/sdkconfig.json']
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
"""Rebuild tests with esp-idf-configdep enabled (default idf.py behavior).
|
||||
|
||||
esp-idf-configdep rewrites compiler .d files to depend on per-option
|
||||
build/config/.../*.cdep stubs instead of sdkconfig.h. When a referenced
|
||||
.cdep file does not exist yet, the wrapper creates it **after** the real
|
||||
compiler has written the .obj. Those stubs then have a newer mtime than the
|
||||
object. On the **next** Ninja run, those .cdep paths are prerequisites in the
|
||||
merged dependency graph, so Ninja correctly treats the object as out of date and
|
||||
rebuilds it—even though nothing in the source tree or sdkconfig changed.
|
||||
|
||||
That one-time “settling” wave is not a CMake bug; it is an artifact of how
|
||||
configdep materializes stubs relative to object timestamps. The tests in
|
||||
test_rebuild.py therefore disable configdep to exercise pure CMake/Ninja
|
||||
incremental behavior. Here we keep configdep **on** and run **two** full
|
||||
idf.py build invocations before any mtime baseline so stub/object mtimes are
|
||||
consistent; then we apply the same coarse-grained checks as the classic rebuild
|
||||
tests (plus relaxed expectations where configdep legitimately skips compiling
|
||||
TUs that do not reference changed CONFIG_* symbols).
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from test_build_system_helpers import ALL_ARTIFACTS_BUILDV1
|
||||
from test_build_system_helpers import ALL_ARTIFACTS_BUILDV2
|
||||
from test_build_system_helpers import APP_BINS
|
||||
from test_build_system_helpers import BOOTLOADER_BINS
|
||||
from test_build_system_helpers import BUILD_SNAPSHOT_EXCLUDE
|
||||
from test_build_system_helpers import PARTITION_BIN
|
||||
from test_build_system_helpers import IdfPyFunc
|
||||
from test_build_system_helpers import get_snapshot
|
||||
from test_build_system_helpers import rebuild_and_check
|
||||
from test_build_system_helpers import replace_in_file
|
||||
|
||||
|
||||
def _settle_configdep_graph(idf_py: IdfPyFunc) -> None:
|
||||
"""Two full builds so ``.cdep`` stubs created by configdep are not newer than ``.obj`` for the next graph walk."""
|
||||
logging.info('settle (configdep): first full build')
|
||||
idf_py('build')
|
||||
logging.info('settle (configdep): second full build reconciles obj vs .cdep mtimes')
|
||||
idf_py('build')
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_rebuild_no_changes_with_configdep(idf_py: IdfPyFunc, request: pytest.FixtureRequest) -> None:
|
||||
"""No-op rebuild: with configdep on, baseline snapshot only after two settle builds (see module docstring)."""
|
||||
_settle_configdep_graph(idf_py)
|
||||
|
||||
logging.info('baseline snapshot after settle')
|
||||
all_build_files = get_snapshot('build/**/*', exclude_patterns=BUILD_SNAPSHOT_EXCLUDE)
|
||||
|
||||
logging.info('check that all build artifacts were generated')
|
||||
all_artifacts = ALL_ARTIFACTS_BUILDV2 if request.config.getoption('buildv2', False) else ALL_ARTIFACTS_BUILDV1
|
||||
for artifact in all_artifacts:
|
||||
assert Path(artifact).exists()
|
||||
|
||||
logging.info('noop build with configdep; mtimes under baseline should match')
|
||||
idf_py('build')
|
||||
all_build_files_after = get_snapshot('build/**/*', exclude_patterns=BUILD_SNAPSHOT_EXCLUDE)
|
||||
all_build_files_after.assert_same(all_build_files)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('test_app_copy')
|
||||
def test_rebuild_source_files_with_configdep(idf_py: IdfPyFunc) -> None:
|
||||
"""Same selective-rebuild checks as ``test_rebuild_source_files``, after configdep settle builds."""
|
||||
idf_path = Path(os.environ['IDF_PATH'])
|
||||
_settle_configdep_graph(idf_py)
|
||||
|
||||
logging.info('updating a component source file rebuilds only that component')
|
||||
component_files_patterns = [
|
||||
'build/esp-idf/esp_system/libesp_system.a',
|
||||
'build/esp-idf/esp_system/CMakeFiles/__idf_esp_system.dir/port/cpu_start.c.obj',
|
||||
]
|
||||
other_files_patterns = [
|
||||
'build/esp-idf/lwip/liblwip.a',
|
||||
'build/esp-idf/freertos/libfreertos.a',
|
||||
*BOOTLOADER_BINS,
|
||||
*PARTITION_BIN,
|
||||
]
|
||||
(idf_path / 'components/esp_system/port/cpu_start.c').touch()
|
||||
rebuild_and_check(idf_py, component_files_patterns, other_files_patterns)
|
||||
|
||||
logging.info('changing a bootloader source file rebuilds the bootloader')
|
||||
(idf_path / 'components/bootloader/subproject/main/bootloader_start.c').touch()
|
||||
rebuild_and_check(idf_py, BOOTLOADER_BINS, APP_BINS + PARTITION_BIN)
|
||||
|
||||
logging.info('changing the partitions CSV file rebuilds only the partition table')
|
||||
(idf_path / 'components/partition_table/partitions_singleapp.csv').touch()
|
||||
rebuild_and_check(idf_py, PARTITION_BIN, APP_BINS + BOOTLOADER_BINS)
|
||||
|
||||
logging.info(
|
||||
'sdkconfig update: binaries and generated headers must refresh (objects are selective under configdep)'
|
||||
)
|
||||
sdkconfig_files = ['build/config/sdkconfig.h', 'build/config/sdkconfig.json']
|
||||
replace_in_file('sdkconfig', '# CONFIG_FREERTOS_UNICORE is not set', 'CONFIG_FREERTOS_UNICORE=y')
|
||||
rebuild_and_check(idf_py, APP_BINS + BOOTLOADER_BINS + sdkconfig_files, PARTITION_BIN)
|
||||
|
||||
logging.info('Updating project CMakeLists.txt triggers app re-link at minimum')
|
||||
replace_in_file(
|
||||
'CMakeLists.txt',
|
||||
'# placeholder_after_include_project_cmake',
|
||||
'add_compile_options("-DUSELESS_MACRO_DOES_NOTHING=1")',
|
||||
)
|
||||
rebuild_and_check(idf_py, APP_BINS, PARTITION_BIN + BOOTLOADER_BINS + sdkconfig_files)
|
||||
@@ -65,6 +65,7 @@ NINJA = 'ninja'
|
||||
IDF_EXE = 'idf-exe'
|
||||
CCACHE = 'ccache'
|
||||
DFU_UTIL = 'dfu-util'
|
||||
ESP_IDF_CONFIGDEP = 'esp-idf-configdep'
|
||||
|
||||
|
||||
def get_version_dict():
|
||||
@@ -98,6 +99,7 @@ NINJA_VERSION = version_dict[NINJA]
|
||||
IDF_EXE_VERSION = version_dict[IDF_EXE]
|
||||
CCACHE_VERSION = version_dict[CCACHE]
|
||||
DFU_UTIL_VERSION = version_dict[DFU_UTIL]
|
||||
ESP_IDF_CONFIGDEP_VERSION = version_dict[ESP_IDF_CONFIGDEP]
|
||||
|
||||
# There are some complex search patterns to detect download snippets
|
||||
|
||||
@@ -383,7 +385,7 @@ class TestUsageUnix(TestUsage):
|
||||
self.assertIn(f'* {CLANGD}:', output)
|
||||
self.assertIn(f'- {CLANGD_VERSION} (recommended)', output)
|
||||
|
||||
required_tools_installed = 8
|
||||
required_tools_installed = 9
|
||||
output = self.run_idf_tools_with_action(['install'])
|
||||
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
|
||||
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
|
||||
@@ -393,6 +395,7 @@ class TestUsageUnix(TestUsage):
|
||||
self.assert_tool_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
|
||||
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
@@ -406,6 +409,7 @@ class TestUsageUnix(TestUsage):
|
||||
RISCV_ESP_GDB_VERSION,
|
||||
ESP_ROM_ELFS_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
|
||||
@@ -424,6 +428,11 @@ class TestUsageUnix(TestUsage):
|
||||
)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
|
||||
self.assertIn(
|
||||
f'{self.temp_tools_dir}/tools/{ESP_IDF_CONFIGDEP}/{ESP_IDF_CONFIGDEP_VERSION}/'
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}/bin',
|
||||
output,
|
||||
)
|
||||
|
||||
output = self.run_idf_tools_with_action(['list', '--outdated'])
|
||||
self.assertEqual('', output)
|
||||
@@ -451,7 +460,7 @@ class TestUsageUnix(TestUsage):
|
||||
self.assertIn((f'{XTENSA_ELF}: version {XTENSA_ELF_VERSION} is outdated by {new_version}'), output)
|
||||
|
||||
def test_tools_for_esp32(self):
|
||||
required_tools_installed = 6
|
||||
required_tools_installed = 7
|
||||
output = self.run_idf_tools_with_action(['install', '--targets=esp32'])
|
||||
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
|
||||
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
|
||||
@@ -461,6 +470,7 @@ class TestUsageUnix(TestUsage):
|
||||
self.assert_tool_not_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
|
||||
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
@@ -472,6 +482,7 @@ class TestUsageUnix(TestUsage):
|
||||
XTENSA_ESP_GDB_VERSION,
|
||||
ESP_ROM_ELFS_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
|
||||
@@ -490,9 +501,14 @@ class TestUsageUnix(TestUsage):
|
||||
)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
|
||||
self.assertIn(
|
||||
f'{self.temp_tools_dir}/tools/{ESP_IDF_CONFIGDEP}/{ESP_IDF_CONFIGDEP_VERSION}/'
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}/bin',
|
||||
output,
|
||||
)
|
||||
|
||||
def test_tools_for_esp32c3(self):
|
||||
required_tools_installed = 5
|
||||
required_tools_installed = 6
|
||||
output = self.run_idf_tools_with_action(['install', '--targets=esp32c3'])
|
||||
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
|
||||
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
|
||||
@@ -502,11 +518,18 @@ class TestUsageUnix(TestUsage):
|
||||
self.assert_tool_not_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
|
||||
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
output = self.run_idf_tools_with_action(['check'])
|
||||
for tool_version in [OPENOCD_VERSION, RISCV_ELF_VERSION, RISCV_ESP_GDB_VERSION, ESP_ROM_ELFS_VERSION]:
|
||||
for tool_version in [
|
||||
OPENOCD_VERSION,
|
||||
RISCV_ELF_VERSION,
|
||||
RISCV_ESP_GDB_VERSION,
|
||||
ESP_ROM_ELFS_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
|
||||
output = self.run_idf_tools_with_action(['export'])
|
||||
@@ -520,9 +543,14 @@ class TestUsageUnix(TestUsage):
|
||||
)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
|
||||
self.assertIn(
|
||||
f'{self.temp_tools_dir}/tools/{ESP_IDF_CONFIGDEP}/{ESP_IDF_CONFIGDEP_VERSION}/'
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}/bin',
|
||||
output,
|
||||
)
|
||||
|
||||
def test_tools_for_esp32s2(self):
|
||||
required_tools_installed = 7
|
||||
required_tools_installed = 8
|
||||
output = self.run_idf_tools_with_action(['install', '--targets=esp32s2'])
|
||||
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
|
||||
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
|
||||
@@ -532,11 +560,18 @@ class TestUsageUnix(TestUsage):
|
||||
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
|
||||
self.assert_tool_not_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
output = self.run_idf_tools_with_action(['check'])
|
||||
for tool_version in [OPENOCD_VERSION, XTENSA_ELF_VERSION, XTENSA_ESP_GDB_VERSION, ESP_ROM_ELFS_VERSION]:
|
||||
for tool_version in [
|
||||
OPENOCD_VERSION,
|
||||
XTENSA_ELF_VERSION,
|
||||
XTENSA_ESP_GDB_VERSION,
|
||||
ESP_ROM_ELFS_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
|
||||
output = self.run_idf_tools_with_action(['export'])
|
||||
@@ -554,9 +589,14 @@ class TestUsageUnix(TestUsage):
|
||||
)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
|
||||
self.assertIn(
|
||||
f'{self.temp_tools_dir}/tools/{ESP_IDF_CONFIGDEP}/{ESP_IDF_CONFIGDEP_VERSION}/'
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}/bin',
|
||||
output,
|
||||
)
|
||||
|
||||
def test_tools_for_esp32s3(self):
|
||||
required_tools_installed = 7
|
||||
required_tools_installed = 8
|
||||
output = self.run_idf_tools_with_action(['install', '--targets=esp32s3'])
|
||||
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
|
||||
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
|
||||
@@ -566,6 +606,7 @@ class TestUsageUnix(TestUsage):
|
||||
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
|
||||
self.assert_tool_not_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
@@ -577,6 +618,7 @@ class TestUsageUnix(TestUsage):
|
||||
RISCV_ESP_GDB_VERSION,
|
||||
ESP_ROM_ELFS_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
|
||||
@@ -595,9 +637,14 @@ class TestUsageUnix(TestUsage):
|
||||
)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
|
||||
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
|
||||
self.assertIn(
|
||||
f'{self.temp_tools_dir}/tools/{ESP_IDF_CONFIGDEP}/{ESP_IDF_CONFIGDEP_VERSION}/'
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}/bin',
|
||||
output,
|
||||
)
|
||||
|
||||
def test_tools_for_esp32p4(self):
|
||||
required_tools_installed = 5
|
||||
required_tools_installed = 6
|
||||
output = self.run_idf_tools_with_action(['install', '--targets=esp32p4'])
|
||||
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
|
||||
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
|
||||
@@ -607,10 +654,17 @@ class TestUsageUnix(TestUsage):
|
||||
self.assert_tool_not_installed(output, ESP32ULP, ESP32ULP_VERSION)
|
||||
self.assert_tool_not_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
output = self.run_idf_tools_with_action(['check'])
|
||||
for tool_version in [OPENOCD_VERSION, RISCV_ELF_VERSION, ESP_ROM_ELFS_VERSION, RISCV_ESP_GDB_VERSION]:
|
||||
for tool_version in [
|
||||
OPENOCD_VERSION,
|
||||
RISCV_ELF_VERSION,
|
||||
ESP_ROM_ELFS_VERSION,
|
||||
RISCV_ESP_GDB_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn(f'version installed in tools directory: {tool_version}', output)
|
||||
|
||||
output = self.run_idf_tools_with_action(['export'])
|
||||
@@ -623,6 +677,17 @@ class TestUsageUnix(TestUsage):
|
||||
os.path.join(self.temp_tools_dir, 'tools', RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION, RISCV_ESP_GDB, 'bin'),
|
||||
output,
|
||||
)
|
||||
self.assertIn(
|
||||
os.path.join(
|
||||
self.temp_tools_dir,
|
||||
'tools',
|
||||
ESP_IDF_CONFIGDEP,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}',
|
||||
'bin',
|
||||
),
|
||||
output,
|
||||
)
|
||||
self.assertNotIn(
|
||||
os.path.join(self.temp_tools_dir, 'tools', ESP32ULP, ESP32ULP_VERSION, ESP32ULP, 'bin'), output
|
||||
)
|
||||
@@ -637,7 +702,7 @@ class TestUsageUnix(TestUsage):
|
||||
|
||||
# a different test for qemu because of "on_request"
|
||||
def test_tools_for_qemu_with_required(self):
|
||||
required_tools_installed = 10
|
||||
required_tools_installed = 11
|
||||
output = self.run_idf_tools_with_action(['install', 'required', 'qemu-xtensa', 'qemu-riscv32'])
|
||||
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
|
||||
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
|
||||
@@ -646,6 +711,7 @@ class TestUsageUnix(TestUsage):
|
||||
self.assert_tool_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
|
||||
self.assert_tool_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
|
||||
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assert_tool_installed(output, QEMU_RISCV, QEMU_RISCV_VERSION)
|
||||
self.assert_tool_installed(output, QEMU_XTENSA, QEMU_XTENSA_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
@@ -675,7 +741,8 @@ class TestUsageWin(TestUsage):
|
||||
self.assertIn(f'- {XTENSA_ELF_VERSION} (recommended)', output)
|
||||
self.assertIn(f'* {CLANGD}:', output)
|
||||
self.assertIn(f'- {CLANGD_VERSION} (recommended)', output)
|
||||
required_tools_installed = 12
|
||||
|
||||
required_tools_installed = 13
|
||||
output = self.run_idf_tools_with_action(['install'])
|
||||
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
|
||||
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
|
||||
@@ -690,6 +757,7 @@ class TestUsageWin(TestUsage):
|
||||
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
|
||||
self.assert_tool_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
@@ -708,6 +776,7 @@ class TestUsageWin(TestUsage):
|
||||
CCACHE_VERSION,
|
||||
DFU_UTIL_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
|
||||
@@ -749,6 +818,17 @@ class TestUsageWin(TestUsage):
|
||||
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
|
||||
)
|
||||
self.assertIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
|
||||
self.assertIn(
|
||||
os.path.join(
|
||||
self.temp_tools_dir,
|
||||
'tools',
|
||||
ESP_IDF_CONFIGDEP,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}',
|
||||
'bin',
|
||||
),
|
||||
output,
|
||||
)
|
||||
|
||||
output = self.run_idf_tools_with_action(['list', '--outdated'])
|
||||
self.assertEqual('', output)
|
||||
@@ -791,6 +871,7 @@ class TestUsageWin(TestUsage):
|
||||
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
|
||||
self.assert_tool_not_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
@@ -806,6 +887,7 @@ class TestUsageWin(TestUsage):
|
||||
IDF_EXE_VERSION,
|
||||
CCACHE_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
self.assertNotIn('version installed in tools directory: ' + DFU_UTIL_VERSION, output)
|
||||
@@ -856,6 +938,17 @@ class TestUsageWin(TestUsage):
|
||||
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
|
||||
)
|
||||
self.assertNotIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
|
||||
self.assertIn(
|
||||
os.path.join(
|
||||
self.temp_tools_dir,
|
||||
'tools',
|
||||
ESP_IDF_CONFIGDEP,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}',
|
||||
'bin',
|
||||
),
|
||||
output,
|
||||
)
|
||||
|
||||
def test_tools_for_esp32c3_win(self):
|
||||
required_tools_installed = 9
|
||||
@@ -873,6 +966,7 @@ class TestUsageWin(TestUsage):
|
||||
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
|
||||
self.assert_tool_not_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
@@ -887,6 +981,7 @@ class TestUsageWin(TestUsage):
|
||||
IDF_EXE_VERSION,
|
||||
CCACHE_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
self.assertNotIn('version installed in tools directory: ' + DFU_UTIL_VERSION, output)
|
||||
@@ -931,6 +1026,17 @@ class TestUsageWin(TestUsage):
|
||||
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
|
||||
)
|
||||
self.assertNotIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
|
||||
self.assertIn(
|
||||
os.path.join(
|
||||
self.temp_tools_dir,
|
||||
'tools',
|
||||
ESP_IDF_CONFIGDEP,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}',
|
||||
'bin',
|
||||
),
|
||||
output,
|
||||
)
|
||||
|
||||
def test_tools_for_esp32s2_win(self):
|
||||
required_tools_installed = 12
|
||||
@@ -948,6 +1054,7 @@ class TestUsageWin(TestUsage):
|
||||
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
|
||||
self.assert_tool_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
@@ -963,6 +1070,7 @@ class TestUsageWin(TestUsage):
|
||||
IDF_EXE_VERSION,
|
||||
CCACHE_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
|
||||
@@ -1012,6 +1120,17 @@ class TestUsageWin(TestUsage):
|
||||
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
|
||||
)
|
||||
self.assertIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
|
||||
self.assertIn(
|
||||
os.path.join(
|
||||
self.temp_tools_dir,
|
||||
'tools',
|
||||
ESP_IDF_CONFIGDEP,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}',
|
||||
'bin',
|
||||
),
|
||||
output,
|
||||
)
|
||||
|
||||
def test_tools_for_esp32s3_win(self):
|
||||
required_tools_installed = 12
|
||||
@@ -1030,6 +1149,7 @@ class TestUsageWin(TestUsage):
|
||||
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
|
||||
self.assert_tool_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
@@ -1046,6 +1166,7 @@ class TestUsageWin(TestUsage):
|
||||
IDF_EXE_VERSION,
|
||||
CCACHE_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn('version installed in tools directory: ' + tool_version, output)
|
||||
|
||||
@@ -1095,6 +1216,17 @@ class TestUsageWin(TestUsage):
|
||||
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
|
||||
)
|
||||
self.assertIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
|
||||
self.assertIn(
|
||||
os.path.join(
|
||||
self.temp_tools_dir,
|
||||
'tools',
|
||||
ESP_IDF_CONFIGDEP,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}',
|
||||
'bin',
|
||||
),
|
||||
output,
|
||||
)
|
||||
|
||||
def test_tools_for_esp32p4_win(self):
|
||||
required_tools_installed = 9
|
||||
@@ -1112,6 +1244,7 @@ class TestUsageWin(TestUsage):
|
||||
self.assert_tool_not_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
|
||||
self.assert_tool_not_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
output = self.run_idf_tools_with_action(['check'])
|
||||
@@ -1125,6 +1258,7 @@ class TestUsageWin(TestUsage):
|
||||
IDF_EXE_VERSION,
|
||||
CCACHE_VERSION,
|
||||
CLANGD_VERSION,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
]:
|
||||
self.assertIn(f'version installed in tools directory: {tool_version}', output)
|
||||
|
||||
@@ -1144,6 +1278,17 @@ class TestUsageWin(TestUsage):
|
||||
self.assertIn(
|
||||
os.path.join(self.temp_tools_dir, 'tools', CCACHE, CCACHE_VERSION, 'ccache-4.12.1-windows-x86_64'), output
|
||||
)
|
||||
self.assertIn(
|
||||
os.path.join(
|
||||
self.temp_tools_dir,
|
||||
'tools',
|
||||
ESP_IDF_CONFIGDEP,
|
||||
ESP_IDF_CONFIGDEP_VERSION,
|
||||
f'{ESP_IDF_CONFIGDEP}-{ESP_IDF_CONFIGDEP_VERSION}',
|
||||
'bin',
|
||||
),
|
||||
output,
|
||||
)
|
||||
self.assertNotIn(
|
||||
os.path.join(self.temp_tools_dir, 'tools', XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF, 'bin'), output
|
||||
)
|
||||
@@ -1178,6 +1323,7 @@ class TestUsageWin(TestUsage):
|
||||
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
|
||||
self.assert_tool_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
|
||||
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
|
||||
self.assert_tool_installed(output, ESP_IDF_CONFIGDEP, ESP_IDF_CONFIGDEP_VERSION)
|
||||
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
|
||||
self.assertEqual(required_tools_installed, output.count('Done'))
|
||||
|
||||
|
||||
@@ -1150,6 +1150,79 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "ESP-IDF configuration dependency tool",
|
||||
"export_paths": [
|
||||
[
|
||||
"esp-idf-configdep-0.2.2",
|
||||
"bin"
|
||||
]
|
||||
],
|
||||
"export_vars": {},
|
||||
"info_url": "https://github.com/espressif/esp-idf-configdep",
|
||||
"install": "always",
|
||||
"license": "Apache-2.0",
|
||||
"name": "esp-idf-configdep",
|
||||
"supported_targets": [
|
||||
"all"
|
||||
],
|
||||
"version_cmd": [
|
||||
"esp-idf-configdep",
|
||||
"--version"
|
||||
],
|
||||
"version_regex": "version: ([0-9.]+)",
|
||||
"versions": [
|
||||
{
|
||||
"linux-amd64": {
|
||||
"sha256": "999aa895c25d5c7edb6823884d3017f146b133f7ae2c580fffe4c989d7ce8c36",
|
||||
"size": 28505,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-linux-x86_64.tar.gz"
|
||||
},
|
||||
"linux-arm64": {
|
||||
"sha256": "0ea8f5e0de463ecfa3354a27b32ba34c4b999570e92127952fe7363f034ab7e9",
|
||||
"size": 59608,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-linux-arm64.tar.gz"
|
||||
},
|
||||
"linux-armel": {
|
||||
"sha256": "0e1663a6f9d8c030f11feb214aab0ffc3b9f6029ebc7ce10cad974db13667632",
|
||||
"size": 36797,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-linux-armel.tar.gz"
|
||||
},
|
||||
"linux-armhf": {
|
||||
"sha256": "98759c0a16e56ec96cc72f2d6b60d2f548194cfcc2adde11cd65c694241912b6",
|
||||
"size": 34310,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-linux-armhf.tar.gz"
|
||||
},
|
||||
"linux-i686": {
|
||||
"sha256": "e337582b1570ac90fcfde0b724e41d62b01581ec0a755c97ac38024c5def55ac",
|
||||
"size": 32114,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-linux-x86.tar.gz"
|
||||
},
|
||||
"macos": {
|
||||
"sha256": "8e7ad2fd91214219c276c6b371f0cd3e315f22055554d60856e88d84eb6422e9",
|
||||
"size": 12755,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-macos-x86_64.tar.gz"
|
||||
},
|
||||
"macos-arm64": {
|
||||
"sha256": "458fa0e3193184ca6360bf35058c63e763545f0ef6cb0b659b01985a5dfafdbf",
|
||||
"size": 13023,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-macos-arm64.tar.gz"
|
||||
},
|
||||
"name": "0.2.2",
|
||||
"status": "recommended",
|
||||
"win32": {
|
||||
"sha256": "6bec5711daa5196df8ec3fa2d3c2c79623e7dc6cb5e0b6cede03ef49b71ac6ac",
|
||||
"size": 114156,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-win-x86.zip"
|
||||
},
|
||||
"win64": {
|
||||
"sha256": "1827c449c9294036f94fa82f5da65f10be1edbc2de6920ce9837cbee1393cac8",
|
||||
"size": 117734,
|
||||
"url": "https://github.com/espressif/esp-idf-configdep/releases/download/v0.2.2/esp-idf-configdep-0.2.2-win-x86_64.zip"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 3
|
||||
|
||||
Reference in New Issue
Block a user