cmake: Toolchain abstraction: optimizations

Introduce toolchain_cc_optimize_for_* family of macros.
Each macro represents a general optimization class.
Each macro is then responsible for setting an output variable to that
class-of-optimization's flag.
The names of these output variables are decided from the root
CMakeLists.txt.

No functional change expected.

Clang's optimization flags are compatible with gcc, and are thus
inherited.

This is motivated by the wish to abstract Zephyr's usage of toolchains,
permitting easier porting to other (commercial) toolchains.

Signed-off-by: Mark Ruvald Pedersen <mped@oticon.com>
This commit is contained in:
Mark Ruvald Pedersen 2019-01-30 10:12:30 +01:00 committed by Anas Nashif
parent d5b2834f58
commit 0b3c65feea
5 changed files with 49 additions and 14 deletions

View file

@ -99,21 +99,26 @@ if(BUILD_VERSION)
)
endif()
# We need to set an optimization level.
# Default to -Os
# unless CONFIG_NO_OPTIMIZATIONS is set, then it is -O0
# or unless CONFIG_DEBUG is set, then it is -Og
# @Intent: Obtain compiler optimizations flags and store in variables
# @details:
# Kconfig.zephyr "Optimization level" is a kconfig choice, ensuring
# only *one* of CONFIG_{NO,DEBUG,SPEED,SIZE}_OPTIMIZATIONS is set.
# Refer to Kconfig.zephyr for selection logic and description of these choices.
# toolchain_cc_optimize_*() macros must provide the mapping from these kconfigs
# to compiler flags. Each macro will store the flags in a CMake variable, whose
# name is passed as argument (somewhat like by reference).
#
# also, some toolchain's break with -Os, and some toolchain's break
# with -Og so allow them to override what flag to use
# If the user wants to tweak the optimizations, there are two ways:
# 1) Using EXTRA_CFLAGS which is applied regardless of kconfig choice, or
# 2) Rely on override support being implemented by your toolchain_cc_optimize_*()
#
# Finally, the user can use Kconfig to add compiler options that will
# come after these options and override them
set_ifndef(OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG "-O0")
set_ifndef(OPTIMIZE_FOR_DEBUG_FLAG "-Og")
set_ifndef(OPTIMIZE_FOR_SIZE_FLAG "-Os")
set_ifndef(OPTIMIZE_FOR_SPEED_FLAG "-O2")
toolchain_cc_optimize_for_no_optimizations_flag(OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG)
toolchain_cc_optimize_for_debug_flag(OPTIMIZE_FOR_DEBUG_FLAG)
toolchain_cc_optimize_for_speed_flag(OPTIMIZE_FOR_SPEED_FLAG)
toolchain_cc_optimize_for_size_flag(OPTIMIZE_FOR_SIZE_FLAG)
# From kconfig choice, pick the actual OPTIMIZATION_FLAG to use.
# Kconfig choice ensures only one of these CONFIG_*_OPTIMIZATIONS is set.
if(CONFIG_NO_OPTIMIZATIONS)
set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG})
elseif(CONFIG_DEBUG_OPTIMIZATIONS)
@ -121,11 +126,14 @@ elseif(CONFIG_DEBUG_OPTIMIZATIONS)
elseif(CONFIG_SPEED_OPTIMIZATIONS)
set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_SPEED_FLAG})
elseif(CONFIG_SIZE_OPTIMIZATIONS)
set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_SIZE_FLAG}) # Default
set(OPTIMIZATION_FLAG ${OPTIMIZE_FOR_SIZE_FLAG}) # Default in kconfig
else()
assert(0 "Unreachable code. Expected optimization level to have been chosen. See Kconfig.zephyr")
endif()
# Apply the final optimization flag(s)
zephyr_compile_options(${OPTIMIZATION_FLAG})
# Dialects of C++, corresponding to the multiple published ISO standards.
# Which standard it implements can be selected using the -std= command-line option.
set_ifndef(DIALECT_STD_CPP98 "c++98")
@ -149,7 +157,6 @@ else()
endif()
zephyr_compile_options(
${OPTIMIZATION_FLAG} # Usually -Os
-g # TODO: build configuration enough?
-Wall
-Wformat

View file

@ -56,3 +56,4 @@ string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
# Clang and GCC are almost feature+flag compatible, so reuse freestanding gcc
include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_fortify.cmake)
include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake)
include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_optimizations.cmake)

View file

@ -141,3 +141,4 @@ string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
# Load toolchain_cc-family macros
include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_security_fortify.cmake)
include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_security_canaries.cmake)
include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_optimizations.cmake)

View file

@ -0,0 +1,25 @@
# See root CMakeLists.txt for description and expectations of this macro
#
# NOTE: Some GNU toolchains break with plain '-Os' or '-Og', but is fixable
# with tweaks. So allow user to override, via ifndef, the compile flags that
# CONFIG_{NO,DEBUG,SPEED,SIZE}_OPTIMIZATIONS will cause, yet still leaving the
# selection logic in kconfig.
#
# These macros leaves it up to the root CMakeLists.txt to choose the CMake
# variable names to store the optimization flags in.
macro(toolchain_cc_optimize_for_no_optimizations_flag dest_var_name)
set_ifndef(${dest_var_name} "-O0")
endmacro()
macro(toolchain_cc_optimize_for_debug_flag dest_var_name)
set_ifndef(${dest_var_name} "-Og")
endmacro()
macro(toolchain_cc_optimize_for_speed_flag dest_var_name)
set_ifndef(${dest_var_name} "-O2")
endmacro()
macro(toolchain_cc_optimize_for_size_flag dest_var_name)
set_ifndef(${dest_var_name} "-Os")
endmacro()

View file

@ -61,3 +61,4 @@ endif()
# Significant overlap with freestanding gcc compiler so reuse it
include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_fortify.cmake)
include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake)
include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_optimizations.cmake)