mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
ESP-IDF compiles every component with -ffunction-sections/-fdata-sections and
links with -Wl,--gc-sections, so that code and data nothing references does not
reach the image. With CONFIG_COMPILER_LTO_LINKTIME the object files carry GIMPLE
instead of machine code and code generation is deferred to the link, where those
two options no longer apply. The LTO partition is therefore emitted as a single
.text/.rodata, and since --gc-sections works at section granularity it can only
keep or drop that section as a whole. Some function in it is always live, so
nothing is dropped.
The options are recorded in the object file (in the .gnu.lto_.opts section), but
they do not reach the code generator. Code generation at link time runs as a
separate compiler invocation (LTRANS) whose command line lto-wrapper
reconstructs from those recorded options, and append_compiler_options() in
gcc/lto-wrapper.cc forwards only CL_TARGET options plus a small hard-coded list:
-fPIC/-fpic/-fPIE/-fpie, -fcommon, -fgnu-tm, -fopenmp/-fopenacc, -fcf-protection=,
(-fasynchronous-)unwind-tables, -g, -O/-Os/-Og/-Ofast/-Oz and the diagnostics
formatting options. Everything else hits the default arm and is dropped.
-ffunction-sections/-fdata-sections are neither. They are plain Common options in
common.opt without the Optimization marker, so they are not part of the
per-function state that is streamed with each function (which is why -O2 and -Os
do survive per translation unit under LTO), and they are not target options
either. They reach LTRANS only if they are repeated on the link command line.
Pass them next to -flto=auto, in both build systems.
This can be verified on any LTO build by adding -save-temps to the link options
and inspecting the generated <output>.ltrans.mk, which contains the literal
LTRANS command line:
grep -o -- "-ffunction-sections\|-fdata-sections" build/*.ltrans.mk
Measured on esp32c3 with -Os and CONFIG_COMPILER_LTO_COMPILETIME, application
binary size in bytes:
no LTO LTO LTO+fix fix saves
hello_world 116112 119792 115808 -3984 (-3.33%)
wifi/getting_started 734720 792960 732976 -59984 (-7.56%)
Without this change, enabling LTO produces a larger image than not using LTO at
all; with it, LTO is size neutral to slightly positive.
Two effects contribute. The dead code inside the partition itself stays, which
scales with how much code was compiled with LTO. On top of that, every function
retained this way keeps whatever it references alive as well, transitively and
across object boundaries: constant data, other functions, and sections of objects
that were not compiled with LTO at all. That second effect is not bounded by the
size of the LTO partition and can dominate. In the wifi/getting_started case a
single retained function, esp_crt_bundle_attach(), is the only referrer of the
mbedTLS certificate bundle, so a 55 KB .rodata blob stayed in an application that
never uses TLS. A plain non-LTO build collects all of it, which is what this
change restores.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
1002 lines
43 KiB
CMake
1002 lines
43 KiB
CMake
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
include_guard(GLOBAL)
|
|
|
|
#[[
|
|
__init_project_name()
|
|
|
|
Initialize the PROJECT_NAME build property, using CMAKE_PROJECT_NAME as a
|
|
fallback.
|
|
#]]
|
|
function(__init_project_name)
|
|
__get_default_value(VARIABLE PROJECT_NAME
|
|
DEFAULT "${CMAKE_PROJECT_NAME}"
|
|
OUTPUT project_name)
|
|
idf_build_set_property(PROJECT_NAME "${project_name}")
|
|
endfunction()
|
|
|
|
#[[
|
|
__init_project_version()
|
|
|
|
Initialize the PROJECT_VER build property based on the following
|
|
precedence.
|
|
|
|
1. The PROJECT_VER environment or CMake variable.
|
|
2. The version.txt file located in the top-level project directory.
|
|
3. The VERSION argument, if provided, in the project() macro.
|
|
4. The output of git describe if the project is within a Git repository.
|
|
5. Defaults to 1 if none of the above conditions are met.
|
|
|
|
The value of PROJECT_VER will be overridden later if
|
|
CONFIG_APP_PROJECT_VER_FROM_CONFIG is defined. For more details, refer to
|
|
components/esp_app_format/CMakeLists.txt.
|
|
#]]
|
|
function(__init_project_version)
|
|
idf_build_get_property(project_dir PROJECT_DIR)
|
|
|
|
# 1. The PROJECT_VER environment or CMake variable.
|
|
__get_default_value(VARIABLE PROJECT_VER
|
|
DEFAULT NOTFOUND
|
|
OUTPUT project_ver)
|
|
if(project_ver)
|
|
idf_build_set_property(PROJECT_VER "${project_ver}")
|
|
return()
|
|
endif()
|
|
|
|
# 2. The version.txt file located in the top-level project directory.
|
|
if(EXISTS "${project_dir}/version.txt")
|
|
file(STRINGS "${project_dir}/version.txt" project_ver)
|
|
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${project_dir}/version.txt")
|
|
idf_build_set_property(PROJECT_VER "${project_ver}")
|
|
return()
|
|
endif()
|
|
|
|
# 3. The VERSION argument, if provided, in the project() macro.
|
|
if(PROJECT_VERSION)
|
|
idf_build_set_property(PROJECT_VER "${PROJECT_VERSION}")
|
|
return()
|
|
endif()
|
|
|
|
# 4. The output of git describe if the project is within a Git repository.
|
|
git_describe(project_ver "${project_dir}")
|
|
if(project_ver)
|
|
idf_build_set_property(PROJECT_VER "${project_ver}")
|
|
return()
|
|
endif()
|
|
|
|
# 5. Defaults to 1 if none of the above conditions are met.
|
|
idf_build_set_property(PROJECT_VER 1)
|
|
endfunction()
|
|
|
|
#[[
|
|
__init_project_configuration()
|
|
|
|
Configure the build settings in one location, incorporating preset
|
|
compilation flags, definitions, and settings based on sdkconfig.
|
|
#]]
|
|
function(__init_project_configuration)
|
|
set(compile_definitions)
|
|
set(compile_options)
|
|
set(c_compile_options)
|
|
set(cxx_compile_options)
|
|
set(asm_compile_options)
|
|
set(link_options)
|
|
|
|
idf_build_get_property(idf_ver IDF_VER)
|
|
idf_build_get_property(idf_path IDF_PATH)
|
|
idf_build_get_property(idf_target IDF_TARGET)
|
|
idf_build_get_property(component_interfaces COMPONENT_INTERFACES)
|
|
idf_build_get_property(build_dir BUILD_DIR)
|
|
idf_build_get_property(project_dir PROJECT_DIR)
|
|
idf_build_get_property(project_name PROJECT_NAME)
|
|
get_property(enabled_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
|
|
|
|
set(c_enabled OFF)
|
|
if(C IN_LIST enabled_languages)
|
|
set(c_enabled ON)
|
|
endif()
|
|
|
|
set(cxx_enabled OFF)
|
|
if(CXX IN_LIST enabled_languages)
|
|
set(cxx_enabled ON)
|
|
endif()
|
|
|
|
# Set the LINKER_TYPE build property. Different linkers may have varying
|
|
# options, so it's important to identify the linker type to configure the
|
|
# options correctly. Currently, LINKER_TYPE is used to set the appropriate
|
|
# linker options for linking the entire archive, which differs between the
|
|
# GNU and Apple linkers when building on the host.
|
|
if(CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
|
# Compiling for the host, and the host is macOS, so the linker is Darwin LD.
|
|
# Note, when adding support for Clang and LLD based toolchain this check will
|
|
# need to be modified.
|
|
set(linker_type "Darwin")
|
|
else()
|
|
set(linker_type "GNU")
|
|
endif()
|
|
idf_build_set_property(LINKER_TYPE "${linker_type}")
|
|
|
|
list(APPEND compile_definitions "_GLIBCXX_USE_POSIX_SEMAPHORE" # These two lines enable libstd++ to use
|
|
"_GLIBCXX_HAVE_POSIX_SEMAPHORE" # posix-semaphores from components/pthread
|
|
"_GNU_SOURCE")
|
|
|
|
list(APPEND compile_definitions "ESP_PLATFORM")
|
|
list(APPEND compile_definitions "IDF_VER=\"${idf_ver}\"")
|
|
|
|
list(APPEND compile_options "-ffunction-sections"
|
|
"-fdata-sections"
|
|
# warning-related flags
|
|
"-Wall"
|
|
"-Wno-error=unused-function"
|
|
"-Wno-error=unused-variable"
|
|
"-Wno-error=unused-but-set-variable"
|
|
"-Wno-error=deprecated-declarations"
|
|
"-Wextra"
|
|
"-Wno-error=extra"
|
|
"-Wno-unused-parameter"
|
|
"-Wno-sign-compare"
|
|
# ignore multiple enum conversion warnings since gcc 11
|
|
# TODO: IDF-5163
|
|
"-Wno-enum-conversion"
|
|
# Default is dwarf-5 since GCC 11, fallback to dwarf-4 because of binary size
|
|
# TODO: IDF-5160
|
|
"-gdwarf-4"
|
|
# always generate debug symbols (even in release mode, these don't
|
|
# go into the final binary so have no impact on size
|
|
"-ggdb")
|
|
|
|
if(CONFIG_COMPILER_DISABLE_DEFAULT_ERRORS AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
|
|
list(APPEND compile_options "-Werror=all")
|
|
else()
|
|
list(APPEND compile_options "-Werror")
|
|
endif()
|
|
|
|
if(IDF_TARGET STREQUAL "linux")
|
|
# Building for Linux target, fall back to an older version of the standard
|
|
# if the preferred one is not supported by the compiler.
|
|
if(c_enabled)
|
|
set(preferred_c_versions gnu23 gnu17 gnu11 gnu99)
|
|
set(ver_found FALSE)
|
|
foreach(c_version ${preferred_c_versions})
|
|
check_c_compiler_flag("-std=${c_version}" ver_${c_version}_supported)
|
|
if(ver_${c_version}_supported)
|
|
set(c_std ${c_version})
|
|
set(ver_found TRUE)
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
if(NOT ver_found)
|
|
idf_die("Failed to set C language standard to one of the supported versions: "
|
|
"${preferred_c_versions}. Please upgrade the host compiler.")
|
|
endif()
|
|
|
|
list(APPEND c_compile_options "-std=${c_std}")
|
|
endif()
|
|
|
|
if(cxx_enabled)
|
|
set(preferred_cxx_versions gnu++26 gnu++2b gnu++20 gnu++2a gnu++17 gnu++14)
|
|
set(ver_found FALSE)
|
|
foreach(cxx_version ${preferred_cxx_versions})
|
|
check_cxx_compiler_flag("-std=${cxx_version}" ver_${cxx_version}_supported)
|
|
if(ver_${cxx_version}_supported)
|
|
set(cxx_std ${cxx_version})
|
|
set(ver_found TRUE)
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
if(NOT ver_found)
|
|
idf_die("Failed to set C++ language standard to one of the supported versions: "
|
|
"${preferred_cxx_versions}. Please upgrade the host compiler.")
|
|
endif()
|
|
|
|
list(APPEND cxx_compile_options "-std=${cxx_std}")
|
|
endif()
|
|
else()
|
|
# Building for chip targets: we use a known version of the toolchain.
|
|
# Use latest supported versions.
|
|
# For Linux target -std settings, refer to the __linux_build_set_lang_version
|
|
# function, which must be called after project().
|
|
# Please update docs/en/api-guides/c.rst, docs/en/api-guides/cplusplus.rst and
|
|
# tools/test_apps/system/cxx_build_test/main/test_cxx_standard.cpp when changing this.
|
|
if(c_enabled)
|
|
list(APPEND c_compile_options "-std=gnu23")
|
|
endif()
|
|
if(cxx_enabled)
|
|
list(APPEND cxx_compile_options "-std=gnu++26")
|
|
endif()
|
|
endif()
|
|
|
|
# Subprojects that handle their own compiler optimization flags can set the
|
|
# SET_COMPILER_OPTIMIZATION build property to NO before idf_project_init().
|
|
idf_build_get_property(set_compiler_optimization SET_COMPILER_OPTIMIZATION)
|
|
if(NOT DEFINED set_compiler_optimization OR set_compiler_optimization STREQUAL "")
|
|
set(set_compiler_optimization YES)
|
|
endif()
|
|
if(set_compiler_optimization)
|
|
if(CONFIG_COMPILER_OPTIMIZATION_SIZE)
|
|
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
|
list(APPEND compile_options "-Oz")
|
|
else()
|
|
list(APPEND compile_options "-Os")
|
|
endif()
|
|
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()
|
|
endif()
|
|
|
|
if(cxx_enabled)
|
|
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()
|
|
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()
|
|
|
|
if(c_enabled)
|
|
# TODO IDF-15784: remove in IDF v7.0 ?
|
|
check_c_compiler_flag("-Wunused-but-set-variable=1" compiler_supports_wunused_but_set_variable_eq_1)
|
|
if(compiler_supports_wunused_but_set_variable_eq_1)
|
|
list(APPEND compile_options "-Wunused-but-set-variable=1")
|
|
endif()
|
|
endif()
|
|
|
|
if(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_UNINITIALIZED)
|
|
set(compiler_cxx_trivial_auto_var_init "uninitialized")
|
|
elseif(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_PATTERN)
|
|
set(compiler_cxx_trivial_auto_var_init "pattern")
|
|
elseif(CONFIG_COMPILER_CXX_TRIVIAL_AUTO_VAR_INIT_ZERO)
|
|
set(compiler_cxx_trivial_auto_var_init "zero")
|
|
endif()
|
|
if(NOT IDF_CUSTOM_TOOLCHAIN AND cxx_enabled AND compiler_cxx_trivial_auto_var_init)
|
|
idf_toolchain_remove_flags(CXX_COMPILE_OPTIONS "-ftrivial-auto-var-init")
|
|
check_cxx_compiler_flag("-ftrivial-auto-var-init=${compiler_cxx_trivial_auto_var_init}"
|
|
compiler_supports_ftrivial_auto_var_init)
|
|
if(compiler_supports_ftrivial_auto_var_init)
|
|
idf_toolchain_add_flags(CXX_COMPILE_OPTIONS "-ftrivial-auto-var-init=${compiler_cxx_trivial_auto_var_init}")
|
|
endif()
|
|
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")
|
|
# 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 implicit conversions 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_NO_MERGE_CONSTANTS)
|
|
list(APPEND compile_options "-fno-merge-constants")
|
|
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()
|
|
|
|
# Kernel Address Sanitizer (CONFIG_COMPILER_KASAN): instrument every memory
|
|
# load and store with a shadow-memory check. The flag goes into the C and C++
|
|
# options rather than the language-agnostic list because the assembler does
|
|
# not accept -fsanitize. Low-level components are de-instrumented again in
|
|
# idf_build_library(), see __kasan_exclude_components().
|
|
#
|
|
# A subproject that must never be instrumented (for example the bootloader,
|
|
# which runs before the sanitizer shadow is initialised) sets the
|
|
# SET_COMPILER_KASAN build property to NO before idf_project_init(), the
|
|
# same way it uses SET_COMPILER_LTO and SET_COMPILER_OPTIMIZATION; an unset
|
|
# property means instrumentation is allowed.
|
|
idf_build_get_property(set_compiler_kasan SET_COMPILER_KASAN)
|
|
if(NOT DEFINED set_compiler_kasan OR set_compiler_kasan STREQUAL "")
|
|
set(set_compiler_kasan YES)
|
|
endif()
|
|
if(CONFIG_COMPILER_KASAN AND set_compiler_kasan)
|
|
list(APPEND c_compile_options "-fsanitize=kernel-address")
|
|
list(APPEND cxx_compile_options "-fsanitize=kernel-address")
|
|
if(NOT CONFIG_KASAN_STACK)
|
|
list(APPEND c_compile_options "--param" "asan-stack=0")
|
|
list(APPEND cxx_compile_options "--param" "asan-stack=0")
|
|
endif()
|
|
list(APPEND link_options "-fsanitize=kernel-address")
|
|
endif()
|
|
|
|
if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
|
list(APPEND compile_options "-fdump-rtl-expand")
|
|
endif()
|
|
|
|
if(CMAKE_C_COMPILER_ID MATCHES "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 15.0)
|
|
list(APPEND c_compile_options "-fzero-init-padding-bits=all" "-fno-malloc-dce")
|
|
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()
|
|
|
|
if(CONFIG_COMPILER_DISABLE_GCC14_WARNINGS)
|
|
list(APPEND compile_options "-Wno-calloc-transposed-args")
|
|
endif()
|
|
|
|
if(CONFIG_COMPILER_DISABLE_GCC15_WARNINGS)
|
|
list(APPEND c_compile_options "-Wno-unterminated-string-initialization")
|
|
list(APPEND c_compile_options "-Wno-header-guard")
|
|
list(APPEND cxx_compile_options "-Wno-self-move")
|
|
list(APPEND cxx_compile_options "-Wno-template-body")
|
|
list(APPEND cxx_compile_options "-Wno-dangling-reference")
|
|
list(APPEND cxx_compile_options "-Wno-defaulted-function-deleted")
|
|
endif()
|
|
|
|
# GCC-specific options
|
|
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
|
list(APPEND compile_options "-fstrict-volatile-bitfields")
|
|
if(CONFIG_COMPILER_STATIC_ANALYZER)
|
|
list(APPEND compile_options "-fanalyzer")
|
|
endif()
|
|
endif()
|
|
|
|
if(CONFIG_ESP_SYSTEM_USE_EH_FRAME)
|
|
list(APPEND compile_options "-fasynchronous-unwind-tables")
|
|
list(APPEND link_options "-Wl,--eh-frame-hdr")
|
|
endif()
|
|
|
|
if(CONFIG_ESP_SYSTEM_USE_FRAME_POINTER)
|
|
list(APPEND compile_options "-fno-omit-frame-pointer")
|
|
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
|
list(APPEND compile_options "-mno-omit-leaf-frame-pointer")
|
|
endif()
|
|
endif()
|
|
|
|
# A subproject that must not use LTO (for example the bootloader) opts out by
|
|
# setting the SET_COMPILER_LTO build property to NO, the same way it uses
|
|
# SET_COMPILER_OPTIMIZATION; an unset property means LTO is allowed.
|
|
idf_build_get_property(set_compiler_lto SET_COMPILER_LTO)
|
|
if(NOT DEFINED set_compiler_lto OR set_compiler_lto STREQUAL "")
|
|
set(set_compiler_lto YES)
|
|
endif()
|
|
if(CONFIG_COMPILER_LTO_LINKTIME AND set_compiler_lto)
|
|
list(APPEND link_options "-flto=auto")
|
|
# LTO generates code at link time, so the -ffunction-sections/-fdata-sections
|
|
# applied to compile_options doesn't reach it: the LTRANS recompilation takes
|
|
# its code generation options from the link command line. Without them the
|
|
# LTO partition is emitted as a single .text/.data, which defeats
|
|
# -Wl,--gc-sections (it can only drop whole sections) and keeps unreferenced
|
|
# functions in the image.
|
|
list(APPEND link_options "-ffunction-sections"
|
|
"-fdata-sections")
|
|
else()
|
|
list(APPEND compile_options "-fno-lto")
|
|
endif()
|
|
|
|
if(CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
|
# Not all versions of the MacOS linker support the -warn_commons flag.
|
|
# ld version 1053.12 (and above) have been tested to support it.
|
|
# Hence, we extract the version string from the linker output
|
|
# before including the flag.
|
|
|
|
# Get the ld version, capturing both stdout and stderr
|
|
execute_process(
|
|
COMMAND ${CMAKE_LINKER} -v
|
|
OUTPUT_VARIABLE LD_VERSION_OUTPUT
|
|
ERROR_VARIABLE LD_VERSION_ERROR
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
ERROR_STRIP_TRAILING_WHITESPACE
|
|
)
|
|
|
|
# Combine stdout and stderr
|
|
set(LD_VERSION_OUTPUT "${LD_VERSION_OUTPUT}\n${LD_VERSION_ERROR}")
|
|
|
|
# Extract the version string
|
|
string(REGEX MATCH "PROJECT:(ld|dyld)-([0-9]+)\\.([0-9]+)" LD_VERSION_MATCH "${LD_VERSION_OUTPUT}")
|
|
set(LD_VERSION_MAJOR_MINOR "${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
|
|
|
|
idf_msg("Linker Version: ${LD_VERSION_MAJOR_MINOR}")
|
|
|
|
# Compare the version with 1053.12
|
|
if(LD_VERSION_MAJOR_MINOR VERSION_GREATER_EQUAL "1053.12")
|
|
list(APPEND link_options "-Wl,-warn_commons")
|
|
endif()
|
|
|
|
list(APPEND link_options "-Wl,-dead_strip")
|
|
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 vApplicationPassiveIdleHook()
|
|
if(CONFIG_FREERTOS_USE_PASSIVE_IDLE_HOOK)
|
|
list(APPEND link_options "-Wl,--wrap=vApplicationPassiveIdleHook")
|
|
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") # TODO IDF-10934
|
|
else()
|
|
list(APPEND cxx_compile_options "-fuse-cxa-atexit")
|
|
endif()
|
|
|
|
if(COMPILER_RT_LIB_NAME)
|
|
list(APPEND link_options "-rtlib=${CONFIG_COMPILER_RT_LIB_NAME}")
|
|
endif()
|
|
|
|
if("${linker_type}" STREQUAL "GNU")
|
|
set(target_upper "${idf_target}")
|
|
string(TOUPPER ${target_upper} target_upper)
|
|
# Add this symbol as a hint for esp_idf_size to guess the target name
|
|
list(APPEND link_options "-Wl,--defsym=IDF_TARGET_${target_upper}=0")
|
|
# Check if linker supports --no-warn-rwx-segments
|
|
execute_process(COMMAND ${CMAKE_LINKER} "--no-warn-rwx-segments" "--version"
|
|
RESULT_VARIABLE result
|
|
OUTPUT_QUIET
|
|
ERROR_QUIET)
|
|
if(${result} EQUAL 0)
|
|
# Do not print RWX segment warnings
|
|
list(APPEND link_options "-Wl,--no-warn-rwx-segments")
|
|
endif()
|
|
if(CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING)
|
|
# Print warnings if orphan sections are found
|
|
list(APPEND link_options "-Wl,--orphan-handling=warn")
|
|
endif()
|
|
endif()
|
|
|
|
# Prepares the list of compiler flags for remapping various paths to fixed
|
|
# names. This is used when reproducible builds are required. This function
|
|
# also creates a gdbinit file for the debugger to remap the substituted
|
|
# paths back to the real paths in the filesystem.
|
|
set(gdbinit_dir ${build_dir}/gdbinit)
|
|
set(gdbinit_path "${gdbinit_dir}/prefix_map")
|
|
set(prefix_map_compile_options)
|
|
|
|
if(CONFIG_COMPILER_HIDE_PATHS_MACROS)
|
|
list(APPEND prefix_map_compile_options "-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.")
|
|
list(APPEND prefix_map_compile_options "-fmacro-prefix-map=${idf_path}=/IDF")
|
|
endif()
|
|
|
|
if(CONFIG_APP_REPRODUCIBLE_BUILD)
|
|
list(APPEND prefix_map_compile_options "-fdebug-prefix-map=${idf_path}=/IDF")
|
|
list(APPEND prefix_map_compile_options "-fdebug-prefix-map=${project_dir}=/IDF_PROJECT")
|
|
list(APPEND prefix_map_compile_options "-fdebug-prefix-map=${build_dir}=/IDF_BUILD")
|
|
|
|
# Generate mapping for component paths
|
|
set(gdbinit_file_lines)
|
|
foreach(component_interface ${component_interfaces})
|
|
__idf_component_get_property_unchecked(component_name ${component_interface} COMPONENT_NAME)
|
|
__idf_component_get_property_unchecked(component_dir ${component_interface} COMPONENT_DIR)
|
|
|
|
string(TOUPPER ${component_name} component_name_uppercase)
|
|
set(substituted_path "/COMPONENT_${component_name_uppercase}_DIR")
|
|
list(APPEND prefix_map_compile_options "-fdebug-prefix-map=${component_dir}=${substituted_path}")
|
|
string(APPEND gdbinit_file_lines "set substitute-path ${substituted_path} ${component_dir}\n")
|
|
endforeach()
|
|
|
|
# Mapping for toolchain path
|
|
execute_process(
|
|
COMMAND ${CMAKE_C_COMPILER} -print-sysroot
|
|
OUTPUT_VARIABLE compiler_sysroot
|
|
)
|
|
if(compiler_sysroot STREQUAL "")
|
|
idf_die("Failed to determine toolchain sysroot")
|
|
endif()
|
|
string(STRIP "${compiler_sysroot}" compiler_sysroot)
|
|
get_filename_component(compiler_sysroot "${compiler_sysroot}/.." REALPATH)
|
|
list(APPEND prefix_map_compile_options "-fdebug-prefix-map=${compiler_sysroot}=/TOOLCHAIN")
|
|
string(APPEND gdbinit_file_lines "set substitute-path /TOOLCHAIN ${compiler_sysroot}\n")
|
|
else()
|
|
set(gdbinit_file_lines "# There is no prefix map defined for the project.\n")
|
|
endif()
|
|
list(APPEND compile_options ${prefix_map_compile_options})
|
|
# Write the prefix_map file even if it is empty.
|
|
file(MAKE_DIRECTORY ${gdbinit_dir})
|
|
file(WRITE "${gdbinit_path}" "${gdbinit_file_lines}")
|
|
|
|
if(CONFIG_APP_REPRODUCIBLE_BUILD AND CONFIG_COMPILER_LTO_LINKTIME AND set_compiler_lto)
|
|
# LTO generates code at link time, where the path remapping applied to
|
|
# compile_options doesn't take effect, so pass it to the linker as well.
|
|
# -save-temps keeps LTRANS objects out of $TMPDIR, and a pinned random
|
|
# seed makes LTO bytecode byte-identical. See the commit message of
|
|
# "feat(build): add options to enable link-time optimization (LTO)"
|
|
# for details.
|
|
list(APPEND link_options ${prefix_map_compile_options})
|
|
list(APPEND link_options "-save-temps")
|
|
list(APPEND compile_options "-frandom-seed=1")
|
|
endif()
|
|
|
|
idf_build_set_property(GDBINIT_FILES_PREFIX_MAP "${gdbinit_path}")
|
|
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)
|
|
endfunction()
|
|
|
|
#[[
|
|
__create_project_flash_targets()
|
|
|
|
Add placeholder flash targets to the build. This is used by components to
|
|
declare dependencies on the flash target.
|
|
#]]
|
|
function(__create_project_flash_targets)
|
|
if(NOT TARGET flash)
|
|
add_custom_target(flash)
|
|
endif()
|
|
|
|
# When flash encryption is enabled, a corresponding 'encrypted-flash' target will be created.
|
|
idf_build_get_property(sdkconfig SDKCONFIG)
|
|
__get_sdkconfig_option(OPTION CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
|
SDKCONFIG "${sdkconfig}"
|
|
OUTPUT sdkconfig_target)
|
|
if(encrypted_flash_enabled AND NOT TARGET encrypted-flash)
|
|
add_custom_target(encrypted-flash)
|
|
endif()
|
|
endfunction()
|
|
|
|
#[[
|
|
__init_project_flash_targets()
|
|
|
|
If binary generation is enabled, initialize the esptool component and
|
|
enable the generation of esptool flash argument files for the flash and
|
|
encrypted-flash targets. Note that this is done after including the
|
|
project_include.cmake files, as we need the functions defined in the
|
|
esptool_py component.
|
|
#]]
|
|
function(__init_project_flash_targets)
|
|
# Skip if esptool_py is not in the build set; the flash-target function
|
|
# would otherwise be undefined.
|
|
if(CONFIG_APP_BUILD_GENERATE_BINARIES AND COMMAND esptool_py_flash_target)
|
|
idf_component_get_property(main_args esptool_py FLASH_ARGS)
|
|
idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS)
|
|
esptool_py_flash_target(flash "${main_args}" "${sub_args}")
|
|
endif()
|
|
endfunction()
|
|
|
|
#[[api
|
|
.. cmakev2:macro:: idf_project_init
|
|
|
|
.. code-block:: cmake
|
|
|
|
idf_project_init()
|
|
|
|
Initialize settings that need to be configured after the ``project()``
|
|
function is called. This must occur after the ``project()`` function and
|
|
before any other build system functions. It initializes the
|
|
``PROJECT_NAME`` and ``PROJECT_VER`` build properties, as well as all
|
|
default C, CXX, and ASM compile options, link options, and compile
|
|
definitions.
|
|
|
|
This macro also includes ``project_include.cmake`` files for the discovered
|
|
components, as these files define project-wide functionality that needs to
|
|
be available before any component's ``CMakeLists.txt`` is evaluated. The
|
|
``project_include.cmake`` files should be evaluated in the global scope.
|
|
Therefore, this is defined as a macro and should be called only from the
|
|
global scope or from within another macro.
|
|
#]]
|
|
macro(idf_project_init)
|
|
idf_build_get_property(project_initialized __PROJECT_INITIALIZED)
|
|
if(NOT project_initialized)
|
|
# Ensure this function is executed only once throughout the entire
|
|
# project.
|
|
|
|
# The IDF_TOOLCHAIN variable is established as a CMake cache variable
|
|
# during the toolchain initialization process in
|
|
# ``tools/cmake/toolchain.cmake``.
|
|
idf_build_set_property(IDF_TOOLCHAIN "${IDF_TOOLCHAIN}")
|
|
|
|
# Warn about the use of deprecated variables.
|
|
deprecate_variable(COMPONENTS)
|
|
deprecate_variable(EXCLUDE_COMPONENTS)
|
|
|
|
# Set PROJECT_NAME build property
|
|
__init_project_name()
|
|
|
|
# Set PROJECT_VER build property
|
|
__init_project_version()
|
|
|
|
# Create global flash targets.
|
|
__create_project_flash_targets()
|
|
|
|
# Discover and initialize components
|
|
__init_components()
|
|
|
|
# Save original sdkconfig before kconfgen may drop unknown options.
|
|
# Only creates a backup when the component manager is enabled.
|
|
__create_sdkconfig_orig_copy()
|
|
|
|
# When the component manager is enabled, suppress kconfgen warnings
|
|
# on this initial pass. Managed component symbols are unknown at this
|
|
# stage and will be resolved after __fetch_components_from_registry().
|
|
idf_build_get_property(idf_component_manager IDF_COMPONENT_MANAGER)
|
|
if(idf_component_manager EQUAL 1)
|
|
idf_build_set_property(__KCONFGEN_QUIET YES)
|
|
endif()
|
|
|
|
# Generate initial sdkconfig with discovered components
|
|
__generate_sdkconfig()
|
|
|
|
# Fetch managed components from registry if the component manager is enabled
|
|
idf_build_get_property(idf_component_manager IDF_COMPONENT_MANAGER)
|
|
if(idf_component_manager EQUAL 1)
|
|
__fetch_components_from_registry()
|
|
else()
|
|
__component_manager_warn_if_disabled_and_manifests_exist()
|
|
endif()
|
|
|
|
# Include sdkconfig.cmake
|
|
idf_build_get_property(sdkconfig_cmake __SDKCONFIG_CMAKE)
|
|
if(NOT EXISTS "${sdkconfig_cmake}")
|
|
idf_die("sdkconfig.cmake file not found.")
|
|
endif()
|
|
include("${sdkconfig_cmake}")
|
|
unset(sdkconfig_cmake)
|
|
|
|
# Initialize all compilation options and defines.
|
|
# This must be done after including sdkconfig.cmake
|
|
__init_project_configuration()
|
|
|
|
# Initialize the target architecture based on the configuration
|
|
# Ensure this is done after including the sdkconfig.
|
|
__init_idf_target_arch()
|
|
|
|
# Make build properties available as CMake variables for backward
|
|
# compatibility with project_include.cmake files (e.g. ULP component
|
|
# references ${SDKCONFIG_HEADER} and ${SDKCONFIG_CMAKE} directly).
|
|
idf_build_get_property(build_properties BUILD_PROPERTIES)
|
|
foreach(build_property IN LISTS build_properties)
|
|
idf_build_get_property(val ${build_property})
|
|
set(${build_property} "${val}")
|
|
endforeach()
|
|
|
|
# Include all project_include.cmake files for the components that have
|
|
# been discovered.
|
|
idf_build_get_property(component_interfaces COMPONENT_INTERFACES)
|
|
foreach(component_interface IN LISTS component_interfaces)
|
|
__idf_component_get_property_unchecked(project_include ${component_interface} __PROJECT_INCLUDE)
|
|
__idf_component_get_property_unchecked(component_dir ${component_interface} COMPONENT_DIR)
|
|
__idf_component_get_property_unchecked(component_name ${component_interface} COMPONENT_NAME)
|
|
if(project_include)
|
|
set(COMPONENT_NAME ${component_name})
|
|
set(COMPONENT_DIR ${component_dir})
|
|
# The use of COMPONENT_PATH is deprecated in cmakev1. Users
|
|
# are encouraged to use COMPONENT_DIR instead.
|
|
set(COMPONENT_PATH ${component_dir})
|
|
idf_dbg("Including ${project_include}")
|
|
include("${project_include}")
|
|
unset(COMPONENT_NAME)
|
|
unset(COMPONENT_DIR)
|
|
unset(COMPONENT_PATH)
|
|
endif()
|
|
endforeach()
|
|
|
|
# Initialize global flash targets.
|
|
__init_project_flash_targets()
|
|
|
|
# If explicitly requested, include all components by calling
|
|
# `add_subdirectory` for every discovered component. The default
|
|
# behavior is to include only the components based on the requirements.
|
|
__get_default_value(VARIABLE IDF_INCLUDE_ALL_COMPONENTS
|
|
DEFAULT NO
|
|
OUTPUT include_all_components)
|
|
if(include_all_components)
|
|
idf_msg("Including all discovered components")
|
|
foreach(component_name IN LISTS component_names)
|
|
idf_component_include("${component_name}")
|
|
endforeach()
|
|
endif()
|
|
unset(include_all_components)
|
|
|
|
idf_build_set_property(__PROJECT_INITIALIZED YES)
|
|
endif()
|
|
unset(project_initialized)
|
|
endmacro()
|
|
|
|
#[[api
|
|
.. cmakev2:function:: idf_build_generate_flasher_args
|
|
|
|
.. code-block:: cmake
|
|
|
|
idf_build_generate_flasher_args()
|
|
|
|
Generate the flasher_args.json file for the global flash target for tools
|
|
that require it.
|
|
#]]
|
|
function(idf_build_generate_flasher_args)
|
|
# The variables listed below are used to configure the template
|
|
# flasher_args.json.in. Some of these variables, such as flash mode, size,
|
|
# and frequency, are set as properties of the esptool_py component.
|
|
|
|
idf_build_get_property(target IDF_TARGET)
|
|
set(ESPTOOLPY_CHIP "${target}")
|
|
set(ESPTOOLPY_BEFORE "${CONFIG_ESPTOOLPY_BEFORE}")
|
|
set(ESPTOOLPY_AFTER "${CONFIG_ESPTOOLPY_AFTER}")
|
|
if(CONFIG_ESPTOOLPY_NO_STUB)
|
|
set(ESPTOOLPY_WITH_STUB false)
|
|
else()
|
|
set(ESPTOOLPY_WITH_STUB true)
|
|
endif()
|
|
|
|
if(CONFIG_SECURE_BOOT OR CONFIG_SECURE_FLASH_ENC_ENABLED)
|
|
# If security enabled then override post flash option
|
|
set(ESPTOOLPY_AFTER "no-reset")
|
|
endif()
|
|
|
|
idf_component_get_property(ESPFLASHMODE esptool_py ESPFLASHMODE)
|
|
idf_component_get_property(ESPFLASHFREQ esptool_py ESPFLASHFREQ)
|
|
idf_component_get_property(ESPFLASHSIZE esptool_py ESPFLASHSIZE)
|
|
idf_component_get_property(esptool_py_dir esptool_py COMPONENT_DIR)
|
|
|
|
# Generate flasher args files
|
|
idf_build_get_property(build_dir BUILD_DIR)
|
|
file(READ "${esptool_py_dir}/flasher_args.json.in" flasher_args_content)
|
|
string(CONFIGURE "${flasher_args_content}" flasher_args_content)
|
|
|
|
# We need to create a flasher_args.json.in to create the final flasher_args.json
|
|
# because CMake only resolves generator expressions in the file_generate command
|
|
# with the INPUT keyword during the generation phase.
|
|
file_generate("${build_dir}/flasher_args.json.in"
|
|
CONTENT "${flasher_args_content}")
|
|
file_generate("${build_dir}/flasher_args.json"
|
|
INPUT "${build_dir}/flasher_args.json.in")
|
|
endfunction()
|
|
|
|
#[[
|
|
.. cmakev2:macro:: __project_default
|
|
|
|
.. code-block:: cmake
|
|
|
|
__project_default()
|
|
|
|
Helper function implementing the main idf_project_default macro
|
|
functionality, preventing global variable scope pollution.
|
|
#]]
|
|
function(__project_default)
|
|
idf_build_get_property(build_dir BUILD_DIR)
|
|
idf_build_get_property(executable PROJECT_NAME)
|
|
|
|
# When the Build system v1 compatibility shim forwarded a COMPONENTS
|
|
# list, use it instead of default main.
|
|
idf_build_get_property(shim_components __SHIM_COMPONENTS)
|
|
if(shim_components)
|
|
set(root_components ${shim_components})
|
|
else()
|
|
set(root_components main)
|
|
endif()
|
|
|
|
idf_build_executable("${executable}"
|
|
COMPONENTS ${root_components}
|
|
MAPFILE_TARGET "${executable}_mapfile")
|
|
|
|
# In Build system v1, the ``project_elf`` variable (set to
|
|
# "${project_name}.elf") is used by several app CMakeLists.txt files to add
|
|
# linker flags after project(). In Build system v2 the executable target
|
|
# is just "${executable}" (the .elf suffix is an output property, not part
|
|
# of the target name). Propagate it to the caller's scope so existing
|
|
# code keeps working.
|
|
set(project_elf "${executable}" PARENT_SCOPE)
|
|
|
|
# Provide Build system v1-compatible build properties so that existing
|
|
# test apps and project CMakeLists.txt files that query EXECUTABLE or
|
|
# BUILD_COMPONENTS continue to work when built through the shim.
|
|
idf_build_get_property(v1_compat __V1_COMPAT_SHIM)
|
|
if(v1_compat)
|
|
idf_build_set_property(EXECUTABLE "${executable}")
|
|
idf_build_set_property(EXECUTABLE_NAME "${executable}")
|
|
|
|
# BUILD_COMPONENTS: in Build system v1 this is the set of components
|
|
# actually processed during the build (COMPONENTS + their transitive
|
|
# REQUIRES within the restricted scope). Use LIBRARY_COMPONENTS_LINKED
|
|
# from the Build system v2 library target which reflects the actual
|
|
# list of components linked, plus the architecture component which
|
|
# Build system v1 always includes but Build system v2 does not track
|
|
# as a linked library.
|
|
get_target_property(library ${executable} LIBRARY_INTERFACE)
|
|
if(library)
|
|
idf_library_get_property(linked_components "${library}" LIBRARY_COMPONENTS_LINKED)
|
|
idf_build_get_property(target_arch IDF_TARGET_ARCH)
|
|
if(target_arch AND NOT target_arch IN_LIST linked_components)
|
|
list(APPEND linked_components ${target_arch})
|
|
endif()
|
|
idf_build_set_property(BUILD_COMPONENTS "${linked_components}")
|
|
endif()
|
|
endif()
|
|
|
|
if(CONFIG_APP_BUILD_GENERATE_BINARIES AND TARGET idf::esptool_py)
|
|
# Is it possible to have a configuration where
|
|
# CONFIG_APP_BUILD_GENERATE_BINARIES is not set?
|
|
|
|
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
|
idf_build_binary("${executable}"
|
|
OUTPUT_FILE "${build_dir}/${executable}-unsigned.bin"
|
|
TARGET "${executable}_binary_unsigned")
|
|
idf_sign_binary("${executable}_binary_unsigned"
|
|
OUTPUT_FILE "${build_dir}/${executable}.bin"
|
|
TARGET "${executable}_binary_signed")
|
|
idf_check_binary_size("${executable}_binary_signed")
|
|
|
|
add_custom_target(app ALL DEPENDS "${executable}_binary_signed")
|
|
|
|
idf_flash_binary("${executable}_binary_signed"
|
|
TARGET app-flash
|
|
NAME "app"
|
|
FLASH)
|
|
idf_build_generate_metadata(BINARY "${executable}_binary_signed"
|
|
HINTS_OUTPUT_FILE "${BUILD_DIR}/hints.yml")
|
|
else()
|
|
idf_build_binary("${executable}"
|
|
OUTPUT_FILE "${build_dir}/${executable}.bin"
|
|
TARGET "${executable}_binary")
|
|
idf_check_binary_size("${executable}_binary")
|
|
idf_check_binary_signed("${executable}_binary")
|
|
|
|
add_custom_target(app ALL DEPENDS "${executable}_binary")
|
|
|
|
idf_flash_binary("${executable}_binary"
|
|
TARGET app-flash
|
|
NAME "app"
|
|
FLASH)
|
|
|
|
idf_create_dfu("${executable}_binary"
|
|
TARGET dfu)
|
|
idf_build_generate_metadata(BINARY "${executable}_binary"
|
|
HINTS_OUTPUT_FILE "${BUILD_DIR}/hints.yml")
|
|
endif()
|
|
|
|
idf_build_generate_flasher_args()
|
|
else()
|
|
idf_build_generate_metadata(EXECUTABLE "${executable}"
|
|
HINTS_OUTPUT_FILE "${BUILD_DIR}/hints.yml")
|
|
endif()
|
|
|
|
idf_create_menuconfig("${executable}"
|
|
TARGET menuconfig-app)
|
|
idf_register_menuconfig(NAME "Main application"
|
|
TARGET menuconfig-app)
|
|
__finalize_menuconfig()
|
|
|
|
idf_create_confserver("${executable}"
|
|
TARGET confserver)
|
|
|
|
idf_create_save_defconfig()
|
|
|
|
idf_create_config_report("${executable}"
|
|
TARGET config-report)
|
|
|
|
idf_create_uf2("${executable}"
|
|
TARGET uf2)
|
|
idf_create_uf2("${executable}"
|
|
TARGET uf2-app
|
|
APP_ONLY)
|
|
|
|
if(TARGET "${executable}_mapfile")
|
|
idf_create_size_report("${executable}_mapfile"
|
|
TARGET size)
|
|
endif()
|
|
|
|
idf_build_generate_depgraph("${executable}")
|
|
endfunction()
|
|
|
|
#[[api
|
|
.. cmakev2:macro:: idf_project_default
|
|
|
|
.. code-block:: cmake
|
|
|
|
idf_project_default()
|
|
|
|
Create a default project executable based on the main component and its
|
|
transitive dependencies. The executable name is derived from the
|
|
``PROJECT_NAME`` variable, which by default uses the ``CMAKE_PROJECT_NAME``
|
|
value specified in the CMake's ``project()`` call.
|
|
|
|
Generate the binary image for the executable, signed or unsigned based on
|
|
the configuration, and add flash targets for it.
|
|
#]]
|
|
macro(idf_project_default)
|
|
idf_project_init()
|
|
|
|
# Use DEFERRED optional-requires resolution only when this will be the sole
|
|
# library being built.
|
|
idf_build_set_property(IDF_COMPONENT_OPTIONAL_REQUIRES_MODE DEFERRED)
|
|
|
|
# Only the idf_project_init macro needs be called within the global scope,
|
|
# as it includes the project_include.cmake files and the cmake version of
|
|
# the configuration. The remaining functionality of the idf_project_default
|
|
# macro is implemented in a __project_default helper function to avoid
|
|
# polluting the global variable space.
|
|
__project_default()
|
|
endmacro()
|