mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
feat(cmakev2/component): add OPTIONAL flag to idf_component_include
Add an OPTIONAL flag to idf_component_include so callers can ask
"include this component if it exists" without aborting the build
when the component is unknown.
Without OPTIONAL, the function behaves exactly as before -- it
calls __get_component_interface_or_die and the build aborts on a
miss. With OPTIONAL, the function performs a non-fatal interface
lookup and returns silently if the component is not known. When
combined with INTERFACE <variable>, the variable is set to the
empty string on miss and to the component's interface target on
hit, so callers can write:
idf_component_include(button OPTIONAL INTERFACE button_iface)
if(button_iface)
target_sources(${COMPONENT_TARGET} PRIVATE button_glue.c)
target_link_libraries(${COMPONENT_TARGET} PRIVATE ${button_iface})
endif()
This gives consumers a public, non-fatal way to wire up integrations
with components that may or may not be in the build (managed
dependencies pulled in only by some board configurations, optional
feature glue, etc.) without reaching into the private
__get_component_interface helper or doing dual-namespace
COMPONENTS_DISCOVERED checks against both <name> and <ns>__<name>
forms.
Backward compatible: existing call sites do not pass OPTIONAL and
continue to fail loudly on miss.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
This commit is contained in:
@@ -807,12 +807,20 @@ endfunction()
|
||||
.. code-block:: cmake
|
||||
|
||||
idf_component_include(<name>
|
||||
[OPTIONAL]
|
||||
[INTERFACE <variable>])
|
||||
|
||||
*name[in]*
|
||||
|
||||
Component name.
|
||||
|
||||
*OPTIONAL[opt]*
|
||||
|
||||
If specified, the call is a silent no-op when the component is not
|
||||
known to the build, instead of aborting. When combined with
|
||||
``INTERFACE``, the output variable is set to the empty string on
|
||||
miss, so callers can use ``if(${variable})`` as a truth check.
|
||||
|
||||
*INTERFACE[out,opt]*
|
||||
|
||||
Optional variable where the name of the target interface for the
|
||||
@@ -830,15 +838,41 @@ endfunction()
|
||||
|
||||
When the ``INTERFACE`` variable is provided, the name of the included
|
||||
component interface target will be stored in it.
|
||||
|
||||
By default, the function aborts the build if ``<name>`` is not known to
|
||||
the build system. Pass ``OPTIONAL`` to make the call non-fatal -- useful
|
||||
for integrations with components that may or may not be in the build,
|
||||
such as managed dependencies that only some board configurations pull
|
||||
in.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
# Wire up an optional integration only when the component is present.
|
||||
idf_component_include(button OPTIONAL INTERFACE button_iface)
|
||||
if(button_iface)
|
||||
target_sources(${COMPONENT_TARGET} PRIVATE button_glue.c)
|
||||
target_link_libraries(${COMPONENT_TARGET} PRIVATE ${button_iface})
|
||||
endif()
|
||||
#]]
|
||||
function(idf_component_include name)
|
||||
set(options)
|
||||
set(options OPTIONAL)
|
||||
set(one_value INTERFACE)
|
||||
set(multi_value)
|
||||
cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN})
|
||||
|
||||
__get_component_interface_or_die(COMPONENT "${name}"
|
||||
OUTPUT component_interface)
|
||||
if(ARG_OPTIONAL)
|
||||
__get_component_interface(COMPONENT "${name}"
|
||||
OUTPUT component_interface)
|
||||
if("${component_interface}" STREQUAL "NOTFOUND")
|
||||
if(DEFINED ARG_INTERFACE)
|
||||
set(${ARG_INTERFACE} "" PARENT_SCOPE)
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
__get_component_interface_or_die(COMPONENT "${name}"
|
||||
OUTPUT component_interface)
|
||||
endif()
|
||||
|
||||
# Check if the component is already included, meaning the add_subdirectory
|
||||
# has already been called for it and the component has been processed. If
|
||||
|
||||
Reference in New Issue
Block a user