cmake_minimum_required(VERSION 3.16) project(esp-idf C CXX ASM) if(CMAKE_CURRENT_LIST_DIR STREQUAL CMAKE_SOURCE_DIR) message(FATAL_ERROR "Current directory '${CMAKE_CURRENT_LIST_DIR}' is not buildable. " "Change directories to one of the example projects in '${CMAKE_CURRENT_LIST_DIR}/examples' and try " "again.") endif() # Variables compile_options, c_compile_options, cxx_compile_options, compile_definitions, link_options shall # not be unset as they may already contain flags, set by toolchain-TARGET.cmake files. # Add the following build specifications here, since these seem to be dependent # on config values on the root Kconfig. if(NOT BOOTLOADER_BUILD) if(CONFIG_COMPILER_OPTIMIZATION_SIZE) list(APPEND compile_options "-Os") if(CMAKE_C_COMPILER_ID MATCHES "GNU") list(APPEND compile_options "-freorder-blocks") endif() elseif(CONFIG_COMPILER_OPTIMIZATION_DEBUG) list(APPEND compile_options "-Og") if(CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT CONFIG_IDF_TARGET_LINUX) list(APPEND compile_options "-fno-shrink-wrap") # Disable shrink-wrapping to reduce binary size endif() elseif(CONFIG_COMPILER_OPTIMIZATION_NONE) list(APPEND compile_options "-O0") elseif(CONFIG_COMPILER_OPTIMIZATION_PERF) list(APPEND compile_options "-O2") endif() else() # BOOTLOADER_BUILD if(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE) list(APPEND compile_options "-Os") if(CMAKE_C_COMPILER_ID MATCHES "GNU") list(APPEND compile_options "-freorder-blocks") endif() elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG) list(APPEND compile_options "-Og") if(CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT CONFIG_IDF_TARGET_LINUX) list(APPEND compile_options "-fno-shrink-wrap") # Disable shrink-wrapping to reduce binary size endif() elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE) list(APPEND compile_options "-O0") elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF) list(APPEND compile_options "-O2") endif() endif() if(CONFIG_COMPILER_CXX_EXCEPTIONS) list(APPEND cxx_compile_options "-fexceptions") else() list(APPEND cxx_compile_options "-fno-exceptions") endif() if(CONFIG_COMPILER_CXX_RTTI) list(APPEND cxx_compile_options "-frtti") else() list(APPEND cxx_compile_options "-fno-rtti") list(APPEND link_options "-fno-rtti") # used to invoke correct multilib variant (no-rtti) during linking endif() if(CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS) list(APPEND compile_options "-msave-restore") endif() if(CMAKE_C_COMPILER_ID MATCHES "GNU") list(APPEND c_compile_options "-Wno-old-style-declaration") endif() # Clang finds some warnings in IDF code which GCC doesn't. # All these warnings should be fixed before Clang is presented # as a toolchain choice for users. if(CMAKE_C_COMPILER_ID MATCHES "Clang") # Clang checks Doxygen comments for being in sync with function prototype. # There are some inconsistencies, especially in ROM headers. list(APPEND compile_options "-Wno-documentation") # GCC allows repeated typedefs when the source and target types are the same. # Clang doesn't allow this. This occurs in many components due to forward # declarations. list(APPEND compile_options "-Wno-typedef-redefinition") # This issue is seemingly related to newlib's char type functions. # Fix is not clear yet. list(APPEND compile_options "-Wno-char-subscripts") # Clang seems to notice format string issues which GCC doesn't. list(APPEND compile_options "-Wno-format-security") # Logic bug in essl component list(APPEND compile_options "-Wno-tautological-overlap-compare") # Some pointer checks in mDNS component check addresses which can't be NULL list(APPEND compile_options "-Wno-tautological-pointer-compare") # Similar to the above, in tcp_transport list(APPEND compile_options "-Wno-pointer-bool-conversion") # mbedTLS md5.c triggers this warning in md5_test_buf (false positive) list(APPEND compile_options "-Wno-string-concatenation") # multiple cases of implict convertions between unrelated enum types list(APPEND compile_options "-Wno-enum-conversion") # When IRAM_ATTR is specified both in function declaration and definition, # it produces different section names, since section names include __COUNTER__. # Occurs in multiple places. list(APPEND compile_options "-Wno-section") # Multiple cases of attributes unknown to clang, for example # __attribute__((optimize("-O3"))) list(APPEND compile_options "-Wno-unknown-attributes") # Disable Clang warnings for atomic operations with access size # more then 4 bytes list(APPEND compile_options "-Wno-atomic-alignment") # several warnings in wpa_supplicant component list(APPEND compile_options "-Wno-unused-but-set-variable") # Clang also produces many -Wunused-function warnings which GCC doesn't. list(APPEND compile_options "-Wno-unused-function") # many warnings in bluedroid code # warning: field 'hdr' with variable sized type 'BT_HDR' not at the end of a struct or class is a GNU extension list(APPEND compile_options "-Wno-gnu-variable-sized-type-not-at-end") # several warnings in bluedroid code list(APPEND compile_options "-Wno-constant-logical-operand") # warning: '_Static_assert' with no message is a C2x extension list(APPEND compile_options "-Wno-c2x-extensions") # warning on xMPU_SETTINGS for esp32s2 has size 0 for C and 1 for C++ list(APPEND compile_options "-Wno-extern-c-compat") if(NOT (CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")) # warning: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 list(APPEND compile_options "-Wno-single-bit-bitfield-constant-conversion") endif() endif() # More warnings may exist in unit tests and example projects. if(CONFIG_COMPILER_WARN_WRITE_STRINGS) list(APPEND compile_options "-Wwrite-strings") endif() if(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE) list(APPEND compile_definitions "-DNDEBUG") endif() if(CONFIG_COMPILER_STACK_CHECK_MODE_NORM) list(APPEND compile_options "-fstack-protector") elseif(CONFIG_COMPILER_STACK_CHECK_MODE_STRONG) list(APPEND compile_options "-fstack-protector-strong") elseif(CONFIG_COMPILER_STACK_CHECK_MODE_ALL) list(APPEND compile_options "-fstack-protector-all") endif() if(CONFIG_COMPILER_DUMP_RTL_FILES) list(APPEND compile_options "-fdump-rtl-expand") endif() if(NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS 8.0.0) if(CONFIG_COMPILER_HIDE_PATHS_MACROS) list(APPEND compile_options "-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.") list(APPEND compile_options "-fmacro-prefix-map=${IDF_PATH}=/IDF") endif() if(CONFIG_APP_REPRODUCIBLE_BUILD) idf_build_set_property(DEBUG_PREFIX_MAP_GDBINIT "${BUILD_DIR}/prefix_map_gdbinit") list(APPEND compile_options "-fdebug-prefix-map=${IDF_PATH}=/IDF") list(APPEND compile_options "-fdebug-prefix-map=${PROJECT_DIR}=/IDF_PROJECT") list(APPEND compile_options "-fdebug-prefix-map=${BUILD_DIR}=/IDF_BUILD") # component dirs idf_build_get_property(python PYTHON) idf_build_get_property(idf_path IDF_PATH) idf_build_get_property(component_dirs BUILD_COMPONENT_DIRS) execute_process( COMMAND ${python} "${idf_path}/tools/generate_debug_prefix_map.py" "${BUILD_DIR}" "${component_dirs}" OUTPUT_VARIABLE result RESULT_VARIABLE ret ) if(NOT ret EQUAL 0) message(FATAL_ERROR "This is a bug. Please report to https://github.com/espressif/esp-idf/issues") endif() spaces2list(result) list(LENGTH component_dirs length) math(EXPR max_index "${length} - 1") foreach(index RANGE ${max_index}) list(GET component_dirs ${index} folder) list(GET result ${index} after) list(APPEND compile_options "-fdebug-prefix-map=${folder}=${after}") endforeach() endif() endif() if(CONFIG_COMPILER_DISABLE_GCC12_WARNINGS) list(APPEND compile_options "-Wno-address" "-Wno-use-after-free") endif() if(CONFIG_COMPILER_DISABLE_GCC13_WARNINGS) list(APPEND compile_options "-Wno-xor-used-as-pow") list(APPEND c_compile_options "-Wno-enum-int-mismatch") list(APPEND cxx_compile_options "-Wno-self-move" "-Wno-dangling-reference") endif() # GCC-specific options if(CMAKE_C_COMPILER_ID STREQUAL "GNU") list(APPEND compile_options "-fstrict-volatile-bitfields" ) endif() if(CONFIG_ESP_SYSTEM_USE_EH_FRAME) list(APPEND compile_options "-fasynchronous-unwind-tables") list(APPEND link_options "-Wl,--eh-frame-hdr") endif() list(APPEND link_options "-fno-lto") if(CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") list(APPEND link_options "-Wl,-dead_strip") list(APPEND link_options "-Wl,-warn_commons") else() list(APPEND link_options "-Wl,--gc-sections") list(APPEND link_options "-Wl,--warn-common") endif() # SMP FreeRTOS user provided minimal idle hook. This allows the user to provide # their own copy of vApplicationMinimalIdleHook() if(CONFIG_FREERTOS_USE_MINIMAL_IDLE_HOOK) list(APPEND link_options "-Wl,--wrap=vApplicationMinimalIdleHook") endif() # Placing jump tables in flash would cause issues with code that required # to be placed in IRAM list(APPEND compile_options "-fno-jump-tables") if(CMAKE_C_COMPILER_ID MATCHES "GNU") # This flag is GCC-specific. # Not clear yet if some other flag should be used for Clang. list(APPEND compile_options "-fno-tree-switch-conversion") endif() if(CMAKE_C_COMPILER_ID MATCHES "Clang") list(APPEND compile_options "-fno-use-cxa-atexit") endif() if(COMPILER_RT_LIB_NAME) list(APPEND link_options "-rtlib=${CONFIG_COMPILER_RT_LIB_NAME}") endif() # For the transition period from 32-bit time_t to 64-bit time_t, # auto-detect the size of this type and set corresponding variable. include(CheckTypeSize) check_type_size("time_t" TIME_T_SIZE) if(TIME_T_SIZE) idf_build_set_property(TIME_T_SIZE ${TIME_T_SIZE}) else() message(FATAL_ERROR "Failed to determine sizeof(time_t)") endif() idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND) idf_build_set_property(C_COMPILE_OPTIONS "${c_compile_options}" APPEND) idf_build_set_property(CXX_COMPILE_OPTIONS "${cxx_compile_options}" APPEND) idf_build_set_property(ASM_COMPILE_OPTIONS "${asm_compile_options}" APPEND) idf_build_set_property(COMPILE_DEFINITIONS "${compile_definitions}" APPEND) idf_build_set_property(LINK_OPTIONS "${link_options}" APPEND) idf_build_get_property(build_component_targets __BUILD_COMPONENT_TARGETS) # Add each component as a subdirectory, processing each component's CMakeLists.txt foreach(component_target ${build_component_targets}) __component_get_property(dir ${component_target} COMPONENT_DIR) __component_get_property(_name ${component_target} COMPONENT_NAME) __component_get_property(prefix ${component_target} __PREFIX) __component_get_property(alias ${component_target} COMPONENT_ALIAS) set(COMPONENT_NAME ${_name}) set(COMPONENT_DIR ${dir}) set(COMPONENT_ALIAS ${alias}) set(COMPONENT_PATH ${dir}) # for backward compatibility only, COMPONENT_DIR is preferred idf_build_get_property(build_prefix __PREFIX) set(__idf_component_context 1) if(NOT prefix STREQUAL build_prefix) add_subdirectory(${dir} ${prefix}_${_name}) else() add_subdirectory(${dir} ${_name}) endif() set(__idf_component_context 0) endforeach()