diff --git a/examples/build_system/cmake/import_lib/main/import_lib_example_main.cpp b/examples/build_system/cmake/import_lib/main/import_lib_example_main.cpp index 0e9ecb3ba4..069296cb03 100644 --- a/examples/build_system/cmake/import_lib/main/import_lib_example_main.cpp +++ b/examples/build_system/cmake/import_lib/main/import_lib_example_main.cpp @@ -7,7 +7,6 @@ #include "esp_log.h" #include "esp_vfs_fat.h" #include "tinyxml2.h" -#include "sdkconfig.h" // TODO IDF-11323: remove static const char *TAG = "example"; @@ -30,12 +29,11 @@ extern "C" void app_main(void) tinyxml2::XMLDocument data; data.LoadFile("/spiflash/sample.xml"); -#if !CONFIG_LIBC_PICOLIBC // TODO IDF-11323: subproject builds with default toolchain-esp*.cmake. No additional -specs=picolibc.specs applied tinyxml2::XMLPrinter printer; data.Print(&printer); ESP_LOGI(TAG, "Read XML data:\n%s", printer.CStr()); -#endif + const char* to_data = data.FirstChildElement("note")->FirstChildElement("to")->GetText(); const char* from_data = data.FirstChildElement("note")->FirstChildElement("from")->GetText(); const char* heading_data = data.FirstChildElement("note")->FirstChildElement("heading")->GetText(); diff --git a/tools/test_build_system/test_cmake.py b/tools/test_build_system/test_cmake.py index 4464a3d12e..1b944b7f5c 100644 --- a/tools/test_build_system/test_cmake.py +++ b/tools/test_build_system/test_cmake.py @@ -1,5 +1,6 @@ -# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 +import json import logging import os import re @@ -48,28 +49,60 @@ def test_build_custom_cmake_project_host() -> None: run_cmake_and_build(str(idf_path / 'examples' / 'build_system' / 'cmake' / 'idf_as_lib'), '-G', 'Ninja') -def test_build_cmake_library_psram_workaround(test_app_copy: Path) -> None: +def test_build_cmake_library_with_toolchain_flags(test_app_copy: Path) -> None: + logging.info('Building a project with CMake library imported with modified toolchain flags') + idf_path = Path(os.environ['IDF_PATH']) + + import_lib_path = idf_path / 'examples' / 'build_system' / 'cmake' / 'import_lib' + run_cmake_and_build( + str(import_lib_path), + '-G', + 'Ninja', + f'-DSDKCONFIG_DEFAULTS={import_lib_path / "sdkconfig.defaults"}', + ) + + +def check_flag_in_compile_commands(build_dir: Path, flag_to_find: str) -> None: + with open(build_dir / 'build' / 'compile_commands.json', encoding='utf-8') as f: + compile_commands = json.load(f) + # check if compile_commands is an array + if not isinstance(compile_commands, list): + assert False, f'compile_commands is not a list: {compile_commands}' + assert len(compile_commands) != 0, 'compile_commands is empty' + for entry in compile_commands: + command = entry['command'] + assert isinstance(command, str), f'command is not a string: {command}' + flag_is_found = flag_to_find in command + if flag_is_found: + continue # Flag found in command, no need to check response files + # check if command contains response file paths starts with @ + response_file_paths = re.findall(r'@([^\s]+)', command) + for response_file_path in response_file_paths: + # check if the flag file contains flag_to_find + try: + # Strip surrounding quotes and normalize the path + response_file_path = response_file_path.strip('"\'\\') + response_file_path = Path(response_file_path).resolve() + with open(response_file_path, encoding='utf-8') as f: + flags = f.read() + if flag_to_find in flags: + flag_is_found = True + break + except FileNotFoundError: + assert False, f'{response_file_path} does not exist' + if not flag_is_found: + assert False, f'{flag_to_find} not found in {command}' + + +def test_build_cmake_library_psram_workaround(idf_py: IdfPyFunc, test_app_copy: Path) -> None: logging.info( 'Building a project with CMake library imported and PSRAM workaround, all files compile with workaround' ) - idf_path = Path(os.environ['IDF_PATH']) (test_app_copy / 'sdkconfig.defaults').write_text( '\n'.join(['CONFIG_SPIRAM=y', 'CONFIG_SPIRAM_CACHE_WORKAROUND=y']) ) - run_cmake( - '-G', - 'Ninja', - '-DCOMPONENTS=main;esp_psram', - '-DSDKCONFIG_DEFAULTS={}'.format(test_app_copy / 'sdkconfig.defaults'), - str(idf_path / 'examples' / 'build_system' / 'cmake' / 'import_lib'), - ) - with open((test_app_copy / 'build' / 'compile_commands.json'), 'r', encoding='utf-8') as f: - data = f.read() - res = re.findall(r'.*\"command\".*', data) - for r in res: - assert 'mfix-esp32-psram-cache-issue' in r, ( - 'All commands in compile_commands.json should use PSRAM cache workaround' - ) + idf_py('reconfigure') + check_flag_in_compile_commands(test_app_copy, '-mfix-esp32-psram-cache-issue') def test_build_cmake_library_psram_strategies(idf_py: IdfPyFunc, test_app_copy: Path) -> None: @@ -85,13 +118,7 @@ def test_build_cmake_library_psram_strategies(idf_py: IdfPyFunc, test_app_copy: ) ) idf_py('reconfigure') - with open((test_app_copy / 'build' / 'compile_commands.json'), 'r', encoding='utf-8') as f: - data = f.read() - res = re.findall(r'.*\"command\".*', data) - for r in res: - assert f'mfix-esp32-psram-cache-strategy={strategy.lower()}' in r, ( - 'All commands in compile_commands.json should use PSRAM cache workaround strategy' - ) + check_flag_in_compile_commands(test_app_copy, f'-mfix-esp32-psram-cache-strategy={strategy.lower()}') (test_app_copy / 'sdkconfig').unlink()