1 # Designed to be included from an IDF app's CMakeLists.txt file
3 cmake_minimum_required(VERSION 3.5)
5 # Set IDF_PATH, as nothing else will work without this
6 set(IDF_PATH "$ENV{IDF_PATH}")
8 # Documentation says you should set IDF_PATH in your environment, but we
9 # can infer it relative to tools/cmake directory if it's not set.
10 get_filename_component(IDF_PATH "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
12 file(TO_CMAKE_PATH "${IDF_PATH}" IDF_PATH)
13 set(ENV{IDF_PATH} ${IDF_PATH})
20 "${IDF_PATH}/tools/cmake"
21 "${IDF_PATH}/tools/cmake/third_party"
23 include(GetGitRevisionDescription)
27 include(git_submodules)
28 include(idf_functions)
30 set_default(PYTHON "python")
32 if(NOT PYTHON_DEPS_CHECKED AND NOT BOOTLOADER_BUILD)
33 message(STATUS "Checking Python dependencies...")
34 execute_process(COMMAND "${PYTHON}" "${IDF_PATH}/tools/check_python_dependencies.py"
35 RESULT_VARIABLE result)
36 if(NOT result EQUAL 0)
37 message(FATAL_ERROR "Some Python dependencies must be installed. Check above message for details.")
43 # This macro wraps the cmake 'project' command to add
44 # all of the IDF-specific functionality required
46 # Implementation Note: This macro wraps 'project' on purpose, because cmake has
47 # some backwards-compatible magic where if you don't call "project" in the
48 # top-level CMakeLists file, it will call it implicitly. However, the implicit
49 # project will not have CMAKE_TOOLCHAIN_FILE set and therefore tries to
50 # create a native build project.
52 # Therefore, to keep all the IDF "build magic", the cleanest way is to keep the
53 # top-level "project" call but customize it to do what we want in the IDF build.
56 # Set global variables used by rest of the build
57 idf_set_global_variables()
59 # Sort the components list, as it may be found via filesystem
60 # traversal and therefore in a non-deterministic order
63 execute_process(COMMAND "${CMAKE_COMMAND}"
64 -D "COMPONENTS=${COMPONENTS}"
65 -D "COMPONENT_REQUIRES_COMMON=${COMPONENT_REQUIRES_COMMON}"
66 -D "DEPENDENCIES_FILE=${CMAKE_BINARY_DIR}/component_depends.cmake"
67 -D "COMPONENT_DIRS=${COMPONENT_DIRS}"
68 -D "BOOTLOADER_BUILD=${BOOTLOADER_BUILD}"
69 -D "IDF_PATH=${IDF_PATH}"
71 -P "${IDF_PATH}/tools/cmake/scripts/expand_requirements.cmake"
72 WORKING_DIRECTORY "${PROJECT_PATH}")
73 include("${CMAKE_BINARY_DIR}/component_depends.cmake")
75 # We now have the following component-related variables:
76 # COMPONENTS is the list of initial components set by the user (or empty to include all components in the build).
77 # BUILD_COMPONENTS is the list of components to include in the build.
78 # BUILD_COMPONENT_PATHS is the paths to all of these components.
80 # Print list of components
81 string(REPLACE ";" " " BUILD_COMPONENTS_SPACES "${BUILD_COMPONENTS}")
82 message(STATUS "Component names: ${BUILD_COMPONENTS_SPACES}")
83 unset(BUILD_COMPONENTS_SPACES)
84 message(STATUS "Component paths: ${BUILD_COMPONENT_PATHS}")
86 kconfig_set_variables()
88 kconfig_process_config()
90 # Include sdkconfig.cmake so rest of the build knows the configuration
91 include(${SDKCONFIG_CMAKE})
93 # Now the configuration is loaded, set the toolchain appropriately
95 # TODO: support more toolchains than just ESP32
96 set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/tools/cmake/toolchain-esp32.cmake)
98 # Declare the actual cmake-level project
99 _project(${name} ASM C CXX)
101 # generate compile_commands.json (needs to come after project)
102 set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
104 # Verify the environment is configured correctly
105 idf_verify_environment()
107 # Add some idf-wide definitions
108 idf_set_global_compiler_options()
110 # Check git revision (may trigger reruns of cmake)
111 ## sets IDF_VER to IDF git revision
112 idf_get_git_revision()
113 ## if project uses git, retrieve revision
114 git_describe(PROJECT_VER "${CMAKE_CURRENT_SOURCE_DIR}")
116 # Include any top-level project_include.cmake files from components
117 foreach(component ${BUILD_COMPONENT_PATHS})
118 set(COMPONENT_PATH "${component}")
119 include_if_exists("${component}/project_include.cmake")
120 unset(COMPONENT_PATH)
124 # Add each component to the build as a library
126 foreach(COMPONENT_PATH ${BUILD_COMPONENT_PATHS})
127 get_filename_component(COMPONENT_NAME ${COMPONENT_PATH} NAME)
128 add_subdirectory(${COMPONENT_PATH} ${COMPONENT_NAME})
130 unset(COMPONENT_NAME)
131 unset(COMPONENT_PATH)
134 # Add the app executable to the build (has name of PROJECT.elf)
138 # Write project description JSON file
139 make_json_list("${BUILD_COMPONENTS}" build_components_json)
140 make_json_list("${BUILD_COMPONENT_PATHS}" build_component_paths_json)
141 configure_file("${IDF_PATH}/tools/cmake/project_description.json.in"
142 "${CMAKE_BINARY_DIR}/project_description.json")
143 unset(build_components_json)
144 unset(build_component_paths_json)
147 # Finish component registration (add cross-dependencies, make
148 # executable dependent on all components)
150 components_finish_registration()