diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cf8b9e5ba..cbd4a132d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/cmake/compiler/clang/target.cmake b/cmake/compiler/clang/target.cmake index f12abf22f4..9ae784e8ee 100644 --- a/cmake/compiler/clang/target.cmake +++ b/cmake/compiler/clang/target.cmake @@ -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) diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake index f23c4f6f00..33ba21c4bc 100644 --- a/cmake/compiler/gcc/target.cmake +++ b/cmake/compiler/gcc/target.cmake @@ -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) diff --git a/cmake/compiler/gcc/target_optimizations.cmake b/cmake/compiler/gcc/target_optimizations.cmake new file mode 100644 index 0000000000..583bb13d17 --- /dev/null +++ b/cmake/compiler/gcc/target_optimizations.cmake @@ -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() diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake index 3a071c50a8..4165b4e1f8 100644 --- a/cmake/compiler/host-gcc/target.cmake +++ b/cmake/compiler/host-gcc/target.cmake @@ -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)