Răsfoiți Sursa

examples: import_lib: demonstrate ExternalProject_Add

Many of the more complicated CMake projects can't be added to the IDF
build system simply by calling add_subdirectory.
"add_subdirectory" also cannot be used with projects which use build
systems other than CMake (for example GNU Make or cargo).
This commit changes the example to use ExternalProject_Add, instead,
which is a more general way of adding subprojects.
As part of this change, tinyxml2 is now downloaded from the Internet,
which allows removing one submodule.
Ivan Grokhotkov 3 ani în urmă
părinte
comite
b2e129fe4f

+ 5 - 3
examples/build_system/cmake/import_lib/README.md

@@ -4,9 +4,11 @@ This example demonstrates how to import third-party CMake libraries.
 
 ## Example Flow
 
-[tinyxml2](https://github.com/leethomason/tinyxml2) is a 
-a small C++ XML parser. It is imported, without modification, for use in the project's `main` component (see the `main` component's [CMakeLists.txt](main/CMakeLists.txt)). To demonstrate the library being used, a sample XML is embedded into the project.
-This sample XML is then read and parsed later on using `tinyxml2`.
+[tinyxml2](https://github.com/leethomason/tinyxml2) is a small C++ XML parser.
+
+It is imported, without modification, into the [tinyxml2](components/tinyxml2/) component. Please refer to the component CMakeLists.txt file for the description of the process: [components/tinyxml2/CMakeLists.txt](components/tinyxml2/CMakeLists.txt).
+
+To demonstrate the library being used, a sample XML is embedded into the project. This sample XML is then read and parsed using `tinyxml2`. Please refer to the [main](main/) component for details.
 
 ### Output
 

+ 67 - 0
examples/build_system/cmake/import_lib/components/tinyxml2/CMakeLists.txt

@@ -0,0 +1,67 @@
+# This component demonstrates how to add an existing third-party library as a component
+# to ESP-IDF build system.
+#
+# Since we are wrapping the library inside a component,
+# the component has to be registered first:
+idf_component_register()
+
+# To build a third-party library, ExternalProject CMake module can be used.
+# ExternalProject offers many features which are impossible to demonstrate
+# in a single example. Please refer to its documentation for more info:
+#   https://cmake.org/cmake/help/latest/module/ExternalProject.html
+include(ExternalProject)
+
+# Define the location where tinyxml2 will be installed:
+set(TINYXML2_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/tinyxml2_install)
+
+# This function downloads the project, calls CMake to configure it,
+# builds the project and installs it to the specified location:
+externalproject_add(tinyxml2_proj
+    # Download the source code of the third party project from the following URL.
+    # (Two URLs are provided, the 2nd one is the mirror for Chinese users)
+    URL https://github.com/leethomason/tinyxml2/archive/refs/tags/9.0.0.zip
+        https://gitcode.net/mirrors/leethomason/tinyxml2/-/archive/9.0.0/tinyxml2-9.0.0.zip
+    # (Downloading is not the only option; the library can also be located in your source tree.
+    #  Consult ExternalProject_Add function documentation for other options.)
+
+    # Specify arguments to be passed when running CMake for this subproject.
+    # Note that ExternalProject_Add also works with non-CMake projects, so this
+    # is just an example.
+    CMAKE_ARGS
+        # Use the same CMake toolchain file as for the main project.
+        -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+        # tinyxml2-specific settings: disable building everything except for the static library
+        -Dtinyxml2_BUILD_TESTING=FALSE
+        -Dtinyxml2_SHARED_LIBS=FALSE
+        # Pass the install directory to the subproject.
+        -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+
+    # These options are set so that Ninja immediately outputs
+    # the subproject build to the terminal. Otherwise it looks like the
+    # build process "hangs" while the subproject is being built.
+    USES_TERMINAL_DOWNLOAD TRUE
+    USES_TERMINAL_CONFIGURE TRUE
+    USES_TERMINAL_BUILD TRUE
+
+    # Specify the installation directory for the subproject
+    INSTALL_DIR ${TINYXML2_INSTALL_DIR}
+    # Let CMake know that the library is generated by the subproject build step.
+    BUILD_BYPRODUCTS "${TINYXML2_INSTALL_DIR}/lib/libtinyxml2.a"
+)
+
+# Now that the subproject build is set up, we need to consume the results
+# of the build: the header file and the static library.
+# To do this, define an imported CMake library:
+add_prebuilt_library(tinyxml2_lib "${TINYXML2_INSTALL_DIR}/lib/libtinyxml2.a"
+                     # tinyxml calls certain C++ support library functions (_Unwind_Resume and similar)
+                     # so a dependency on IDF's cxx component is added here:
+                     PRIV_REQUIRES cxx)
+target_include_directories(tinyxml2_lib INTERFACE "${TINYXML2_INSTALL_DIR}/include")
+add_dependencies(tinyxml2_lib tinyxml2_proj)
+
+# Link the imported library to the current component.
+target_link_libraries(${COMPONENT_LIB} INTERFACE tinyxml2_lib)
+
+# To use tinyxml2 in another component, add 'tinyxml2' (the name of this component)
+# to PRIV_REQUIRES or REQUIRES list its idf_component_register call.
+# See ../../main/CMakeLists.txt for an example.

+ 3 - 22
examples/build_system/cmake/import_lib/main/CMakeLists.txt

@@ -1,23 +1,4 @@
 idf_component_register(SRCS "main.cpp"
-                    INCLUDE_DIRS "."
-                    EMBED_TXTFILES "sample.xml")
-
-# Build static library, do not build test executables
-option(BUILD_SHARED_LIBS OFF)
-option(BUILD_TESTING OFF)
-
-# Unfortunately the library performs install and export. Would
-# have been nice if devs made that an option like BUILD_SHARED_LIBS
-# and BUILD_TESTING. Override install() and export() to do nothing
-# instead.
-function(install)
-endfunction()
-
-function(export)
-endfunction()
-
-# Import tinyxml2 targets
-add_subdirectory(lib/tinyxml2)
-
-# Link tinyxml2 to main component
-target_link_libraries(${COMPONENT_LIB} PUBLIC tinyxml2)
+                       INCLUDE_DIRS "."
+                       EMBED_TXTFILES sample.xml
+                       PRIV_REQUIRES tinyxml2 fatfs)

+ 1 - 1
examples/build_system/cmake/import_lib/main/main.cpp

@@ -7,7 +7,7 @@
 #include "esp_err.h"
 #include "esp_log.h"
 #include "esp_vfs_fat.h"
-#include "lib/tinyxml2/tinyxml2.h"
+#include "tinyxml2.h"
 
 using namespace tinyxml2;