esp-idf/tools/cmake/idf_functions.cmake
Angus Gratton 56694fb4b6 cmake: Fix psram workaround compiler flag application
Previously, this compiler flag was not being applied
regardless of CONFIG_SPIRAM_CACHE_WORKAROUND setting.

Explanation: add_compile_options() only applies to
source files added after the function is run, or in
subdirectories added after the function is run. In
this case, no new source files were being added after
this function was run.
2019-02-27 16:38:29 +11:00

262 lines
8.6 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 esp32 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()
# Note: the visual studio generator doesn't support this syntax
add_compile_options("$<$<COMPILE_LANGUAGE:C>:-std=gnu99>")
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-std=gnu++11>")
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>")
if(CONFIG_CXX_EXCEPTIONS)
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-fexceptions>")
else()
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>")
endif()
# Default compiler configuration
add_compile_options(-ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -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_compile_options("$<$<COMPILE_LANGUAGE:C>:-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()