]> granicus.if.org Git - esp-idf/blob - tools/cmake/idf_functions.cmake
Merge branch 'feature/cmake' into 'master'
[esp-idf] / tools / cmake / idf_functions.cmake
1 # Some IDF-specific functions and functions
2
3 include(crosstool_version_check)
4
5 #
6 # Set some variables used by rest of the build
7 #
8 # Note at the time this macro is expanded, the config is not yet
9 # loaded and the toolchain and project are not yet set
10 #
11 macro(idf_set_global_variables)
12     # Note that CONFIG_xxx is not available when this function is called
13
14     set_default(EXTRA_COMPONENT_DIRS "")
15
16     # Commmon components, required by every component in the build
17     #
18     set_default(COMPONENT_REQUIRES_COMMON "cxx esp32 newlib freertos heap log soc")
19
20     # PROJECT_PATH has the path to the IDF project (top-level cmake directory)
21     #
22     # (cmake calls this CMAKE_SOURCE_DIR, keeping old name for compatibility.)
23     set(PROJECT_PATH "${CMAKE_SOURCE_DIR}")
24
25     # Note: Unlike older build system, "main" is no longer a component. See build docs for details.
26     set_default(COMPONENT_DIRS "${PROJECT_PATH}/components ${EXTRA_COMPONENT_DIRS} ${IDF_PATH}/components")
27     spaces2list(COMPONENT_DIRS)
28
29     spaces2list(COMPONENTS)
30
31     # Tell cmake to drop executables in the top-level build dir
32     set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
33
34     # path to idf.py tool
35     set(IDFTOOL ${PYTHON} "${IDF_PATH}/tools/idf.py")
36 endmacro()
37
38 # Add all the IDF global compiler & preprocessor options
39 # (applied to all components). Some are config-dependent
40 #
41 # If you only want to set options for a particular component,
42 # don't call or edit this function. TODO DESCRIBE WHAT TO DO INSTEAD
43 #
44 function(idf_set_global_compiler_options)
45     add_definitions(-DESP_PLATFORM)
46     add_definitions(-DHAVE_CONFIG_H)
47
48     if(CONFIG_OPTIMIZATION_LEVEL_RELEASE)
49         add_compile_options(-Os)
50     else()
51         add_compile_options(-Og)
52     endif()
53
54     add_c_compile_options(-std=gnu99)
55
56     add_cxx_compile_options(-std=gnu++11 -fno-rtti)
57
58     if(CONFIG_CXX_EXCEPTIONS)
59         add_cxx_compile_options(-fexceptions)
60     else()
61         add_cxx_compile_options(-fno-exceptions)
62     endif()
63
64     # Default compiler configuration
65     add_compile_options(-ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib)
66
67     # Default warnings configuration
68     add_compile_options(
69         -Wall
70         -Werror=all
71         -Wno-error=unused-function
72         -Wno-error=unused-but-set-variable
73         -Wno-error=unused-variable
74         -Wno-error=deprecated-declarations
75         -Wextra
76         -Wno-unused-parameter
77         -Wno-sign-compare)
78     add_c_compile_options(
79         -Wno-old-style-declaration
80         )
81
82     # Stack protection
83     if(NOT BOOTLOADER_BUILD)
84         if(CONFIG_STACK_CHECK_NORM)
85             add_compile_options(-fstack-protector)
86         elseif(CONFIG_STACK_CHECK_STRONG)
87             add_compile_options(-fstack-protector-strong)
88         elseif(CONFIG_STACK_CHECK_ALL)
89             add_compile_options(-fstack-protector-all)
90         endif()
91     endif()
92
93     if(CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED)
94         add_definitions(-DNDEBUG)
95     endif()
96
97     # Always generate debug symbols (even in Release mode, these don't
98     # go into the final binary so have no impact on size)
99     add_compile_options(-ggdb)
100
101     # Enable ccache if it's on the path
102     if(NOT CCACHE_DISABLE)
103         find_program(CCACHE_FOUND ccache)
104         if(CCACHE_FOUND)
105             message(STATUS "ccache will be used for faster builds")
106             set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
107         endif()
108     endif()
109
110 endfunction()
111
112
113 # Verify the IDF environment is configured correctly (environment, toolchain, etc)
114 function(idf_verify_environment)
115
116     if(NOT CMAKE_PROJECT_NAME)
117         message(FATAL_ERROR "Internal error, IDF project.cmake should have set this variable already")
118     endif()
119
120     # Check toolchain is configured properly in cmake
121     if(NOT ( ${CMAKE_SYSTEM_NAME} STREQUAL "Generic" AND ${CMAKE_C_COMPILER} MATCHES xtensa))
122         message(FATAL_ERROR "Internal error, toolchain has not been set correctly by project "
123             "(or an invalid CMakeCache.txt file has been generated somehow)")
124     endif()
125
126     #
127     # Warn if the toolchain version doesn't match
128     #
129     # TODO: make these platform-specific for diff toolchains
130     gcc_version_check("5.2.0")
131     crosstool_version_check("1.22.0-80-g6c4433a")
132
133 endfunction()
134
135 # idf_add_executable
136 #
137 # Calls add_executable to add the final project executable
138 # Adds .map & .bin file targets
139 # Sets up flash-related targets
140 function(idf_add_executable)
141     set(exe_target ${PROJECT_NAME}.elf)
142
143     spaces2list(MAIN_SRCS)
144     add_executable(${exe_target} "${MAIN_SRCS}")
145
146     add_map_file(${exe_target})
147 endfunction()
148
149
150 # add_map_file
151 #
152 # Set linker args for 'exe_target' to generate a linker Map file
153 function(add_map_file exe_target)
154     get_filename_component(basename ${exe_target} NAME_WE)
155     set(mapfile "${basename}.map")
156     target_link_libraries(${exe_target} "-Wl,--gc-sections -Wl,--cref -Wl,--Map=${mapfile} -Wl,--start-group")
157     set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
158         ADDITIONAL_MAKE_CLEAN_FILES
159         "${CMAKE_CURRENT_BINARY_DIR}/${mapfile}")
160
161     # add size targets, depend on map file, run idf_size.py
162     add_custom_target(size
163         DEPENDS ${exe_target}
164         COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py ${mapfile}
165         )
166     add_custom_target(size-files
167         DEPENDS ${exe_target}
168         COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --files ${mapfile}
169         )
170     add_custom_target(size-components
171         DEPENDS ${exe_target}
172         COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --archives ${mapfile}
173         )
174
175 endfunction()
176
177 # component_compile_options
178 #
179 # Wrapper around target_compile_options that passes the component name
180 function(component_compile_options)
181     target_compile_options(${COMPONENT_NAME} PRIVATE ${ARGV})
182 endfunction()
183
184 # component_compile_definitions
185 #
186 # Wrapper around target_compile_definitions that passes the component name
187 function(component_compile_definitions)
188     target_compile_definitions(${COMPONENT_NAME} PRIVATE ${ARGV})
189 endfunction()
190
191 # idf_get_git_revision
192 #
193 # Set global IDF_VER to the git revision of ESP-IDF.
194 #
195 # Running git_describe() here automatically triggers rebuilds
196 # if the ESP-IDF git version changes
197 function(idf_get_git_revision)
198     git_describe(IDF_VER "${IDF_PATH}")
199     add_definitions(-DIDF_VER=\"${IDF_VER}\")
200     git_submodule_check("${IDF_PATH}")
201     set(IDF_VER ${IDF_VER} PARENT_SCOPE)
202 endfunction()