Files
esp-idf/tools/cmakev2/test/CMakeLists.txt
T
Frantisek Hrbata e08aca162a feat(cmakev2/size): add idf_create_size_report function
The idf_create_size_report function allows for the creation of size
report targets based on the generated link map file. The size report
targets are created using the TARGET option name: "<target>",
"<target>-files", and "<target>-components". These size report targets
are added to the idf_default_project with the TARGET set to "size",
resulting in the creation of "size", "size-files", and "size-components"
targets for the default project.

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2025-11-19 11:35:36 +01:00

291 lines
10 KiB
CMake

# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
# Simple project for basic cmakev2 testing
# Run: cmake -S . -B build
cmake_minimum_required(VERSION 3.22)
include($ENV{IDF_PATH}/tools/cmakev2/idf.cmake)
project(cmakev2
VERSION 1.2.3
LANGUAGES C CXX ASM)
add_custom_target(flash)
idf_project_init()
# Test component priority
function(test_component_priority)
# Set the idf component to be replaced with a testing component of higher
# priority.
set(component_name "esp_system")
# Check that idf component is between discovered components.
__get_component_interface(COMPONENT "${component_name}"
OUTPUT component_interface)
if("${component_interface}" STREQUAL "NOTFOUND")
idf_die("Component '${component_name}' not found")
endif()
# Check that idf component has "idf_components" as source.
idf_component_get_property(component_source
${component_interface}
COMPONENT_SOURCE)
if(NOT "${component_source}" STREQUAL "idf_components")
idf_die("Unexpected idf component '${component_name}' source '${component_source}'")
endif()
# Create fake component with same name as idf component.
set(component_dir "${CMAKE_CURRENT_BINARY_DIR}/${component_name}")
file(MAKE_DIRECTORY "${component_dir}")
file(TOUCH "${component_dir}/CMakeLists.txt")
# Initialize fake component with higher "project_components" priority.
idf_build_get_property(component_prefix PREFIX)
__init_component(DIRECTORY "${component_dir}"
PREFIX "${component_prefix}"
SOURCE "project_components")
# Check that the idf component was replaced with fake component.
idf_component_get_property(component_source
${component_interface}
COMPONENT_SOURCE)
if(NOT "${component_source}" STREQUAL "project_components")
idf_die("Unexpected fake component '${component_name}' source '${component_source}'")
endif()
idf_component_get_property(component_dir
${component_interface}
COMPONENT_DIR)
if(NOT "${component_dir}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/${component_name}")
idf_die("Unexpected fake component '${component_name}' directory '${component_dir}'")
endif()
__dump_component_properties("${component_name}")
endfunction()
# Test that IDF_VERSION and IDF_VER build property is set
function(test_idf_version)
if(NOT DEFINED IDF_VERSION_MAJOR OR
NOT DEFINED IDF_VERSION_MINOR OR
NOT DEFINED IDF_VERSION_PATCH OR
NOT DEFINED ENV{IDF_VERSION})
idf_die("IDF_VERSION not set")
endif()
idf_build_get_property(idf_ver IDF_VER)
if(NOT idf_ver)
idf_die("IDF_VER build property not set")
endif()
endfunction()
# Test that Python interpreter is set
function(test_python)
if(NOT DEFINED PYTHON OR "${PYTHON}" STREQUAL "")
idf_die("PYTHON variable not defined or empty")
endif()
endfunction()
# Test that toolchain is properly set
function(test_toolchain)
if(NOT IDF_TOOLCHAIN)
idf_die("IDF_TOOLCHAIN variable not defined or empty")
endif()
if(NOT CMAKE_TOOLCHAIN_FILE)
idf_die("CMAKE_TOOLCHAIN_FILE variable not defined or empty")
endif()
idf_build_get_property(toolchain IDF_TOOLCHAIN)
if(NOT toolchain)
idf_die("IDF_TOOLCHAIN build property not set")
endif()
idf_build_get_property(toolchain_file IDF_TOOLCHAIN_FILE)
if(NOT toolchain_file)
idf_die("IDF_TOOLCHAIN_FILE build property not set")
endif()
endfunction()
# Test idf_build_library
function(test_idf_build_library)
# Create idflibtest with specific set of components and test that it
# contains them.
set(components app_trace app_update bootloader bootloader_support bt cmock)
set(idflib idflibtest)
idf_build_library("${idflib}" COMPONENTS "${components}")
if(NOT TARGET "${idflib}")
idf_die("'${idflib}' not created")
endif()
idf_library_get_property(lib_components "${idflib}" LIBRARY_COMPONENTS)
if(NOT "${lib_components}" STREQUAL "${components}")
idf_die("Library '${idflib}' components '${lib_components}' do not match "
"expected components '${components}'")
endif()
# Create idflibtest2 without specifying COMPONENTS and test that it
# contains all discovered components.
set(idflib idflibtest2)
idf_build_library("${idflib}")
if(NOT TARGET "${idflib}")
idf_die("'${idflib}' not created")
endif()
idf_library_get_property(lib_components "${idflib}" LIBRARY_COMPONENTS)
idf_build_get_property(component_names COMPONENTS_DISCOVERED)
if(NOT "${lib_components}" STREQUAL "${component_names}")
idf_die("Library '${idflib}' components '${lib_components}' do not match "
"COMPONENTS_DISCOVERED")
endif()
endfunction()
function(test_kconfig)
# Check that kconfig output files were generated
idf_build_get_property(config_dir CONFIG_DIR)
set(output_files sdkconfig.h sdkconfig.cmake sdkconfig.json)
foreach(file ${output_files})
set(file_path "${config_dir}/${file}")
if(NOT EXISTS "${file_path}")
idf_die("Missing kconfig output: ${file_path}")
endif()
file(SIZE "${file_path}" file_size)
if(file_size EQUAL 0)
idf_die("Empty kconfig output: ${file_path}")
endif()
endforeach()
# Check that kconfig targets were created
set(targets menuconfig confserver save-defconfig)
foreach(target ${targets})
if(NOT TARGET ${target})
idf_die("Missing kconfig target: ${target}")
endif()
endforeach()
endfunction()
# Test that PROJECT_NAME and PROJECT_VER build property is set and contain
# values provided in project() call.
function(test_project_properties)
idf_build_get_property(project_name PROJECT_NAME)
if(NOT project_name)
idf_die("PROJECT_NAME build property not set")
endif()
if(NOT "${project_name}" STREQUAL "${PROJECT_NAME}")
idf_die("PROJECT_NAME build property '${project_name}' != '${PROJECT_NAME}'")
endif()
idf_build_get_property(project_ver PROJECT_VER)
if(NOT project_ver)
idf_die("PROJECT_VER build property not set")
endif()
if(NOT "${project_ver}" STREQUAL "${PROJECT_VERSION}")
idf_die("PROJECT_VER build property '${project_ver}' != '${PROJECT_VERSION}'")
endif()
endfunction()
# Test that the targets for component1 and component2 are created when
# component2 is included.
function(test_include_component)
idf_build_library(idflibtest3 COMPONENTS component2)
idf_component_get_property(component_real_target
component2
COMPONENT_REAL_TARGET)
if(NOT TARGET ${component_real_target})
idf_die("Missing component2 target")
endif()
# Test that component1 is included as a dependency of component2.
idf_component_get_property(component_real_target
component1
COMPONENT_REAL_TARGET)
if(NOT TARGET ${component_real_target})
idf_die("Missing component1 target")
endif()
endfunction()
# Add two executables fatfs_example and hello_world_example, generate
# binary images for them and add flash and menuconfig targets.
# After configuration these can be build with
# idf.py hello_world_example_bin
# idf.py fatfs_example_bin
# or simply
# idf.py hello_world_example-flash monitor
# idf.py fatfs-flash monitor
# The menuconfig can be invoked with
# idf.py --no-hints menuconfig-hello_world
# idf.py --no-hints menuconfig-fatfs
# The confserver can be invoked with
# idf.py confserver-hello_world
# idf.py confserver-fatfs
function(test_executable)
idf_build_executable(fatfs_example
COMPONENTS fatfs_example
MAPFILE_TARGET fatfs_example_mapfile)
idf_build_binary(fatfs_example
TARGET fatfs_example_bin
OUTPUT_FILE fatfs_example.bin)
idf_check_binary_size(fatfs_example_bin)
idf_flash_binary(fatfs_example_bin
TARGET fatfs_example-flash
NAME fatfs_example)
idf_create_menuconfig(fatfs_example
TARGET menuconfig-fatfs)
idf_build_generate_metadata(fatfs_example_bin
OUTPUT_FILE project_description_fatfs.json)
idf_create_confserver(fatfs_example
TARGET confserver-fatfs)
if(TARGET fatfs_example_mapfile)
idf_create_size_report(fatfs_example_mapfile
TARGET fatfs-size)
endif()
idf_build_executable(hello_world_example
COMPONENTS hello_world_example
MAPFILE_TARGET hello_world_example_mapfile)
idf_build_binary(hello_world_example
TARGET hello_world_example_bin
OUTPUT_FILE hello_world_example.bin)
idf_check_binary_size(hello_world_example_bin)
idf_flash_binary(hello_world_example_bin
TARGET hello_world_example-flash
NAME hello_world_example)
idf_create_menuconfig(hello_world_example
TARGET menuconfig-hello_world)
idf_build_generate_metadata(hello_world_example_bin
OUTPUT_FILE project_description_hello_world.json)
idf_create_confserver(hello_world_example
TARGET confserver-hello_world)
if(TARGET hello_world_example_mapfile)
idf_create_size_report(hello_world_example_mapfile
TARGET hello-size)
endif()
endfunction()
# Run tests
test_idf_version()
test_python()
test_toolchain()
test_idf_build_library()
test_project_properties()
test_include_component()
test_executable()
# Create default project
idf_project_default()
# The kconfig test also verifies whether kconfig-related targets, such as
# menuconfig, are created. These targets are now generated within
# idf_project_default rather than globally, so this test should be run only
# after the default project is created.
test_kconfig()
# Call this test last because it replaces the ESP system component.
test_component_priority()
__dump_all_properties()
message("ALL TESTS PASSED")