Skip to content

Commit b3ef899

Browse files
committed
Merge branch 'feature/cmake_overriding_components_new_features' into 'master'
CMake: useful features for overriding components See merge request espressif/esp-idf!8220
2 parents 91d8c26 + 9950c7f commit b3ef899

File tree

4 files changed

+81
-4
lines changed

4 files changed

+81
-4
lines changed

docs/en/api-guides/build-system.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ The list of directories in ``COMPONENT_DIRS`` is searched for the project's comp
308308

309309
When CMake runs to configure the project, it logs the components included in the build. This list can be useful for debugging the inclusion/exclusion of certain components.
310310

311+
.. _cmake-components-same-name:
312+
311313
Multiple components with the same name
312314
--------------------------------------
313315

@@ -1266,7 +1268,9 @@ the first element/member instead.
12661268
[LDFRAGMENTS ldfragment1 ldfragment2 ...]
12671269
[REQUIRED_IDF_TARGETS target1 target2 ...]
12681270
[EMBED_FILES file1 file2 ...]
1269-
[EMBED_TXTFILES file1 file2 ...])
1271+
[EMBED_TXTFILES file1 file2 ...]
1272+
[KCONFIG kconfig]
1273+
[KCONFIG_PROJBUILD kconfig_projbuild])
12701274
12711275
Register a component to the build system. Much like the ``project()`` CMake command, this should be called from the component's
12721276
CMakeLists.txt directly (not through a function or macro) and is recommended to be called before any other command. Here are some
@@ -1289,6 +1293,8 @@ The arguments for ``idf_component_register`` include:
12891293
- PRIV_REQUIRES - private component requirements for the component; ignored on config-only components
12901294
- LDFRAGMENTS - component linker fragment files
12911295
- REQUIRED_IDF_TARGETS - specify the only target the component supports
1296+
- KCONFIG - override the default Kconfig file
1297+
- KCONFIG_PROJBUILD - override the default Kconfig.projbuild file
12921298

12931299
The following are used for :ref:`embedding data into the component<cmake_embed_data>`, and is considered as source files
12941300
when determining if a component is config-only. This means that even if the component does not specify source files, a static library is still
@@ -1313,6 +1319,7 @@ For example, to get the directory of the ``freertos`` component:
13131319
- COMPONENT_ALIAS - alias for COMPONENT_LIB used for linking the component to external targets; set by ``idf_build_component`` and alias library itself
13141320
is created by ``idf_component_register``
13151321
- COMPONENT_DIR - component directory; set by ``idf_build_component``
1322+
- COMPONENT_OVERRIDEN_DIR - contains the directory of the original component if ref:`this component overrides another component<cmake-components-same-name>`
13161323
- COMPONENT_LIB - name for created component static/interface library; set by ``idf_build_component`` and library itself
13171324
is created by ``idf_component_register``
13181325
- COMPONENT_NAME - name of the component; set by ``idf_build_component`` based on the component directory name

tools/ci/test_build_system_cmake.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,19 @@ endmenu\n" >> ${IDF_PATH}/Kconfig
743743
rm -rf build
744744
popd
745745

746+
print_status "Getting component overriden dir"
747+
clean_build_dir
748+
mkdir -p components/esp32
749+
echo "idf_component_get_property(overriden_dir \${COMPONENT_NAME} COMPONENT_OVERRIDEN_DIR)" >> components/esp32/CMakeLists.txt
750+
echo "message(STATUS overriden_dir:\${overriden_dir})" >> components/esp32/CMakeLists.txt
751+
(idf.py reconfigure | grep "overriden_dir:$IDF_PATH/components/esp32") || failure "Failed to get overriden dir" # no registration, overrides registration as well
752+
print_status "Overriding Kconfig"
753+
echo "idf_component_register(KCONFIG \${overriden_dir}/Kconfig)" >> components/esp32/CMakeLists.txt
754+
echo "idf_component_get_property(kconfig \${COMPONENT_NAME} KCONFIG)" >> components/esp32/CMakeLists.txt
755+
echo "message(STATUS kconfig:\${overriden_dir}/Kconfig)" >> components/esp32/CMakeLists.txt
756+
(idf.py reconfigure | grep "kconfig:$IDF_PATH/components/esp32/Kconfig") || failure "Failed to verify original `main` directory"
757+
rm -rf components
758+
746759
print_status "All tests completed"
747760
if [ -n "${FAILURES}" ]; then
748761
echo "Some failures were detected:"

tools/cmake/component.cmake

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ function(__component_add component_dir prefix)
171171
add_library(${component_target} STATIC IMPORTED)
172172
endif()
173173
idf_build_set_property(__COMPONENT_TARGETS ${component_target} APPEND)
174+
else()
175+
__component_get_property(dir ${component_target} COMPONENT_DIR)
176+
__component_set_property(${component_target} COMPONENT_OVERRIDEN_DIR ${dir})
174177
endif()
175178

