From 63df409906661b1c620ab0ef72c468b9335aa05f Mon Sep 17 00:00:00 2001 From: Mark Ruvald Pedersen Date: Mon, 18 Feb 2019 23:54:30 +0100 Subject: [PATCH] cmake: Toolchain abstraction: C++ Introduce toolchain_cc_cpp_*-family of macros. Move the following into the toolchain_cc_cpp_* macros: * Common base set of flags * C++ standard version * RTTI * Exceptions These macros must be implemented by every compiler port. These macros set the respective flags, but leaves logic and control to the root CMakeLists.txt file. No functional change expected. Clang's C++ 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 --- CMakeLists.txt | 75 ++++++++++++++++------------ cmake/compiler/clang/target.cmake | 1 + cmake/compiler/gcc/target.cmake | 1 + cmake/compiler/gcc/target_cpp.cmake | 34 +++++++++++++ cmake/compiler/host-gcc/target.cmake | 1 + 5 files changed, 80 insertions(+), 32 deletions(-) create mode 100644 cmake/compiler/gcc/target_cpp.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b4c348f317..5813a060a96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,28 +134,59 @@ 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") -set_ifndef(DIALECT_STD_CPP11 "c++11") -set_ifndef(DIALECT_STD_CPP14 "c++14") -set_ifndef(DIALECT_STD_CPP17 "c++17") -set_ifndef(DIALECT_STD_CPP2A "c++2a") +# @Intent: Obtain compiler specific flags related to C++ that are not influenced by kconfig +toolchain_cc_cpp_base_flags(CPP_BASE_FLAGS) +foreach(flag ${CPP_BASE_FLAGS}) + zephyr_compile_options( + $<$:${flag}> + ) +endforeach() +# @Intent: Obtain compiler specific flags for compiling under different ISO standards of C++ +toolchain_cc_cpp_dialect_std_98_flags(CPP_DIALECT_STD_98_FLAGS) +toolchain_cc_cpp_dialect_std_11_flags(CPP_DIALECT_STD_11_FLAGS) +toolchain_cc_cpp_dialect_std_14_flags(CPP_DIALECT_STD_14_FLAGS) +toolchain_cc_cpp_dialect_std_17_flags(CPP_DIALECT_STD_17_FLAGS) +toolchain_cc_cpp_dialect_std_2a_flags(CPP_DIALECT_STD_2A_FLAGS) + +# From kconfig choice, pick a single dialect. +# Kconfig choice ensures only one of these CONFIG_STD_CPP* is set. if(CONFIG_STD_CPP98) - set(STD_CPP_DIALECT ${DIALECT_STD_CPP98}) + set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_98_FLAGS}) elseif(CONFIG_STD_CPP11) - set(STD_CPP_DIALECT ${DIALECT_STD_CPP11}) # Default + set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_11_FLAGS}) # Default in kconfig elseif(CONFIG_STD_CPP14) - set(STD_CPP_DIALECT ${DIALECT_STD_CPP14}) + set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_14_FLAGS}) elseif(CONFIG_STD_CPP17) - set(STD_CPP_DIALECT ${DIALECT_STD_CPP17}) + set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_17_FLAGS}) elseif(CONFIG_STD_CPP2A) - set(STD_CPP_DIALECT ${DIALECT_STD_CPP2A}) + set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_2A_FLAGS}) else() assert(0 "Unreachable code. Expected C++ standard to have been chosen. See Kconfig.zephyr.") endif() +foreach(flag ${STD_CPP_DIALECT_FLAGS}) + zephyr_compile_options( + $<$:${flag}> + ) +endforeach() + +if(NOT CONFIG_EXCEPTIONS) + # @Intent: Obtain compiler specific flags related to C++ Exceptions + toolchain_cc_cpp_no_exceptions_flag(CPP_NO_EXCEPTIONS_FLAG) + zephyr_compile_options( + $<$:${CPP_NO_EXCEPTIONS_FLAG}> + ) +endif() + +if(NOT CONFIG_RTTI) + # @Intent: Obtain compiler specific flags related to C++ Run Time Type Information + toolchain_cc_cpp_no_rtti_flag(CPP_NO_RTTI_FLAG) + zephyr_compile_options( + $<$:${CPP_NO_RTTI_FLAG}> + ) +endif() + zephyr_compile_options( -g # TODO: build configuration enough? -Wall @@ -171,25 +202,10 @@ zephyr_compile_options( ) zephyr_compile_options( - $<$:-std=${STD_CPP_DIALECT}> - $<$:-fcheck-new> - $<$:-xassembler-with-cpp> $<$:-D_ASMLANGUAGE> ) -if(NOT CONFIG_RTTI) -zephyr_compile_options( - $<$:-fno-rtti> -) -endif() - -if(NOT CONFIG_EXCEPTIONS) -zephyr_compile_options( - $<$:-fno-exceptions> -) -endif() - zephyr_ld_options( ${TOOLCHAIN_LD_FLAGS} ) @@ -264,11 +280,6 @@ if(W MATCHES "3") ) endif() -if(NOT CONFIG_STD_CPP98) # "register" keyword was deprecated since C++11. - zephyr_compile_options( - $<$:-Wno-register> - ) -endif() # Allow the user to inject options when calling cmake, e.g. # 'cmake -DEXTRA_CFLAGS="-Werror -Wno-deprecated-declarations" ..' diff --git a/cmake/compiler/clang/target.cmake b/cmake/compiler/clang/target.cmake index 9ae784e8eec..fd02fb4539c 100644 --- a/cmake/compiler/clang/target.cmake +++ b/cmake/compiler/clang/target.cmake @@ -57,3 +57,4 @@ string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") 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) +include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_cpp.cmake) diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake index 33ba21c4bcd..037e66a7c55 100644 --- a/cmake/compiler/gcc/target.cmake +++ b/cmake/compiler/gcc/target.cmake @@ -142,3 +142,4 @@ string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") 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) +include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_cpp.cmake) diff --git a/cmake/compiler/gcc/target_cpp.cmake b/cmake/compiler/gcc/target_cpp.cmake new file mode 100644 index 00000000000..0f73a7bd74e --- /dev/null +++ b/cmake/compiler/gcc/target_cpp.cmake @@ -0,0 +1,34 @@ +# See root CMakeLists.txt for description and expectations of these macros + +macro(toolchain_cc_cpp_base_flags dest_list_name) + list(APPEND ${dest_list_name} "-fcheck-new") +endmacro() + +# The "register" keyword was deprecated since C++11, but not for C++98 +macro(toolchain_cc_cpp_dialect_std_98_flags dest_list_name) + list(APPEND ${dest_list_name} "-std=c++98") +endmacro() +macro(toolchain_cc_cpp_dialect_std_11_flags dest_list_name) + list(APPEND ${dest_list_name} "-std=c++11") + list(APPEND ${dest_list_name} "-Wno-register") +endmacro() +macro(toolchain_cc_cpp_dialect_std_14_flags dest_list_name) + list(APPEND ${dest_list_name} "-std=c++14") + list(APPEND ${dest_list_name} "-Wno-register") +endmacro() +macro(toolchain_cc_cpp_dialect_std_17_flags dest_list_name) + list(APPEND ${dest_list_name} "-std=c++17") + list(APPEND ${dest_list_name} "-Wno-register") +endmacro() +macro(toolchain_cc_cpp_dialect_std_2a_flags dest_list_name) + list(APPEND ${dest_list_name} "-std=c++2a") + list(APPEND ${dest_list_name} "-Wno-register") +endmacro() + +macro(toolchain_cc_cpp_no_exceptions_flag dest_var_name) + set_ifndef(${dest_var_name} "-fno-exceptions") +endmacro() + +macro(toolchain_cc_cpp_no_rtti_flag dest_var_name) + set_ifndef(${dest_var_name} "-fno-rtti") +endmacro() diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake index 4165b4e1f85..dadf0b1e6b0 100644 --- a/cmake/compiler/host-gcc/target.cmake +++ b/cmake/compiler/host-gcc/target.cmake @@ -62,3 +62,4 @@ endif() 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) +include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_cpp.cmake)