mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(cmakev2): Added conditional_component example for cmakev2
This commit adds a new example at examples/build_system/cmakev2/features/conditional_components to demonstrate the cmakev2 ability to conditionally include components in the build based on Kconfig options.
This commit is contained in:
@@ -158,6 +158,15 @@ Demonstrates link-time plugin registration using whole-archive linking and const
|
||||
|
||||
---
|
||||
|
||||
### conditional_component
|
||||
**Location:** [conditional_component](./features/conditional_component/)
|
||||
|
||||
Demonstrates the use of the Kconfig configuration system to conditionally include or exclude components in the build.
|
||||
|
||||
**Key Concepts:** Kconfig configuration, `idf_component_include()`
|
||||
|
||||
**When to use:** When you need to build applications or components that must conditionally depend on other components based on `sdkconfig` options.
|
||||
|
||||
## Build System v2 API Quick Reference
|
||||
|
||||
### Project Setup
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# This example demonstrates conditional component inclusion with Build System v2
|
||||
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmakev2/idf.cmake)
|
||||
|
||||
project(conditional_component C CXX ASM)
|
||||
|
||||
# Initialize the project
|
||||
idf_project_init()
|
||||
|
||||
# Build the executable.
|
||||
# main component provides the main function and conditionally
|
||||
# includes logging_util and math_util. esptool_py is required
|
||||
# for binary generation.
|
||||
idf_build_executable(${CMAKE_PROJECT_NAME}.elf
|
||||
COMPONENTS main esptool_py)
|
||||
|
||||
# Generate binary from executable
|
||||
idf_build_binary(${CMAKE_PROJECT_NAME}.elf
|
||||
OUTPUT_FILE "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.bin"
|
||||
TARGET ${CMAKE_PROJECT_NAME}_binary)
|
||||
|
||||
# Create flash target
|
||||
idf_flash_binary(${CMAKE_PROJECT_NAME}_binary
|
||||
TARGET app-flash
|
||||
NAME "app"
|
||||
FLASH)
|
||||
|
||||
# Check binary size
|
||||
idf_check_binary_size(${CMAKE_PROJECT_NAME}_binary)
|
||||
|
||||
# Create app target
|
||||
add_custom_target(app ALL DEPENDS ${CMAKE_PROJECT_NAME}_binary)
|
||||
|
||||
# Generate metadata
|
||||
idf_build_generate_metadata(BINARY ${CMAKE_PROJECT_NAME}_binary)
|
||||
|
||||
# Create utility targets for configuration
|
||||
idf_create_menuconfig(${CMAKE_PROJECT_NAME}.elf TARGET menuconfig)
|
||||
idf_create_confserver(${CMAKE_PROJECT_NAME}.elf TARGET confserver)
|
||||
@@ -0,0 +1,41 @@
|
||||
| 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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
|
||||
|
||||
# Conditional Component Inclusion Example
|
||||
|
||||
This example demonstrates how to conditionally include components at build time using Build System v2's pure CMake approach. Components are included or excluded based on Kconfig configuration options, and all components are written using standard CMake functions rather than IDF-specific abstractions.
|
||||
|
||||
## Overview
|
||||
|
||||
In Build System v2, components can be written as plain CMake static libraries using `add_library`, `target_link_libraries`, and `target_include_directories`. A component is brought into the build on demand by calling `idf_component_include()`, which sets up the component's target name and invokes its CMakeLists.txt. Dependencies on other components are expressed using the `idf::<name>` alias targets.
|
||||
|
||||
This example uses that mechanism to conditionally pull in two utility components — `logging_util` and `math_util` — from within the `main` component, based on Kconfig options.
|
||||
|
||||
## Project Structure
|
||||
|
||||
The project is initialized manually with `idf_project_init()` and `idf_build_executable()`, which gives precise control over which components are seeded into the build. The `main` component itself is a pure CMake static library. It conditionally includes `logging_util` and/or `math_util` at configure time by calling `idf_component_include()` inside `if(CONFIG_...)` guards and linking the resulting targets with `target_link_libraries`.
|
||||
|
||||
`logging_util` depends on IDF's `log` component for `ESP_LOG*` macros. It pulls `log` into the build with `idf_component_include(log)` and links it via the `idf::log` alias target. `math_util` has no IDF dependencies and is a self-contained static library.
|
||||
|
||||
## Configuration Options
|
||||
|
||||
Two Kconfig options control which components are included:
|
||||
|
||||
- `CONFIG_EXAMPLE_ENABLE_LOGGING` — includes and links the `logging_util` component.
|
||||
- `CONFIG_EXAMPLE_ENABLE_MATH` — includes and links the `math_util` component.
|
||||
|
||||
Both default to enabled. Toggle them via menuconfig under **Conditional Component Example Configuration**.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
cd examples/build_system/cmakev2/conditional_component
|
||||
idf.py set-target <target>
|
||||
idf.py build
|
||||
```
|
||||
|
||||
To change which components are included, run `idf.py menuconfig` before rebuilding.
|
||||
|
||||
## Output
|
||||
|
||||
With both components enabled the serial output shows info and warning log messages from `logging_util` and the results of add, subtract, and multiply operations from `math_util`. Disabling either option removes the corresponding section and replaces it with a "DISABLED" message.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
# This component provides the logging utility functions.
|
||||
|
||||
# Explicitly pull in the IDF log component before using it.
|
||||
idf_component_include(log)
|
||||
|
||||
add_library(${COMPONENT_TARGET} STATIC logging_util.c)
|
||||
target_include_directories(${COMPONENT_TARGET} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_link_libraries(${COMPONENT_TARGET} PRIVATE idf::log)
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Log an informational message
|
||||
*
|
||||
* @param message The message to log
|
||||
*/
|
||||
void log_info(const char *message);
|
||||
|
||||
/**
|
||||
* @brief Log a warning message
|
||||
*
|
||||
* @param message The message to log
|
||||
*/
|
||||
void log_warn(const char *message);
|
||||
|
||||
/**
|
||||
* @brief Log an error message
|
||||
*
|
||||
* @param message The message to log
|
||||
*/
|
||||
void log_error(const char *message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "logging_util.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "logging_util";
|
||||
|
||||
void log_info(const char *message)
|
||||
{
|
||||
ESP_LOGI(TAG, "%s", message);
|
||||
}
|
||||
|
||||
void log_warn(const char *message)
|
||||
{
|
||||
ESP_LOGW(TAG, "%s", message);
|
||||
}
|
||||
|
||||
void log_error(const char *message)
|
||||
{
|
||||
ESP_LOGE(TAG, "%s", message);
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# This component provides the math utility functions.
|
||||
add_library(${COMPONENT_TARGET} STATIC math_util.c)
|
||||
target_include_directories(${COMPONENT_TARGET} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Add two integers
|
||||
*
|
||||
* @param a First operand
|
||||
* @param b Second operand
|
||||
* @return Sum of a and b
|
||||
*/
|
||||
int math_add(int a, int b);
|
||||
|
||||
/**
|
||||
* @brief Subtract two integers
|
||||
*
|
||||
* @param a First operand
|
||||
* @param b Second operand
|
||||
* @return a minus b
|
||||
*/
|
||||
int math_subtract(int a, int b);
|
||||
|
||||
/**
|
||||
* @brief Multiply two integers
|
||||
*
|
||||
* @param a First operand
|
||||
* @param b Second operand
|
||||
* @return Product of a and b
|
||||
*/
|
||||
int math_multiply(int a, int b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "math_util.h"
|
||||
|
||||
int math_add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int math_subtract(int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
int math_multiply(int a, int b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# This component provides the main function and conditionally
|
||||
# includes logging_util and math_util based on the Kconfig options.
|
||||
|
||||
# Provide the main component as a static library
|
||||
add_library(${COMPONENT_TARGET} STATIC main.c)
|
||||
|
||||
if(CONFIG_EXAMPLE_ENABLE_LOGGING)
|
||||
idf_component_include(logging_util)
|
||||
target_link_libraries(${COMPONENT_TARGET} PRIVATE idf::logging_util)
|
||||
idf_msg("Conditional component 'logging_util' is ENABLED")
|
||||
else()
|
||||
idf_msg("Conditional component 'logging_util' is DISABLED")
|
||||
endif()
|
||||
|
||||
if(CONFIG_EXAMPLE_ENABLE_MATH)
|
||||
idf_component_include(math_util)
|
||||
target_link_libraries(${COMPONENT_TARGET} PRIVATE idf::math_util)
|
||||
idf_msg("Conditional component 'math_util' is ENABLED")
|
||||
else()
|
||||
idf_msg("Conditional component 'math_util' is DISABLED")
|
||||
endif()
|
||||
@@ -0,0 +1,17 @@
|
||||
menu "Conditional Component Example Configuration"
|
||||
|
||||
config EXAMPLE_ENABLE_LOGGING
|
||||
bool "Enable Logging Utility Component"
|
||||
default y
|
||||
help
|
||||
Enable the logging_util component to demonstrate conditional
|
||||
component inclusion in Build System v2.
|
||||
|
||||
config EXAMPLE_ENABLE_MATH
|
||||
bool "Enable Math Utility Component"
|
||||
default y
|
||||
help
|
||||
Enable the math_util component to demonstrate conditional
|
||||
component inclusion in Build System v2.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_LOGGING
|
||||
#include "logging_util.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_MATH
|
||||
#include "math_util.h"
|
||||
#endif
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
printf("Conditional Component Example\n");
|
||||
printf("==============================\n\n");
|
||||
|
||||
printf("This example demonstrates Build System v2's idf_component_include()\n");
|
||||
printf("function for conditional component inclusion.\n\n");
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_LOGGING
|
||||
printf("Logging component is ENABLED\n");
|
||||
log_info("This is an info message from logging_util");
|
||||
log_warn("This is a warning message from logging_util");
|
||||
#else
|
||||
printf("Logging component is DISABLED\n");
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_ENABLE_MATH
|
||||
printf("Math component is ENABLED\n");
|
||||
int a = 10, b = 5;
|
||||
printf(" add(%d, %d) = %d\n", a, b, math_add(a, b));
|
||||
printf(" subtract(%d, %d) = %d\n", a, b, math_subtract(a, b));
|
||||
printf(" multiply(%d, %d) = %d\n", a, b, math_multiply(a, b));
|
||||
#else
|
||||
printf("Math component is DISABLED\n");
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
printf("You can change the component configuration via menuconfig:\n");
|
||||
printf(" idf.py menuconfig -> Conditional Component Example Configuration\n");
|
||||
}
|
||||
Reference in New Issue
Block a user