]> granicus.if.org Git - esp-idf/blob - tools/cmake/kconfig.cmake
Merge branch 'feature/cmake' into 'master'
[esp-idf] / tools / cmake / kconfig.cmake
1 include(ExternalProject)
2
3 macro(kconfig_set_variables)
4     set(CONFIG_DIR ${CMAKE_BINARY_DIR}/config)
5     set_default(SDKCONFIG ${PROJECT_PATH}/sdkconfig)
6     set(SDKCONFIG_HEADER ${CONFIG_DIR}/sdkconfig.h)
7     set(SDKCONFIG_CMAKE ${CONFIG_DIR}/sdkconfig.cmake)
8     set(SDKCONFIG_JSON ${CONFIG_DIR}/sdkconfig.json)
9     set(KCONFIG_JSON_MENUS ${CONFIG_DIR}/kconfig_menus.json)
10
11     set(ROOT_KCONFIG ${IDF_PATH}/Kconfig)
12
13     set_default(SDKCONFIG_DEFAULTS "${SDKCONFIG}.defaults")
14
15     # ensure all source files can include sdkconfig.h
16     include_directories("${CONFIG_DIR}")
17 endmacro()
18
19 if(CMAKE_HOST_WIN32)
20     # Prefer a prebuilt mconf-idf on Windows
21     find_program(WINPTY winpty)
22     find_program(MCONF mconf-idf)
23
24     # Fall back to the old binary which was called 'mconf' not 'mconf-idf'
25     if(NOT MCONF)
26         find_program(MCONF mconf)
27         if(MCONF)
28             message(WARNING "Falling back to mconf binary '${MCONF}' not mconf-idf. "
29                 "This is probably because an old version of IDF mconf is installed and this is fine. "
30                 "However if there are config problems please check the Getting Started guide for your platform.")
31         endif()
32     endif()
33
34     if(NOT MCONF)
35         find_program(NATIVE_GCC gcc)
36         if(NOT NATIVE_GCC)
37             message(FATAL_ERROR
38                 "Windows requires a prebuilt mconf-idf for your platform "
39                 "on the PATH, or an MSYS2 version of gcc on the PATH to build mconf-idf. "
40                 "Consult the setup docs for ESP-IDF on Windows.")
41         endif()
42     elseif(WINPTY)
43         set(MCONF "${WINPTY}" "${MCONF}")
44     endif()
45 endif()
46
47 if(NOT MCONF)
48     # Use the existing Makefile to build mconf (out of tree) when needed
49     #
50     set(MCONF kconfig_bin/mconf-idf)
51
52     externalproject_add(mconf-idf
53         SOURCE_DIR ${IDF_PATH}/tools/kconfig
54         CONFIGURE_COMMAND ""
55         BINARY_DIR "kconfig_bin"
56         BUILD_COMMAND make -f ${IDF_PATH}/tools/kconfig/Makefile mconf-idf
57         BUILD_BYPRODUCTS ${MCONF}
58         INSTALL_COMMAND ""
59         EXCLUDE_FROM_ALL 1
60         )
61
62     file(GLOB mconf_srcfiles ${IDF_PATH}/tools/kconfig/*.c)
63     externalproject_add_stepdependencies(mconf-idf build
64         ${mconf_srcfiles}
65         ${IDF_PATH}/tools/kconfig/Makefile
66         ${CMAKE_CURRENT_LIST_FILE})
67     unset(mconf_srcfiles)
68
69     set(menuconfig_depends DEPENDS mconf-idf)
70
71 endif()
72
73 # Find all Kconfig files for all components
74 function(kconfig_process_config)
75     file(MAKE_DIRECTORY "${CONFIG_DIR}")
76     set(kconfigs)
77     set(kconfigs_projbuild)
78
79     # Find Kconfig and Kconfig.projbuild for each component as applicable
80     # if any of these change, cmake should rerun
81     foreach(dir ${BUILD_COMPONENT_PATHS} "${CMAKE_SOURCE_DIR}/main")
82         file(GLOB kconfig "${dir}/Kconfig")
83         if(kconfig)
84             set(kconfigs "${kconfigs} ${kconfig}")
85             set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig})
86         endif()
87         file(GLOB kconfig ${dir}/Kconfig.projbuild)
88         if(kconfig)
89             set(kconfigs_projbuild "${kconfigs_projbuild} ${kconfig}")
90             set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig})
91         endif()
92     endforeach()
93
94     if(EXISTS ${SDKCONFIG_DEFAULTS})
95         set(defaults_arg --defaults "${SDKCONFIG_DEFAULTS}")
96     endif()
97
98     # Set these in the parent scope, so that they can be written to project_description.json
99     set(kconfigs "${kconfigs}")
100     set(COMPONENT_KCONFIGS "${kconfigs}" PARENT_SCOPE)
101     set(COMPONENT_KCONFIGS_PROJBUILD "${kconfigs_projbuild}" PARENT_SCOPE)
102
103     set(confgen_basecommand
104         ${PYTHON} ${IDF_PATH}/tools/kconfig_new/confgen.py
105         --kconfig ${ROOT_KCONFIG}
106         --config ${SDKCONFIG}
107         ${defaults_arg}
108         --create-config-if-missing
109         --env "COMPONENT_KCONFIGS=${kconfigs}"
110         --env "COMPONENT_KCONFIGS_PROJBUILD=${kconfigs_projbuild}"
111         --env "IDF_CMAKE=y")
112
113     # Generate the menuconfig target (uses C-based mconf-idf tool, either prebuilt or via mconf-idf target above)
114     add_custom_target(menuconfig
115         ${menuconfig_depends}
116         # create any missing config file, with defaults if necessary
117         COMMAND ${confgen_basecommand} --output config ${SDKCONFIG}
118         COMMAND ${CMAKE_COMMAND} -E env
119         "COMPONENT_KCONFIGS=${kconfigs}"
120         "COMPONENT_KCONFIGS_PROJBUILD=${kconfigs_projbuild}"
121         "IDF_CMAKE=y"
122         "KCONFIG_CONFIG=${SDKCONFIG}"
123         ${MCONF} ${ROOT_KCONFIG}
124         VERBATIM
125         USES_TERMINAL)
126
127     # Custom target to run confserver.py from the build tool
128     add_custom_target(confserver
129         COMMAND ${CMAKE_COMMAND} -E env
130         "COMPONENT_KCONFIGS=${kconfigs}"
131         "COMPONENT_KCONFIGS_PROJBUILD=${kconfigs_projbuild}"
132         ${IDF_PATH}/tools/kconfig_new/confserver.py --kconfig ${IDF_PATH}/Kconfig --config ${SDKCONFIG}
133         VERBATIM
134         USES_TERMINAL)
135
136     # Generate configuration output via confgen.py
137     # makes sdkconfig.h and skdconfig.cmake
138     #
139     # This happens during the cmake run not during the build
140     execute_process(COMMAND ${confgen_basecommand}
141         --output header ${SDKCONFIG_HEADER}
142         --output cmake ${SDKCONFIG_CMAKE}
143         --output json ${SDKCONFIG_JSON}
144         --output json_menus ${KCONFIG_JSON_MENUS}
145         RESULT_VARIABLE config_result)
146     if(config_result)
147         message(FATAL_ERROR "Failed to run confgen.py (${confgen_basecommand}). Error ${config_result}")
148     endif()
149
150     # When sdkconfig file changes in the future, trigger a cmake run
151     set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG}")
152
153     # Ditto if either of the generated files are missing/modified (this is a bit irritating as it means
154     # you can't edit these manually without them being regenerated, but I don't know of a better way...)
155     set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG_HEADER}")
156     set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${SDKCONFIG_CMAKE}")
157
158     # Or if the config generation tool changes
159     set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${IDF_PATH}/tools/kconfig_new/confgen.py")
160     set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${IDF_PATH}/tools/kconfig_new/kconfiglib.py")
161
162     set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
163         ADDITIONAL_MAKE_CLEAN_FILES
164         "${SDKCONFIG_HEADER}" "${SDKCONFIG_CMAKE}")
165
166 endfunction()