Sfoglia il codice sorgente

Merge branch 'feature/spiflash_override_cmake_function' into 'master'

build system: Add spi_flash_add_link_dependency function for spi_flash custom driver

Closes IDF-3167

See merge request espressif/esp-idf!14186
Ivan Grokhotkov 3 anni fa
parent
commit
32754865da

+ 17 - 0
docs/en/api-guides/build-system.rst

@@ -605,6 +605,23 @@ The order of components in the ``BUILD_COMPONENTS`` variable determines other or
 - Order that :ref:`project_include.cmake` files are included into the project.
 - Order that the list of header paths is generated for compilation (via ``-I`` argument). (Note that for a given component's source files, only that component's dependency's header paths are passed to the compiler.)
 
+Adding Link-Time Dependencies
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. highlight:: cmake
+
+The ESP-IDF CMake helper function ``idf_component_add_link_dependency`` adds a link-only dependency between one component and another. In almost all cases, it is better to use the ``PRIV_REQUIRES`` feature in ``idf_component_register`` to create a dependency. However, in some cases, it's necessary to add the link-time dependency of another component to this component, i.e., the reverse order to ``PRIV_REQUIRES`` (for example: :doc:`/api-reference/storage/spi_flash_override_driver`).
+
+To make another component depend on this component at link time::
+
+  idf_component_add_link_dependency(FROM other_component)
+
+Place this line after the line with ``idf_component_register``.
+
+It's also possible to specify both components by name::
+
+  idf_component_add_link_dependency(FROM other_component TO that_component)
+
 .. _override_project_config:
 
 Overriding Parts of the Project

+ 16 - 4
docs/en/api-reference/storage/spi_flash_override_driver.rst

@@ -17,6 +17,8 @@ Users should note the following when customizing chip drivers:
 Steps For Creating Custom Chip Drivers and Overriding the IDF Default Driver List
 ---------------------------------------------------------------------------------
 
+.. highlight: cmake
+
 1. Enable the :ref:`CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST` config option. This will prevent compilation and linking of the Default Chip Driver List (`default_registered_chips`) provided by IDF. Instead, the linker will search for the structure of the same name (`default_registered_chips`) that must be provided by the user.
 2. Add a new component in your project, e.g. `custom_chip_driver`.
 3. Copy the necessary chip driver files from the `spi_flash` component in IDF. This may include:
@@ -25,7 +27,11 @@ Steps For Creating Custom Chip Drivers and Overriding the IDF Default Driver Lis
     - Any of the `spi_flash_chip_*.c` files that matches your own flash model best
     - `CMakeLists.txt` and `linker.lf` files
 
-   Modify the files above properly.
+   Modify the files above properly. Including:
+
+   - Change the ``default_registered_chips`` variable to non-static and remove the #ifdef logic around it.
+   - Update `linker.lf` file to rename the fragment header and the library name to match the new component.
+   - If reusing other drivers, some header names need prefixing with ``spi_flash/`` when included from outside spi_flash component.
 
 .. note::
    - When writing your own flash chip driver, you can set your flash chip capabilities through `spi_flash_chip_***(vendor)_get_caps` and points the function pointer `get_chip_caps` for protection to the `spi_flash_chip_***_get_caps` function. The steps are as follows.
@@ -56,10 +62,16 @@ Steps For Creating Custom Chip Drivers and Overriding the IDF Default Driver Lis
 
    - You also can see how to implement this in the example :example:`storage/custom_flash_driver`.
 
-4. Add linking dependency from `spi_flash` component to the new `custom_chip_driver` component, by adding the following lines after the `idf_component_register`, in the `CMakeLists.txt` file of the `custom_chip_driver` component:
+4. Write a new `CMakeLists.txt` file for the `custom_chip_driver` component, including an additional line to add a linker dependency from `spi_flash` to `custom_chip_driver`::
+
+        idf_component_register(SRCS "spi_flash_chip_drivers.c"
+                               "spi_flash_chip_mychip.c"  # modify as needed
+                               REQUIRES hal
+                               PRIV_REQUIRES spi_flash
+                               LDFRAGMENTS linker.lf)
+        idf_component_add_link_dependency(FROM spi_flash)
 
-      idf_component_get_property(spi_flash_lib spi_flash COMPONENT_LIB)
-      set_property(TARGET ${spi_flash_lib} APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:${COMPONENT_LIB}>)
+   - An example of this component CMakeLists.txt can be found in :example_file:`storage/custom_flash_driver/components/custom_chip_driver/CMakeLists.txt`
 
 5. The `linker.lf` is used to put every chip driver that you are going to use whilst cache is disabled into internal RAM. See :doc:`/api-guides/linker-script-generation` for more details. Make sure this file covers all the source files that you add.
 

+ 17 - 0
docs/zh_CN/api-guides/build-system.rst

@@ -605,6 +605,23 @@ CMake 通常会在链接器命令行上重复两次组件库名称来自动处
 - 项目导入 :ref:`project_include.cmake` 文件的顺序。
 - 生成用于编译(通过 ``-I`` 参数)的头文件路径列表的顺序。请注意,对于给定组件的源文件,仅需将该组件的依赖组件的头文件路径告知编译器。
 
+添加链接时依赖项
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. highlight:: cmake
+
+ESP-IDF 的 CMake 辅助函数 ``idf_component_add_link_dependency`` 可以在组件之间添加仅作用于链接时的依赖关系。绝大多数情况下,我们都建议您使用 ``idf_component_register`` 中的 ``PRIV_REQUIRES`` 功能来构建依赖关系。然而在某些情况下,还是有必要添加另一个组件对当前组件的链接时依赖,即反转 ``PRIV_REQUIRES`` 中的依赖关系(参考示例::doc:`/api-reference/storage/spi_flash_override_driver`)。
+
+要使另一个组件在链接时依赖于这个组件::
+
+  idf_component_add_link_dependency(FROM other_component)
+
+请将上述行置于 ``idf_component_register`` 行之后。
+
+也可以通过名称指定两个组件::
+
+  idf_component_add_link_dependency(FROM other_component TO that_component)
+
 .. _override_project_config:
 
 覆盖项目的部分设置

+ 1 - 2
examples/storage/custom_flash_driver/components/custom_chip_driver/CMakeLists.txt

@@ -3,5 +3,4 @@ idf_component_register(SRCS "chip_drivers.c" "spi_flash_chip_eon.c"
                     LDFRAGMENTS linker.lf
                     INCLUDE_DIRS "")
 
-idf_component_get_property(spi_flash_lib spi_flash COMPONENT_LIB)
-set_property(TARGET ${spi_flash_lib} APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:${COMPONENT_LIB}>)
+idf_component_add_link_dependency(FROM spi_flash)

+ 27 - 0
tools/cmake/component.cmake

@@ -604,6 +604,33 @@ function(idf_component_optional_requires req_type)
     endforeach()
 endfunction()
 
+# idf_component_add_link_dependency
+#
+# @brief Specify than an ESP-IDF component library depends on another component
+# library at link time only.
+#
+# @note Almost always it's better to use idf_component_register() REQUIRES or
+# PRIV_REQUIRES for this. However using this function allows adding a dependency
+# from inside a different component, as a last resort.
+#
+# @param[in, required] FROM Component the dependency is from (this component depends on the other component)
+# @param[in, optional] TO Component the dependency is to (this component is depended on by FROM). If omitted
+# then the current component is assumed. For this default value to work, this function must be called after
+# idf_component_register() in the component CMakeLists.txt file.
+function(idf_component_add_link_dependency)
+    set(single_value FROM TO)
+    cmake_parse_arguments(_ "" "${single_value}" "" ${ARGN})
+
+    idf_component_get_property(from_lib ${__FROM} COMPONENT_LIB)
+    if(__TO)
+        idf_component_get_property(to_lib ${__TO} COMPONENT_LIB)
+    else()
+        set(to_lib ${COMPONENT_LIB})
+    endif()
+    set_property(TARGET ${from_lib} APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:${to_lib}>)
+endfunction()
+
+
 #
 # Deprecated functions
 #