]> granicus.if.org Git - esp-idf/blob - tools/cmake/project.cmake
Merge branch 'bugfix/btdm_fix_save_error_key_in_smp_when_reconnect' into 'master'
[esp-idf] / tools / cmake / project.cmake
1 # Designed to be included from an IDF app's CMakeLists.txt file
2 #
3 cmake_minimum_required(VERSION 3.5)
4
5 # Set IDF_PATH, as nothing else will work without this
6 set(IDF_PATH "$ENV{IDF_PATH}")
7 if(NOT 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)
11 endif()
12 file(TO_CMAKE_PATH "${IDF_PATH}" IDF_PATH)
13 set(ENV{IDF_PATH} ${IDF_PATH})
14
15
16 #
17 # Load cmake modules
18 #
19 set(CMAKE_MODULE_PATH
20     "${IDF_PATH}/tools/cmake"
21     "${IDF_PATH}/tools/cmake/third_party"
22     ${CMAKE_MODULE_PATH})
23 include(GetGitRevisionDescription)
24 include(utilities)
25 include(components)
26 include(kconfig)
27 include(git_submodules)
28 include(idf_functions)
29
30 set_default(PYTHON "python")
31
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.")
38     endif()
39 endif()
40
41 # project
42 #
43 # This macro wraps the cmake 'project' command to add
44 # all of the IDF-specific functionality required
45 #
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.
51 #
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.
54 #
55 macro(project name)
56     # Set global variables used by rest of the build
57     idf_set_global_variables()
58
59     # Sort the components list, as it may be found via filesystem
60     # traversal and therefore in a non-deterministic order
61     list(SORT COMPONENTS)
62
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}"
70         -D "DEBUG=${DEBUG}"
71         -P "${IDF_PATH}/tools/cmake/scripts/expand_requirements.cmake"
72         WORKING_DIRECTORY "${PROJECT_PATH}")
73     include("${CMAKE_BINARY_DIR}/component_depends.cmake")
74
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.
79
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}")
85
86     kconfig_set_variables()
87
88     kconfig_process_config()
89
90     # Include sdkconfig.cmake so rest of the build knows the configuration
91     include(${SDKCONFIG_CMAKE})
92
93     # Now the configuration is loaded, set the toolchain appropriately
94     #
95     # TODO: support more toolchains than just ESP32
96     set(CMAKE_TOOLCHAIN_FILE $ENV{IDF_PATH}/tools/cmake/toolchain-esp32.cmake)
97
98     # Declare the actual cmake-level project
99     _project(${name} ASM C CXX)
100
101     # generate compile_commands.json (needs to come after project)
102     set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
103
104     # Verify the environment is configured correctly
105     idf_verify_environment()
106
107     # Add some idf-wide definitions
108     idf_set_global_compiler_options()
109
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}")
115
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)
121     endforeach()
122
123     #
124     # Add each component to the build as a library
125     #
126     foreach(COMPONENT_PATH ${BUILD_COMPONENT_PATHS})
127         get_filename_component(COMPONENT_NAME ${COMPONENT_PATH} NAME)
128         add_subdirectory(${COMPONENT_PATH} ${COMPONENT_NAME})
129     endforeach()
130     unset(COMPONENT_NAME)
131     unset(COMPONENT_PATH)
132
133     #
134     # Add the app executable to the build (has name of PROJECT.elf)
135     #
136     idf_add_executable()
137
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)
145
146     #
147     # Finish component registration (add cross-dependencies, make
148     # executable dependent on all components)
149     #
150     components_finish_registration()
151
152 endmacro()