176179
set(component_lib __${prefix}_${component_name})
@@ -413,9 +416,11 @@ endfunction()
413416
# @param[in, optional] REQUIRED_IDF_TARGETS (multivalue) the list of IDF build targets that the component only supports
414417
# @param[in, optional] EMBED_FILES (multivalue) list of binary files to embed with the component
415418
# @param[in, optional] EMBED_TXTFILES (multivalue) list of text files to embed with the component
419+
# @param[in, optional] KCONFIG (single value) override the default Kconfig
420+
# @param[in, optional] KCONFIG_PROJBUILD (single value) override the default Kconfig
416421
function(idf_component_register)
417422
set(options)
418-
set(single_value)
423+
set(single_value KCONFIG KCONFIG_PROJBUILD)
419424
set(multi_value SRCS SRC_DIRS EXCLUDE_SRCS
420425
INCLUDE_DIRS PRIV_INCLUDE_DIRS LDFRAGMENTS REQUIRES
421426
PRIV_REQUIRES REQUIRED_IDF_TARGETS EMBED_FILES EMBED_TXTFILES)

tools/cmake/scripts/component_get_requirements.cmake

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
cmake_minimum_required(VERSION 3.5)
12
include("${BUILD_PROPERTIES_FILE}")
23
include("${COMPONENT_PROPERTIES_FILE}")
34

@@ -18,18 +19,52 @@ function(__component_get_property var component_target property)
1819
set(${var} ${${_property}} PARENT_SCOPE)
1920
endfunction()
2021

22+
#
23+
# Given a component name or alias, get the corresponding component target.
24+
#
25+
function(__component_get_target var name_or_alias)
26+
idf_build_get_property(component_targets __COMPONENT_TARGETS)
27+
28+
# Assume first that the paramters is an alias.
29+
string(REPLACE "::" "_" name_or_alias "${name_or_alias}")
30+
set(component_target ___${name_or_alias})
31+
32+
if(component_target IN_LIST component_targets)
33+
set(${var} ${component_target} PARENT_SCOPE)
34+
set(target ${component_target})
35+
else() # assumption is wrong, try to look for it manually
36+
unset(target)
37+
foreach(component_target ${component_targets})
38+
__component_get_property(_component_name ${component_target} COMPONENT_NAME)
39+
if(name_or_alias STREQUAL _component_name)
40+
set(target ${component_target})
41+
break()
42+
endif()
43+
endforeach()
44+
set(${var} ${target} PARENT_SCOPE)
45+
endif()
46+
endfunction()
47+
48+
function(idf_component_get_property var component property)
49+
__component_get_target(component_target ${component})
50+
__component_get_property(_var ${component_target} ${property})
51+
set(${var} ${_var} PARENT_SCOPE)
52+
endfunction()
53+
2154
macro(require_idf_targets)
2255
endmacro()
2356

2457
macro(idf_component_register)
2558
set(options)
26-
set(single_value)
59+
set(single_value KCONFIG KCONFIG_PROJBUILD)
2760
set(multi_value SRCS SRC_DIRS EXCLUDE_SRCS
2861
INCLUDE_DIRS PRIV_INCLUDE_DIRS LDFRAGMENTS REQUIRES
2962
PRIV_REQUIRES REQUIRED_IDF_TARGETS EMBED_FILES EMBED_TXTFILES)
3063
cmake_parse_arguments(_ "${options}" "${single_value}" "${multi_value}" "${ARGN}")
31-
set(__component_requires "${__REQUIRES}")
3264
set(__component_priv_requires "${__PRIV_REQUIRES}")
65+
set(__component_requires "${__REQUIRES}")
66+
set(__component_kconfig "${__KCONFIG}")
67+
set(__component_kconfig_projbuild "${__KCONFIG_PROJBUILD}")
3368
set(__component_registered 1)
3469
return()
3570
endmacro()
@@ -64,6 +99,8 @@ function(__component_get_requirements)
6499

65100
set(__component_requires "${__component_requires}" PARENT_SCOPE)
66101
set(__component_priv_requires "${__component_priv_requires}" PARENT_SCOPE)
102+
set(__component_kconfig "${__component_kconfig}" PARENT_SCOPE)
103+
set(__component_kconfig_projbuild "${__component_kconfig_projbuild}" PARENT_SCOPE)
67104
set(__component_registered ${__component_registered} PARENT_SCOPE)
68105
endfunction()
69106

@@ -97,6 +134,21 @@ foreach(__component_target ${__component_targets})
97134
__component_set_property(${__component_target} PRIV_REQUIRES \"${__component_priv_requires}\")
98135
__component_set_property(${__component_target} __COMPONENT_REGISTERED ${__component_registered})"
99136
)
137+
138+
if(__component_kconfig)
139+
get_filename_component(__component_kconfig "${__component_kconfig}" ABSOLUTE)
140+
set(__contents
141+
"${__contents}\n__component_set_property(${__component_target} KCONFIG \"${__component_kconfig}\")"
142+
)
143+
endif()
144+
145+
if(__component_kconfig_projbuild)
146+
get_filename_component(__component_kconfig "${__component_kconfig}" ABSOLUTE)
147+
set(__contents
148+
"${__contents}\n__component_set_property(${__component_target} KCONFIG_PROJBUILD \"${__component_kconfig_projbuild}\")"
149+
)
150+
endif()
151+
100152
set(__component_requires_contents "${__component_requires_contents}\n${__contents}")
101153
endforeach()
102154

0 commit comments

Comments
 (0)