build system: add WHOLE_ARCHIVE component property

This component property allows including all component object files
into the executable. It is equivalent to wrapping the component
library with -Wl,--whole-archive and -Wl,--no-whole-archive flags.

Closes https://github.com/espressif/esp-idf/issues/8667
This commit is contained in:
Ivan Grokhotkov 2022-03-30 00:42:32 +02:00
parent 86e5ff1e64
commit 273633ee31
No known key found for this signature in database
GPG Key ID: 1E050E141B280628
4 changed files with 21 additions and 4 deletions

View File

@ -1342,7 +1342,8 @@ Set a specified *component*'s :ref:`component property<cmake-component-propertie
[EMBED_FILES file1 file2 ...]
[EMBED_TXTFILES file1 file2 ...]
[KCONFIG kconfig]
[KCONFIG_PROJBUILD kconfig_projbuild])
[KCONFIG_PROJBUILD kconfig_projbuild]
[WHOLE_ARCHIVE])
Register a component to the build system. Much like the ``project()`` CMake command, this should be called from the component's CMakeLists.txt directly (not through a function or macro) and is recommended to be called before any other command. Here are some guidelines on what commands can **not** be called before ``idf_component_register``:
@ -1364,6 +1365,7 @@ The arguments for ``idf_component_register`` include:
- REQUIRED_IDF_TARGETS - specify the only target the component supports
- KCONFIG - override the default Kconfig file
- KCONFIG_PROJBUILD - override the default Kconfig.projbuild file
- WHOLE_ARCHIVE - if specified, the component library is surrounded by ``-Wl,--whole-archive``, ``-Wl,--no-whole-archive`` when linked. This has the same effect as setting ``WHOLE_ARCHIVE`` component property.
The following are used for :ref:`embedding data into the component<cmake_embed_data>`, and is considered as source files 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 created internally for the component if it specifies either:
@ -1399,6 +1401,7 @@ These are properties that describe a component. Values of component properties c
- REQUIRED_IDF_TARGETS - list of targets the component supports; set from ``idf_component_register`` EMBED_TXTFILES argument
- REQUIRES - list of public component dependencies; set from ``idf_component_register`` REQUIRES argument
- SRCS - list of component source files; set from SRCS or SRC_DIRS/EXCLUDE_SRCS argument of ``idf_component_register``
- WHOLE_ARCHIVE - if this property is set to ``TRUE`` (or any boolean "true" CMake value: 1, ``ON``, ``YES``, ``Y``), the component library is surrounded by ``-Wl,--whole-archive``, ``-Wl,--no-whole-archive`` when linked. This can be used to force the linker to include every object file into the executable, even if the object file doesn't resolve any references from the rest of the application. This is commonly used when a component contains plugins or modules which rely on link-time registration. This property is ``FALSE`` by default. It can be set to ``TRUE`` from the component CMakeLists.txt file.
.. _cmake-file-globbing:

View File

@ -88,6 +88,8 @@ macro(__component_set_properties)
__component_set_property(${component_target} EMBED_FILES "${__EMBED_FILES}")
__component_set_property(${component_target} EMBED_TXTFILES "${__EMBED_TXTFILES}")
__component_set_property(${component_target} REQUIRED_IDF_TARGETS "${__REQUIRED_IDF_TARGETS}")
__component_set_property(${component_target} WHOLE_ARCHIVE ${__WHOLE_ARCHIVE})
endmacro()
#
@ -417,8 +419,9 @@ endfunction()
# @param[in, optional] EMBED_TXTFILES (multivalue) list of text files to embed with the component
# @param[in, optional] KCONFIG (single value) override the default Kconfig
# @param[in, optional] KCONFIG_PROJBUILD (single value) override the default Kconfig
# @param[in, optional] WHOLE_ARCHIVE (option) link the component as --whole-archive
function(idf_component_register)
set(options)
set(options WHOLE_ARCHIVE)
set(single_value KCONFIG KCONFIG_PROJBUILD)
set(multi_value SRCS SRC_DIRS EXCLUDE_SRCS
INCLUDE_DIRS PRIV_INCLUDE_DIRS LDFRAGMENTS REQUIRES

View File

@ -484,7 +484,18 @@ macro(project project_name)
if(test_components)
list(REMOVE_ITEM build_components ${test_components})
endif()
target_link_libraries(${project_elf} ${build_components})
foreach(build_component ${build_components})
__component_get_target(build_component_target ${build_component})
__component_get_property(whole_archive ${build_component_target} WHOLE_ARCHIVE)
if(whole_archive)
message(STATUS "Component ${build_component} will be linked with -Wl,--whole-archive")
target_link_libraries(${project_elf} "-Wl,--whole-archive" ${build_component} "-Wl,--no-whole-archive")
else()
target_link_libraries(${project_elf} ${build_component})
endif()
endforeach()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(mapfile "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map")

View File

@ -66,7 +66,7 @@ macro(idf_component_mock)
endmacro()
macro(idf_component_register)
set(options)
set(options WHOLE_ARCHIVE)
set(single_value KCONFIG KCONFIG_PROJBUILD)
set(multi_value SRCS SRC_DIRS EXCLUDE_SRCS
INCLUDE_DIRS PRIV_INCLUDE_DIRS LDFRAGMENTS REQUIRES