261 lines
No EOL
8.4 KiB
CMake
261 lines
No EOL
8.4 KiB
CMake
# Some IDF-specific functions and functions
|
|
|
|
include(crosstool_version_check)
|
|
|
|
#
|
|
# Set some variables used by rest of the build
|
|
#
|
|
# Note at the time this macro is expanded, the config is not yet
|
|
# loaded and the toolchain and project are not yet set
|
|
#
|
|
macro(idf_set_global_variables)
|
|
# Note that CONFIG_xxx is not available when this function is called
|
|
|
|
set_default(EXTRA_COMPONENT_DIRS "")
|
|
|
|
# Commmon components, required by every component in the build
|
|
#
|
|
set_default(COMPONENT_REQUIRES_COMMON "cxx ${IDF_TARGET} newlib freertos heap log soc")
|
|
|
|
# PROJECT_PATH has the path to the IDF project (top-level cmake directory)
|
|
#
|
|
# (cmake calls this CMAKE_SOURCE_DIR, keeping old name for compatibility.)
|
|
set(PROJECT_PATH "${CMAKE_SOURCE_DIR}")
|
|
|
|
if(MAIN_SRCS)
|
|
message(WARNING "main is now a component, use of MAIN_SRCS is deprecated")
|
|
set_default(COMPONENT_DIRS "${PROJECT_PATH}/components ${EXTRA_COMPONENT_DIRS} \
|
|
${IDF_PATH}/components")
|
|
else()
|
|
set_default(COMPONENT_DIRS "${PROJECT_PATH}/components ${EXTRA_COMPONENT_DIRS} \
|
|
${IDF_PATH}/components ${PROJECT_PATH}/main")
|
|
endif()
|
|
|
|
spaces2list(COMPONENT_DIRS)
|
|
|
|
spaces2list(COMPONENTS)
|
|
|
|
# Tell cmake to drop executables in the top-level build dir
|
|
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
|
|
|
|
# path to idf.py tool
|
|
set(IDFTOOL ${PYTHON} "${IDF_PATH}/tools/idf.py")
|
|
|
|
# Temporary trick to support both gcc5 and gcc8 builds
|
|
if(CMAKE_C_COMPILER_VERSION VERSION_EQUAL 5.2.0)
|
|
set(GCC_NOT_5_2_0 0)
|
|
else()
|
|
set(GCC_NOT_5_2_0 1)
|
|
endif()
|
|
endmacro()
|
|
|
|
# Add all the IDF global compiler & preprocessor options
|
|
# (applied to all components). Some are config-dependent
|
|
#
|
|
# If you only want to set options for a particular component,
|
|
# don't call or edit this function. TODO DESCRIBE WHAT TO DO INSTEAD
|
|
#
|
|
function(idf_set_global_compiler_options)
|
|
add_definitions(-DESP_PLATFORM)
|
|
add_definitions(-DHAVE_CONFIG_H)
|
|
|
|
if(CONFIG_OPTIMIZATION_LEVEL_RELEASE)
|
|
add_compile_options(-Os)
|
|
else()
|
|
add_compile_options(-Og)
|
|
endif()
|
|
|
|
add_c_compile_options(-std=gnu99)
|
|
|
|
add_cxx_compile_options(-std=gnu++11 -fno-rtti)
|
|
|
|
if(CONFIG_CXX_EXCEPTIONS)
|
|
add_cxx_compile_options(-fexceptions)
|
|
else()
|
|
add_cxx_compile_options(-fno-exceptions)
|
|
endif()
|
|
|
|
# Default compiler configuration
|
|
add_compile_options(-ffunction-sections -fdata-sections -fstrict-volatile-bitfields -nostdlib)
|
|
|
|
# Default warnings configuration
|
|
add_compile_options(
|
|
-Wall
|
|
-Werror=all
|
|
-Wno-error=unused-function
|
|
-Wno-error=unused-but-set-variable
|
|
-Wno-error=unused-variable
|
|
-Wno-error=deprecated-declarations
|
|
-Wextra
|
|
-Wno-unused-parameter
|
|
-Wno-sign-compare)
|
|
add_c_compile_options(
|
|
-Wno-old-style-declaration
|
|
)
|
|
|
|
if(CONFIG_DISABLE_GCC8_WARNINGS)
|
|
add_compile_options(
|
|
-Wno-parentheses
|
|
-Wno-sizeof-pointer-memaccess
|
|
-Wno-clobbered
|
|
)
|
|
|
|
# doesn't use GCC_NOT_5_2_0 because idf_set_global_variables was not called before
|
|
if(NOT CMAKE_C_COMPILER_VERSION VERSION_EQUAL 5.2.0)
|
|
add_compile_options(
|
|
-Wno-format-overflow
|
|
-Wno-stringop-truncation
|
|
-Wno-misleading-indentation
|
|
-Wno-cast-function-type
|
|
-Wno-implicit-fallthrough
|
|
-Wno-unused-const-variable
|
|
-Wno-switch-unreachable
|
|
-Wno-format-truncation
|
|
-Wno-memset-elt-size
|
|
-Wno-int-in-bool-context
|
|
)
|
|
endif()
|
|
endif()
|
|
|
|
# Stack protection
|
|
if(NOT BOOTLOADER_BUILD)
|
|
if(CONFIG_STACK_CHECK_NORM)
|
|
add_compile_options(-fstack-protector)
|
|
elseif(CONFIG_STACK_CHECK_STRONG)
|
|
add_compile_options(-fstack-protector-strong)
|
|
elseif(CONFIG_STACK_CHECK_ALL)
|
|
add_compile_options(-fstack-protector-all)
|
|
endif()
|
|
endif()
|
|
|
|
if(CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED)
|
|
add_definitions(-DNDEBUG)
|
|
endif()
|
|
|
|
# Always generate debug symbols (even in Release mode, these don't
|
|
# go into the final binary so have no impact on size)
|
|
add_compile_options(-ggdb)
|
|
|
|
# Enable ccache if it's on the path
|
|
if(NOT CCACHE_DISABLE)
|
|
find_program(CCACHE_FOUND ccache)
|
|
if(CCACHE_FOUND)
|
|
message(STATUS "ccache will be used for faster builds")
|
|
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
|
endif()
|
|
endif()
|
|
|
|
# Temporary trick to support both gcc5 and gcc8 builds
|
|
add_definitions(-DGCC_NOT_5_2_0=${GCC_NOT_5_2_0})
|
|
endfunction()
|
|
|
|
|
|
# Verify the IDF environment is configured correctly (environment, toolchain, etc)
|
|
function(idf_verify_environment)
|
|
|
|
if(NOT CMAKE_PROJECT_NAME)
|
|
message(FATAL_ERROR "Internal error, IDF project.cmake should have set this variable already")
|
|
endif()
|
|
|
|
# Check toolchain is configured properly in cmake
|
|
if(NOT ( ${CMAKE_SYSTEM_NAME} STREQUAL "Generic" AND ${CMAKE_C_COMPILER} MATCHES xtensa))
|
|
message(FATAL_ERROR "Internal error, toolchain has not been set correctly by project "
|
|
"(or an invalid CMakeCache.txt file has been generated somehow)")
|
|
endif()
|
|
|
|
#
|
|
# Warn if the toolchain version doesn't match
|
|
#
|
|
# TODO: make these platform-specific for diff toolchains
|
|
get_expected_ctng_version(expected_toolchain expected_gcc)
|
|
gcc_version_check("${expected_gcc}")
|
|
crosstool_version_check("${expected_toolchain}")
|
|
|
|
endfunction()
|
|
|
|
# idf_add_executable
|
|
#
|
|
# Calls add_executable to add the final project executable
|
|
# Adds .map & .bin file targets
|
|
# Sets up flash-related targets
|
|
function(idf_add_executable)
|
|
set(exe_target ${PROJECT_NAME}.elf)
|
|
|
|
if(MAIN_SRCS)
|
|
spaces2list(MAIN_SRCS)
|
|
add_executable(${exe_target} ${MAIN_SRCS})
|
|
else()
|
|
# Create a dummy file to work around CMake requirement of having a source
|
|
# file while adding an executable
|
|
add_executable(${exe_target} "${CMAKE_CURRENT_BINARY_DIR}/dummy_main_src.c")
|
|
add_custom_command(OUTPUT dummy_main_src.c
|
|
COMMAND ${CMAKE_COMMAND} -E touch dummy_main_src.c
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
VERBATIM)
|
|
|
|
add_custom_target(dummy_main_src DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dummy_main_src.c)
|
|
|
|
add_dependencies(${exe_target} dummy_main_src)
|
|
endif()
|
|
|
|
add_map_file(${exe_target})
|
|
endfunction()
|
|
|
|
|
|
# add_map_file
|
|
#
|
|
# Set linker args for 'exe_target' to generate a linker Map file
|
|
function(add_map_file exe_target)
|
|
get_filename_component(basename ${exe_target} NAME_WE)
|
|
set(mapfile "${basename}.map")
|
|
target_link_libraries(${exe_target} "-Wl,--gc-sections -Wl,--cref -Wl,--Map=${mapfile} -Wl,--start-group")
|
|
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
|
|
ADDITIONAL_MAKE_CLEAN_FILES
|
|
"${CMAKE_CURRENT_BINARY_DIR}/${mapfile}")
|
|
|
|
# add size targets, depend on map file, run idf_size.py
|
|
add_custom_target(size
|
|
DEPENDS ${exe_target}
|
|
COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py ${mapfile}
|
|
)
|
|
add_custom_target(size-files
|
|
DEPENDS ${exe_target}
|
|
COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --files ${mapfile}
|
|
)
|
|
add_custom_target(size-components
|
|
DEPENDS ${exe_target}
|
|
COMMAND ${PYTHON} ${IDF_PATH}/tools/idf_size.py --archives ${mapfile}
|
|
)
|
|
|
|
endfunction()
|
|
|
|
# component_compile_options
|
|
#
|
|
# Wrapper around target_compile_options that passes the component name
|
|
function(component_compile_options)
|
|
target_compile_options(${COMPONENT_NAME} PRIVATE ${ARGV})
|
|
endfunction()
|
|
|
|
# component_compile_definitions
|
|
#
|
|
# Wrapper around target_compile_definitions that passes the component name
|
|
function(component_compile_definitions)
|
|
target_compile_definitions(${COMPONENT_NAME} PRIVATE ${ARGV})
|
|
endfunction()
|
|
|
|
# idf_get_git_revision
|
|
#
|
|
# Set global IDF_VER to the git revision of ESP-IDF.
|
|
#
|
|
# Running git_describe() here automatically triggers rebuilds
|
|
# if the ESP-IDF git version changes
|
|
function(idf_get_git_revision)
|
|
if(EXISTS "${IDF_PATH}/version.txt")
|
|
file(STRINGS "${IDF_PATH}/version.txt" IDF_VER)
|
|
else()
|
|
git_describe(IDF_VER "${IDF_PATH}")
|
|
endif()
|
|
add_definitions(-DIDF_VER=\"${IDF_VER}\")
|
|
git_submodule_check("${IDF_PATH}")
|
|
set(IDF_VER ${IDF_VER} PARENT_SCOPE)
|
|
endfunction() |