toolchain: improved toolchain abstraction for compilers and linker

First abstraction completed for the toolchains:
- gcc
- clang

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index efcd207..02f3784 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -97,11 +97,11 @@
 
 # @Intent: Set compiler flags to enable buffer overflow checks in libc functions
 # @config in CONFIG_NO_OPTIMIZATIONS optional : Optimizations may affect security
-toolchain_cc_security_fortify()
+zephyr_compile_definitions($<TARGET_PROPERTY:compiler,security_fortify> )
 
 # @Intent: Set compiler flags to detect general stack overflows across all functions
 if(CONFIG_STACK_CANARIES)
-  toolchain_cc_security_canaries()
+  zephyr_compile_options($<TARGET_PROPERTY:compiler,security_canaries>)
 endif()
 
 if(BUILD_VERSION)
@@ -123,10 +123,10 @@
 #    1) Using EXTRA_CFLAGS which is applied regardless of kconfig choice, or
 #    2) Rely on override support being implemented by your toolchain_cc_optimize_*()
 #
-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)
+get_property(OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG TARGET compiler PROPERTY no_optimization)
+get_property(OPTIMIZE_FOR_DEBUG_FLAG TARGET compiler PROPERTY optimization_debug)
+get_property(OPTIMIZE_FOR_SPEED_FLAG TARGET compiler PROPERTY optimization_speed)
+get_property(OPTIMIZE_FOR_SIZE_FLAG  TARGET compiler PROPERTY optimization_size)
 
 # From kconfig choice, pick the actual OPTIMIZATION_FLAG to use.
 # Kconfig choice ensures only one of these CONFIG_*_OPTIMIZATIONS is set.
@@ -153,101 +153,75 @@
 zephyr_compile_options(${OPTIMIZATION_FLAG})
 
 # @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(
-    $<$<COMPILE_LANGUAGE:CXX>:${flag}>
-  )
-endforeach()
+zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,required>>)
 
 # @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)
-
 if(CONFIG_CPLUSPLUS)
   # 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_FLAGS ${CPP_DIALECT_STD_98_FLAGS})
+    set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp98>)
   elseif(CONFIG_STD_CPP11)
-    set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_11_FLAGS}) # Default in kconfig
+    set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp11>) # Default in kconfig
   elseif(CONFIG_STD_CPP14)
-    set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_14_FLAGS})
+    set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp14>)
   elseif(CONFIG_STD_CPP17)
-    set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_17_FLAGS})
+    set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp17>)
   elseif(CONFIG_STD_CPP2A)
-    set(STD_CPP_DIALECT_FLAGS ${CPP_DIALECT_STD_2A_FLAGS})
+    set(STD_CPP_DIALECT_FLAGS $<TARGET_PROPERTY:compiler-cpp,dialect_cpp2a>)
   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(
-      $<$<COMPILE_LANGUAGE:CXX>:${flag}>
-    )
-  endforeach()
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:${STD_CPP_DIALECT_FLAGS}>)
 endif()
 
 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(
-    $<$<COMPILE_LANGUAGE:CXX>:${CPP_NO_EXCEPTIONS_FLAG}>
-  )
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,no_exceptions>>)
 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(
-    $<$<COMPILE_LANGUAGE:CXX>:${CPP_NO_RTTI_FLAG}>
-  )
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,no_rtti>>)
 endif()
 
 if(CONFIG_MISRA_SANE)
   # @Intent: Obtain toolchain compiler flags relating to MISRA.
-  toolchain_cc_warning_error_misra_sane(CC_MISRA_SANE_FLAG)
-  toolchain_cc_cpp_warning_error_misra_sane(CPP_MISRA_SANE_FLAG)
-  zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:${CC_MISRA_SANE_FLAG}>)
-  zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:${CPP_MISRA_SANE_FLAG}>)
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_misra_sane>>)
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_error_misra_sane>>)
 endif()
 
 # This is intend to be temporary. Once we have fixed the violations that
 # prevents build Zephyr, these flags shall be part of the default flags.
 if(CONFIG_CODING_GUIDELINE_CHECK)
   # @Intent: Obtain toolchain compiler flags relating to coding guideline
-  toolchain_cc_warning_error_coding_guideline_check(CC_CODING_GUIDELINE_CHECK_FLAG)
-  zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:${CC_CODING_GUIDELINE_CHECK_FLAG}>)
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_coding_guideline>>)
 endif()
 
 # @Intent: Set compiler specific macro inclusion of AUTOCONF_H
-toolchain_cc_imacros(${AUTOCONF_H})
+zephyr_compile_options($<TARGET_PROPERTY:compiler,imacros>${AUTOCONF_H})
 
 # @Intent: Set compiler specific flag for bare metal freestanding option
-toolchain_cc_freestanding()
+zephyr_compile_options($<TARGET_PROPERTY:compiler,freestanding>)
 
 # @Intent: Set compiler specific flag for tentative definitions, no-common
-toolchain_cc_nocommon()
+zephyr_compile_options($<TARGET_PROPERTY:compiler,no_common>)
 
 # @Intent: Set compiler specific flag for production of debug information
-toolchain_cc_produce_debug_info()
+zephyr_compile_options($<TARGET_PROPERTY:compiler,debug>)
 
 zephyr_compile_options(
   ${TOOLCHAIN_C_FLAGS}
 )
 
 # @Intent: Obtain compiler specific flags related to assembly
-toolchain_cc_asm_base_flags(ASM_BASE_FLAG)
-zephyr_compile_options(
-  $<$<COMPILE_LANGUAGE:ASM>:${ASM_BASE_FLAG}>
-)
+# ToDo: Remember to get feedback from Oticon on this, as they might use the `ASM_BASE_FLAG` since this is done this way.
+zephyr_compile_options($<$<COMPILE_LANGUAGE:ASM>:$<TARGET_PROPERTY:asm,required>>)
 
 # @Intent: Enforce standard integer type correspondance to match Zephyr usage.
 # (must be after compiler specific flags)
-toolchain_cc_imacros(${ZEPHYR_BASE}/include/toolchain/zephyr_stdint.h)
+zephyr_compile_options($<TARGET_PROPERTY:compiler,imacros>${ZEPHYR_BASE}/include/toolchain/zephyr_stdint.h)
 
 # Common toolchain-agnostic assembly flags
 zephyr_compile_options(
@@ -273,7 +247,8 @@
 endif()
 
 # @Intent: Add the basic toolchain warning flags
-toolchain_cc_warning_base()
+zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_base>>)
+zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_base>>)
 
 # ==========================================================================
 #
@@ -285,22 +260,26 @@
 # ==========================================================================
 # @Intent: Add cmake -DW toolchain supported warnings, if any
 if(W MATCHES "1")
-  toolchain_cc_warning_dw_1()
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_1>>)
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_1>>)
 endif()
 
 if(W MATCHES "2")
-  toolchain_cc_warning_dw_2()
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_2>>)
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_2>>)
 endif()
 
 if(W MATCHES "3")
-  toolchain_cc_warning_dw_3()
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_dw_3>>)
+  zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_dw_3>>)
 endif()
 
 # @Intent: Add extended, more specific, toolchain warning flags
-toolchain_cc_warning_extended()
+zephyr_compile_options($<TARGET_PROPERTY:compiler,warning_extended>)
 
 # @Intent: Trigger an error when a declaration does not specify a type
-toolchain_cc_warning_error_implicit_int()
+zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,warning_error_implicit_int>>)
+zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:$<TARGET_PROPERTY:compiler-cpp,warning_error_implicit_int>>)
 
 # Allow the user to inject options when calling cmake, e.g.
 # 'cmake -DEXTRA_CFLAGS="-Werror -Wno-deprecated-declarations" ..'
@@ -921,9 +900,8 @@
 set_ifndef(CSTD c99)
 
 # @Intent: Obtain compiler specific flag for specifying the c standard
-toolchain_cc_cstd_flag(CC_CSTD ${CSTD})
 zephyr_compile_options(
-  $<$<COMPILE_LANGUAGE:C>:${CC_CSTD}>
+  $<$<COMPILE_LANGUAGE:C>:$<TARGET_PROPERTY:compiler,cstd>${CSTD}>
 )
 
 # @Intent: Configure linker scripts, i.e. generate linker scripts with variables substituted
@@ -1102,131 +1080,120 @@
 
 if(NOT CONFIG_BUILD_NO_GAP_FILL)
   # Use ';' as separator to get proper space in resulting command.
-  set(GAP_FILL "0xff")
+  set(GAP_FILL "$<TARGET_PROPERTY:bintools,elfconvert_flag_gapfill>0xff")
 endif()
 
 if(CONFIG_OUTPUT_PRINT_MEMORY_USAGE)
-  # @Intent: Use the toolchain bintools method for printing memory usage
-  set(memUsageCmd    "")
-  set(memUsageByProd "")
-  bintools_print_mem_usage(
-    RESULT_CMD_LIST    memUsageCmd
-    RESULT_BYPROD_LIST memUsageByProd
-  )
-  list(APPEND
-    post_build_commands
-    ${memUsageCmd}
-    )
-  list(APPEND
-    post_build_byproducts
-    ${memUsageByProd}
-    )
+  target_link_libraries(${ZEPHYR_PREBUILT_EXECUTABLE} $<TARGET_PROPERTY:linker,memusage>)
+
+  get_property(memusage_build_command TARGET bintools PROPERTY memusage_command)
+  if(memusage_build_command)
+    # Note: The use of generator expressions allows downstream extensions to add/change the post build.
+    # Unfortunately, the BYPRODUCTS does not allow for generator expression, so question is if we
+    # should remove the downstream ability from start.
+    # Or fix the output name, by the use of `get_property`
+    list(APPEND
+      post_build_commands
+      COMMAND ${memusage_build_command}
+      )
+
+    # For now, the byproduct can only be supported upstream on byproducts name,
+    # cause byproduct does not support generator expressions
+    get_property(memusage_byproducts TARGET bintools PROPERTY memusage_byproducts)
+    list(APPEND
+      post_build_byproducts
+      ${memusage_byproducts}
+      )
+  endif()
 endif()
 
 if(CONFIG_BUILD_OUTPUT_HEX OR BOARD_FLASH_RUNNER STREQUAL openocd)
-  set(out_hex_cmd    "")
-  set(out_hex_byprod "")
-  set(out_hex_sections_remove
-    .comment
-    COMMON
-    .eh_frame
-    )
-  bintools_objcopy(
-    RESULT_CMD_LIST    out_hex_cmd
-    RESULT_BYPROD_LIST out_hex_byprod
-    STRIP_ALL
-    GAP_FILL           ${GAP_FILL}
-    TARGET_OUTPUT      "ihex"
-    SECTION_REMOVE     ${out_hex_sections_remove}
-    FILE_INPUT         ${KERNEL_ELF_NAME}
-    FILE_OUTPUT        ${KERNEL_HEX_NAME}
-    )
-  list(APPEND
-    post_build_commands
-    ${out_hex_cmd}
-    )
-  list(APPEND
-    post_build_byproducts
-    ${KERNEL_HEX_NAME}
-    ${out_hex_byprod}
-    )
+  get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats)
+  if(ihex IN_LIST elfconvert_formats)
+    list(APPEND
+      post_build_commands
+      COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command>
+              $<TARGET_PROPERTY:bintools,elfconvert_flag>
+              ${GAP_FILL}
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>ihex
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_section_remove>.comment
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_section_remove>COMMON
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_section_remove>.eh_frame
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME}
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_HEX_NAME}
+      )
+    list(APPEND
+      post_build_byproducts
+      ${KERNEL_HEX_NAME}
+      # ${out_hex_byprod} # Is this needed ?
+      )
+  endif()
 endif()
 
 if(CONFIG_BUILD_OUTPUT_BIN)
-  set(out_bin_cmd    "")
-  set(out_bin_byprod "")
-  set(out_bin_sections_remove
-    .comment
-    COMMON
-    .eh_frame
-    )
-  bintools_objcopy(
-    RESULT_CMD_LIST    out_bin_cmd
-    RESULT_BYPROD_LIST out_bin_byprod
-    STRIP_ALL
-    GAP_FILL           ${GAP_FILL}
-    TARGET_OUTPUT      "binary"
-    SECTION_REMOVE     ${out_bin_sections_remove}
-    FILE_INPUT         ${KERNEL_ELF_NAME}
-    FILE_OUTPUT        ${KERNEL_BIN_NAME}
-    )
-  list(APPEND
-    post_build_commands
-    ${out_bin_cmd}
-    )
-  list(APPEND
-    post_build_byproducts
-    ${KERNEL_BIN_NAME}
-    ${out_bin_byprod}
-    )
+  get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats)
+  if(binary IN_LIST elfconvert_formats)
+    list(APPEND
+      post_build_commands
+      COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command>
+              $<TARGET_PROPERTY:bintools,elfconvert_flag>
+              ${GAP_FILL}
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>binary
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_section_remove>.comment
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_section_remove>COMMON
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_section_remove>.eh_frame
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME}
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_BIN_NAME}
+      )
+    list(APPEND
+      post_build_byproducts
+      ${KERNEL_BIN_NAME}
+      # ${out_hex_byprod} # Is this needed ?
+      )
+  endif()
 endif()
 
 if(CONFIG_BUILD_OUTPUT_S19)
-  set(out_S19_cmd    "")
-  set(out_S19_byprod "")
-  bintools_objcopy(
-    RESULT_CMD_LIST    out_S19_cmd
-    RESULT_BYPROD_LIST out_S19_byprod
-    GAP_FILL           ${GAP_FILL}
-    TARGET_OUTPUT      "srec"
-    SREC_LEN           1
-    FILE_INPUT         ${KERNEL_ELF_NAME}
-    FILE_OUTPUT        ${KERNEL_S19_NAME}
-    )
-  list(APPEND
-    post_build_commands
-    ${out_S19_cmd}
-    )
-  list(APPEND
-    post_build_byproducts
-    ${KERNEL_S19_NAME}
-    ${out_S19_byprod}
-    )
+  get_property(elfconvert_formats TARGET bintools PROPERTY elfconvert_formats)
+  if(srec IN_LIST elfconvert_formats)
+    # Should we print a warning if case the tools does not support converting to s19 ?
+    list(APPEND
+      post_build_commands
+      COMMAND $<TARGET_PROPERTY:bintools,elfconvert_command>
+              $<TARGET_PROPERTY:bintools,elfconvert_flag>
+              ${GAP_FILL}
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_outtarget>srec
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_srec_len>1
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_infile>${KERNEL_ELF_NAME}
+              $<TARGET_PROPERTY:bintools,elfconvert_flag_outfile>${KERNEL_S19_NAME}
+      )
+    list(APPEND
+      post_build_byproducts
+      ${KERNEL_S19_NAME}
+      # ${out_S19_byprod} # Is this needed ?
+
+      )
+  endif()
 endif()
 
 if(CONFIG_OUTPUT_DISASSEMBLY)
-  set(out_disassembly_cmd    "")
-  set(out_disassembly_byprod "")
-  if(CONFIG_OUTPUT_DISASSEMBLE_ALL)
-    set(disassembly_type DISASSEMBLE_ALL)
+if(CONFIG_OUTPUT_DISASSEMBLE_ALL)
+    set(disassembly_type "$<TARGET_PROPERTY:bintools,disassembly_flag_all>")
   else()
-    set(disassembly_type DISASSEMBLE_SOURCE)
+    set(disassembly_type "$<TARGET_PROPERTY:bintools,disassembly_flag_inline_source>")
   endif()
-  bintools_objdump(
-    RESULT_CMD_LIST    out_disassembly_cmd
-    RESULT_BYPROD_LIST out_disassembly_byprod
-    ${disassembly_type}
-    FILE_INPUT         ${KERNEL_ELF_NAME}
-    FILE_OUTPUT        ${KERNEL_LST_NAME}
-    )
   list(APPEND
     post_build_commands
-    ${out_disassembly_cmd}
+    COMMAND $<TARGET_PROPERTY:bintools,disassembly_command>
+            $<TARGET_PROPERTY:bintools,disassembly_flag>
+            ${disassembly_type}
+            $<TARGET_PROPERTY:bintools,disassembly_flag_infile> ${KERNEL_ELF_NAME}
+            $<TARGET_PROPERTY:bintools,disassembly_flag_outfile> ${KERNEL_LST_NAME}
     )
   list(APPEND
     post_build_byproducts
     ${KERNEL_LST_NAME}
-    ${out_disassembly_byprod}
+#    ${out_disassembly_byprod} # Needed ??
     )
 endif()
 
@@ -1319,6 +1286,7 @@
   BYPRODUCTS
   ${post_build_byproducts}
   COMMENT "Generating files from ${KERNEL_ELF_NAME} for board: ${BOARD}"
+  COMMAND_EXPAND_LISTS
   # NB: COMMENT only works for some CMake-Generators
   )
 
@@ -1407,4 +1375,6 @@
 # @Intent: Set compiler specific flags for standard C includes
 # Done at the very end, so any other system includes which may
 # be added by Zephyr components were first in list.
-toolchain_cc_nostdinc()
+# Note, the compile flags are moved, but the system include is still present here.
+zephyr_compile_options($<TARGET_PROPERTY:compiler,nostdinc>)
+target_include_directories(zephyr_interface SYSTEM INTERFACE $<TARGET_PROPERTY:compiler,nostdinc_include>)
diff --git a/arch/arm/core/aarch32/CMakeLists.txt b/arch/arm/core/aarch32/CMakeLists.txt
index ef90462..4d28989 100644
--- a/arch/arm/core/aarch32/CMakeLists.txt
+++ b/arch/arm/core/aarch32/CMakeLists.txt
@@ -3,7 +3,8 @@
 zephyr_library()
 
 if (CONFIG_COVERAGE)
-  toolchain_cc_coverage()
+  zephyr_compile_options($<TARGET_PROPERTY:compiler,coverage>)
+  zephyr_link_libraries($<TARGET_PROPERTY:linker,coverage>)
 endif ()
 
 zephyr_library_sources(
diff --git a/arch/arm/core/aarch64/CMakeLists.txt b/arch/arm/core/aarch64/CMakeLists.txt
index f29703e..c21d6d8 100644
--- a/arch/arm/core/aarch64/CMakeLists.txt
+++ b/arch/arm/core/aarch64/CMakeLists.txt
@@ -3,7 +3,8 @@
 zephyr_library()
 
 if (CONFIG_COVERAGE)
-  toolchain_cc_coverage()
+  zephyr_compile_options($<TARGET_PROPERTY:compiler,coverage>)
+  zephyr_link_libraries($<TARGET_PROPERTY:linker,coverage>)
 endif ()
 
 zephyr_library_sources(
diff --git a/arch/posix/CMakeLists.txt b/arch/posix/CMakeLists.txt
index b8d2e1e..664c7a3 100644
--- a/arch/posix/CMakeLists.txt
+++ b/arch/posix/CMakeLists.txt
@@ -20,20 +20,23 @@
   )
 
 # @Intent: Obtain compiler specific flags for no freestanding compilation
-toolchain_cc_no_freestanding_options()
+zephyr_compile_options($<TARGET_PROPERTY:compiler,hosted>)
 
 zephyr_include_directories(${BOARD_DIR})
 
 if (CONFIG_COVERAGE)
-  toolchain_cc_coverage()
+  zephyr_compile_options($<TARGET_PROPERTY:compiler,coverage>)
+  zephyr_link_libraries($<TARGET_PROPERTY:linker,coverage>)
 endif ()
 
 if (CONFIG_ASAN)
-  toolchain_cc_asan()
+  zephyr_compile_options($<TARGET_PROPERTY:compiler,sanitize_address>)
+  zephyr_link_libraries($<TARGET_PROPERTY:linker,sanitize_address>)
 endif ()
 
 if (CONFIG_UBSAN)
-  toolchain_cc_ubsan()
+  zephyr_compile_options($<TARGET_PROPERTY:compiler,sanitize_undefined>)
+  zephyr_link_libraries($<TARGET_PROPERTY:linker,sanitize_undefined>)
 endif ()
 
 zephyr_compile_definitions(_POSIX_C_SOURCE=200809 _XOPEN_SOURCE=600 _XOPEN_SOURCE_EXTENDED)
diff --git a/arch/x86/core/CMakeLists.txt b/arch/x86/core/CMakeLists.txt
index 87411a1..5fdfe49 100644
--- a/arch/x86/core/CMakeLists.txt
+++ b/arch/x86/core/CMakeLists.txt
@@ -4,7 +4,8 @@
 zephyr_library()
 
 if (CONFIG_COVERAGE)
-  toolchain_cc_coverage()
+  zephyr_compile_options($<TARGET_PROPERTY:compiler,coverage>)
+  zephyr_link_libraries($<TARGET_PROPERTY:linker,coverage>)
 endif ()
 
 zephyr_library_sources(cpuhalt.c)
diff --git a/cmake/app/boilerplate.cmake b/cmake/app/boilerplate.cmake
index 9c3e2bc..6399ea5 100644
--- a/cmake/app/boilerplate.cmake
+++ b/cmake/app/boilerplate.cmake
@@ -550,6 +550,13 @@
 settings in the board's .dts file. Multiple files may be listed, e.g. \
 DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"")
 
+# Populate USER_CACHE_DIR with a directory that user applications may
+# write cache files to.
+if(NOT DEFINED USER_CACHE_DIR)
+  find_appropriate_cache_directory(USER_CACHE_DIR)
+endif()
+message(STATUS "Cache files will be written to: ${USER_CACHE_DIR}")
+
 # Prevent CMake from testing the toolchain
 set(CMAKE_C_COMPILER_FORCED   1)
 set(CMAKE_CXX_COMPILER_FORCED 1)
@@ -605,6 +612,12 @@
 
 project(Zephyr-Kernel VERSION ${PROJECT_VERSION})
 enable_language(C CXX ASM)
+# The setup / configuration of the toolchain itself and the configuration of
+# supported compilation flags are now split, as this allows to use the toolchain
+# for generic purposes, for example DTS, and then test the toolchain for
+# supported flags at stage two.
+# Testing the toolchain flags requires the enable_language() to have been called in CMake.
+include(${ZEPHYR_BASE}/cmake/target_toolchain_flags.cmake)
 
 # 'project' sets PROJECT_BINARY_DIR to ${CMAKE_CURRENT_BINARY_DIR},
 # but for legacy reasons we need it to be set to
@@ -624,13 +637,6 @@
 set(KERNEL_STAT_NAME  ${KERNEL_NAME}.stat)
 set(KERNEL_STRIP_NAME ${KERNEL_NAME}.strip)
 
-# Populate USER_CACHE_DIR with a directory that user applications may
-# write cache files to.
-if(NOT DEFINED USER_CACHE_DIR)
-  find_appropriate_cache_directory(USER_CACHE_DIR)
-endif()
-message(STATUS "Cache files will be written to: ${USER_CACHE_DIR}")
-
 include(${BOARD_DIR}/board.cmake OPTIONAL)
 
 # If we are using a suitable ethernet driver inside qemu, then these options
diff --git a/cmake/compiler/clang/compiler_flags.cmake b/cmake/compiler/clang/compiler_flags.cmake
new file mode 100644
index 0000000..5e7610c
--- /dev/null
+++ b/cmake/compiler/clang/compiler_flags.cmake
@@ -0,0 +1,103 @@
+# First step is to inherit all properties from gcc, as clang is compatible with most flags.
+include(${ZEPHYR_BASE}/cmake/compiler/gcc/compiler_flags.cmake)
+
+# Now, let's overwrite the flags that are different in clang.
+
+# No property flag, clang doesn't understand fortify at all
+set_compiler_property(PROPERTY security_fortify)
+
+# No property flag, this is used by the native_posix, clang has problems
+# compiling the native_posix with -fno-freestanding.
+check_set_compiler_property(PROPERTY hosted)
+
+# clang flags for coverage generation
+set_property(TARGET compiler PROPERTY coverage --coverage -fno-inline)
+
+#######################################################
+# This section covers flags related to warning levels #
+#######################################################
+
+# clang option standard warning base in Zephyr
+set_compiler_property(PROPERTY warning_base
+                      -Wall
+                      -Wformat
+                      -Wformat-security
+                      -Wno-format-zero-length
+                      -Wno-main
+)
+
+check_set_compiler_property(APPEND PROPERTY warning_base -Wno-pointer-sign)
+
+# Prohibit void pointer arithmetic. Illegal in C99
+check_set_compiler_property(APPEND PROPERTY warning_base -Wpointer-arith)
+
+# clang options for warning levels 1, 2, 3, when using `-DW=[1|2|3]`
+set_compiler_property(PROPERTY warning_dw_1
+                      -Wextra
+                      -Wunused
+                      -Wno-unused-parameter
+                      -Wmissing-declarations
+                      -Wmissing-format-attribute
+)
+check_set_compiler_property(APPEND PROPERTY warning_dw_1
+                            -Wold-style-definition
+                            -Wmissing-prototypes
+                            -Wmissing-include-dirs
+                            -Wunused-but-set-variable
+                            -Wno-missing-field-initializers
+)
+
+set_compiler_property(PROPERTY warning_dw_2
+                      -Waggregate-return
+                      -Wcast-align
+                      -Wdisabled-optimization
+                      -Wnested-externs
+                      -Wshadow
+)
+
+check_set_compiler_property(APPEND PROPERTY warning_dw_2
+                            -Wlogical-op
+                            -Wmissing-field-initializers
+)
+
+set_compiler_property(PROPERTY warning_dw_3
+                      -Wbad-function-cast
+                      -Wcast-qual
+                      -Wconversion
+                      -Wpacked
+                      -Wpadded
+                      -Wpointer-arith
+                      -Wredundant-decls
+                      -Wswitch-default
+)
+
+check_set_compiler_property(APPEND PROPERTY warning_dw_3
+                            -Wpacked-bitfield-compat
+                            -Wvla
+)
+
+
+check_set_compiler_property(PROPERTY warning_extended
+                            #FIXME: need to fix all of those
+                            -Wno-sometimes-uninitialized
+                            -Wno-shift-overflow
+                            -Wno-missing-braces
+                            -Wno-self-assign
+                            -Wno-address-of-packed-member
+                            -Wno-unused-function
+                            -Wno-initializer-overrides
+                            -Wno-section
+                            -Wno-unknown-warning-option
+                            -Wno-unused-variable
+                            -Wno-format-invalid-specifier
+                            -Wno-gnu
+                            # comparison of unsigned expression < 0 is always false
+                            -Wno-tautological-compare
+)
+
+set_compiler_property(PROPERTY warning_error_coding_guideline
+                      -Werror=vla
+                      -Wimplicit-fallthrough
+                      -Wconversion
+                      -Woverride-init
+)
diff --git a/cmake/compiler/clang/target.cmake b/cmake/compiler/clang/target.cmake
index 45b9d8b..1967308 100644
--- a/cmake/compiler/clang/target.cmake
+++ b/cmake/compiler/clang/target.cmake
@@ -75,24 +75,3 @@
     zephyr_compile_options( -nostdinc)
   endif()
 endmacro()
-
-# Clang and GCC are almost feature+flag compatible, so reuse freestanding gcc
-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)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_asm.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_baremetal.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_warnings.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_imacros.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_base.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_coverage.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_sanitizers.cmake)
-
-macro(toolchain_cc_security_fortify)
-  # No op, clang doesn't understand fortify at all
-endmacro()
-
-macro(toolchain_cc_no_freestanding_options)
-  # No op, this is used by the native_posix, clang has problems
-  # compiling the native_posix with -fno-freestanding.
-endmacro()
diff --git a/cmake/compiler/clang/target_coverage.cmake b/cmake/compiler/clang/target_coverage.cmake
deleted file mode 100644
index 7cbfa17..0000000
--- a/cmake/compiler/clang/target_coverage.cmake
+++ /dev/null
@@ -1,18 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-macro(toolchain_cc_coverage)
-
-zephyr_compile_options(
-  --coverage
-  -fno-inline
-)
-
-if (NOT CONFIG_COVERAGE_GCOV)
-
-  zephyr_link_libraries(
-    --coverage
-  )
-
-endif()
-
-endmacro()
diff --git a/cmake/compiler/clang/target_sanitizers.cmake b/cmake/compiler/clang/target_sanitizers.cmake
deleted file mode 100644
index 091b6d2..0000000
--- a/cmake/compiler/clang/target_sanitizers.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-macro(toolchain_cc_asan)
-
-zephyr_compile_options(-fsanitize=address)
-zephyr_ld_options(-fsanitize=address)
-
-endmacro()
-
-macro(toolchain_cc_ubsan)
-
-zephyr_compile_options(-fsanitize=undefined)
-zephyr_ld_options(-fsanitize=undefined)
-
-endmacro()
diff --git a/cmake/compiler/clang/target_warnings.cmake b/cmake/compiler/clang/target_warnings.cmake
deleted file mode 100644
index ce80662..0000000
--- a/cmake/compiler/clang/target_warnings.cmake
+++ /dev/null
@@ -1,135 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# See root CMakeLists.txt for description and expectations of this macro
-
-macro(toolchain_cc_warning_base)
-
-  zephyr_compile_options(
-    -Wall
-    -Wformat
-    -Wformat-security
-    -Wno-format-zero-length
-    -Wno-main
-  )
-
-  zephyr_cc_option(-Wno-pointer-sign)
-
-  # Prohibit void pointer arithmetic. Illegal in C99
-  zephyr_cc_option(-Wpointer-arith)
-
-endmacro()
-
-macro(toolchain_cc_warning_dw_1)
-
-  zephyr_compile_options(
-    -Wextra
-    -Wunused
-    -Wno-unused-parameter
-    -Wmissing-declarations
-    -Wmissing-format-attribute
-    )
-  zephyr_cc_option(
-    -Wold-style-definition
-    -Wmissing-prototypes
-    -Wmissing-include-dirs
-    -Wunused-but-set-variable
-    -Wno-missing-field-initializers
-    )
-
-endmacro()
-
-macro(toolchain_cc_warning_dw_2)
-
-  zephyr_compile_options(
-    -Waggregate-return
-    -Wcast-align
-    -Wdisabled-optimization
-    -Wnested-externs
-    -Wshadow
-    )
-  zephyr_cc_option(
-    -Wlogical-op
-    -Wmissing-field-initializers
-    )
-
-endmacro()
-
-macro(toolchain_cc_warning_dw_3)
-
-  zephyr_compile_options(
-    -Wbad-function-cast
-    -Wcast-qual
-    -Wconversion
-    -Wpacked
-    -Wpadded
-    -Wpointer-arith
-    -Wredundant-decls
-    -Wswitch-default
-    )
-  zephyr_cc_option(
-    -Wpacked-bitfield-compat
-    -Wvla
-    )
-
-endmacro()
-
-macro(toolchain_cc_warning_extended)
-
-  zephyr_cc_option(
-    #FIXME: need to fix all of those
-    -Wno-sometimes-uninitialized
-    -Wno-shift-overflow
-    -Wno-missing-braces
-    -Wno-self-assign
-    -Wno-address-of-packed-member
-    -Wno-unused-function
-    -Wno-initializer-overrides
-    -Wno-section
-    -Wno-unknown-warning-option
-    -Wno-unused-variable
-    -Wno-format-invalid-specifier
-    -Wno-gnu
-    # comparison of unsigned expression < 0 is always false
-    -Wno-tautological-compare
-    )
-
-endmacro()
-
-macro(toolchain_cc_warning_error_implicit_int)
-
-  # Force an error when things like SYS_INIT(foo, ...) occur with a missing header
-  zephyr_cc_option(-Werror=implicit-int)
-
-endmacro()
-
-#
-# The following macros leaves it up to the root CMakeLists.txt to choose
-#  the variables in which to put the requested flags, and whether or not
-#  to call the macros
-#
-
-macro(toolchain_cc_warning_error_misra_sane dest_var_name)
-  set_ifndef(${dest_var_name} "-Werror=vla")
-endmacro()
-
-macro(toolchain_cc_cpp_warning_error_misra_sane dest_var_name)
-  set_ifndef(${dest_var_name} "-Werror=vla")
-endmacro()
-
-macro(toolchain_cc_warning_error_coding_guideline_check dest_var_name)
-  if (NOT ${dest_var_name})
-    set(${dest_var_name}
-      -Wvla
-      -Wimplicit-fallthrough
-      -Wconversion
-      -Woverride-init
-      )
-  endif()
-endmacro()
-
-# List the warnings that are not supported for C++ compilations
-
-list(APPEND CXX_EXCLUDED_OPTIONS
-  -Werror=implicit-int
-  -Wold-style-definition
-  )
diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake
new file mode 100644
index 0000000..b7ff02c
--- /dev/null
+++ b/cmake/compiler/gcc/compiler_flags.cmake
@@ -0,0 +1,176 @@
+# Those are flags not to test for CXX compiler.
+list(APPEND CXX_EXCLUDED_OPTIONS
+  -Werror=implicit-int
+  -Wold-style-definition
+  -Wno-pointer-sign
+)
+
+########################################################
+# Setting compiler properties for gcc / g++ compilers. #
+########################################################
+
+#####################################################
+# This section covers flags related to optimization #
+#####################################################
+set_compiler_property(PROPERTY no_optimization -O0)
+if(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.8.0")
+  set_compiler_property(PROPERTY optimization_debug -O0)
+else()
+  set_compiler_property(PROPERTY optimization_debug -Og)
+endif()
+set_compiler_property(PROPERTY optimization_speed -O2)
+set_compiler_property(PROPERTY optimization_size  -Os)
+
+#######################################################
+# This section covers flags related to warning levels #
+#######################################################
+
+# GCC Option standard warning base in Zephyr
+set_compiler_property(PROPERTY warning_base
+    -Wall
+    -Wformat
+    -Wformat-security
+    -Wno-format-zero-length
+    -Wno-main
+)
+
+check_set_compiler_property(APPEND PROPERTY warning_base -Wno-pointer-sign)
+
+# Prohibit void pointer arithmetic. Illegal in C99
+check_set_compiler_property(APPEND PROPERTY warning_base -Wpointer-arith)
+
+if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9.1.0")
+  set_compiler_property(APPEND PROPERTY warning_base
+                        # FIXME: Remove once #16587 is fixed
+                        -Wno-address-of-packed-member
+  )
+endif()
+
+
+# GCC options for warning levels 1, 2, 3, when using `-DW=[1|2|3]`
+set_compiler_property(PROPERTY warning_dw_1
+                      -Waggregate-return
+                      -Wcast-align
+                      -Wdisabled-optimization
+                      -Wnested-externs
+                      -Wshadow
+)
+check_set_compiler_property(APPEND PROPERTY warning_dw_1
+                            -Wlogical-op
+                            -Wmissing-field-initializers
+)
+
+set_compiler_property(PROPERTY warning_dw_2
+                      -Wbad-function-cast
+                      -Wcast-qual
+                      -Wconversion
+                      -Wpacked
+                      -Wpadded
+                      -Wpointer-arith
+                      -Wredundant-decls
+                      -Wswitch-default
+)
+check_set_compiler_property(APPEND PROPERTY warning_dw_2
+                            -Wpacked-bitfield-compat
+                            -Wvla
+)
+set_compiler_property(PROPERTY warning_dw_3
+                      -Wbad-function-cast
+                      -Wcast-qual
+                      -Wconversion
+                      -Wpacked
+                      -Wpadded
+                      -Wpointer-arith
+                      -Wredundant-decls
+                      -Wswitch-default
+)
+check_set_compiler_property(APPEND PROPERTY warning_dw_3
+                            -Wpacked-bitfield-compat
+                            -Wvla
+)
+
+set_compiler_property(PROPERTY warning_extended -Wno-unused-but-set-variable)
+
+set_compiler_property(PROPERTY warning_error_implicit_int -Werror=implicit-int)
+
+set_compiler_property(PROPERTY warning_error_misra_sane -Werror=vla)
+
+set_compiler_property(PROPERTY warning_error_coding_guideline
+                      -Werror=vla
+                      -Wimplicit-fallthrough=2
+                      -Wconversion
+                      -Woverride-init
+)
+
+###########################################################################
+# This section covers flags related to C or C++ standards / standard libs #
+###########################################################################
+
+# GCC compiler flags for C standard. The specific standard must be appended by user.
+set_compiler_property(PROPERTY cstd -std=)
+
+if (NOT CONFIG_NEWLIB_LIBC AND
+    NOT COMPILER STREQUAL "xcc" AND
+    NOT CONFIG_NATIVE_APPLICATION)
+  set_compiler_property(PROPERTY nostdinc -nostdinc)
+  set_compiler_property(APPEND PROPERTY nostdinc_include ${NOSTDINC})
+endif()
+
+# Required C++ flags when using gcc
+set_property(TARGET compiler-cpp PROPERTY required "-fcheck-new")
+
+# GCC compiler flags for C++ dialects
+set_property(TARGET compiler-cpp PROPERTY dialect_cpp98 "-std=c++98")
+set_property(TARGET compiler-cpp PROPERTY dialect_cpp11 "-std=c++11" "-Wno-register")
+set_property(TARGET compiler-cpp PROPERTY dialect_cpp14 "-std=c++14" "-Wno-register")
+set_property(TARGET compiler-cpp PROPERTY dialect_cpp17 "-std=c++17" "-Wno-register")
+set_property(TARGET compiler-cpp PROPERTY dialect_cpp2a "-std=c++2a" "-Wno-register")
+
+# Disable exeptions flag in C++
+set_property(TARGET compiler-cpp PROPERTY no_exceptions "-fno-exceptions")
+
+# Disable rtti in C++
+set_property(TARGET compiler-cpp PROPERTY no_rtti "-fno-rtti")
+
+
+###################################################
+# This section covers all remaining C / C++ flags #
+###################################################
+
+# gcc flags for coverage generation
+set_compiler_property(PROPERTY coverage -fprofile-arcs -ftest-coverage -fno-inline)
+
+# Security canaries.
+set_compiler_property(PROPERTY security_canaries -fstack-protector-all)
+
+# Only a valid option with GCC 7.x and above, so let's do check and set.
+check_set_compiler_property(APPEND PROPERTY security_canaries -mstack-protector-guard=global)
+
+if(NOT CONFIG_NO_OPTIMIZATIONS)
+  # _FORTIFY_SOURCE: Detect common-case buffer overflows for certain functions
+  # _FORTIFY_SOURCE=1 : Compile-time checks (requires -O1 at least)
+  # _FORTIFY_SOURCE=2 : Additional lightweight run-time checks
+  set_compiler_property(PROPERTY security_fortify _FORTIFY_SOURCE=2)
+endif()
+
+# gcc flag for a hosted (no-freestanding) application
+check_set_compiler_property(APPEND PROPERTY hosted -fno-freestanding)
+
+# gcc flag for a freestandingapplication
+set_compiler_property(PROPERTY freestanding -ffreestanding)
+
+# Flag to enable debugging
+set_compiler_property(PROPERTY debug -g)
+
+set_compiler_property(PROPERTY no_common -fno-common)
+
+# GCC compiler flags for imacros. The specific header must be appended by user.
+set_compiler_property(PROPERTY imacros -imacros)
+
+# GCC compiler flags for sanitizing.
+set_compiler_property(PROPERTY sanitize_address -fsanitize=address)
+
+set_compiler_property(PROPERTY sanitize_undefined -fsanitize=undefined)
+
+# Required ASM flags when using gcc
+set_property(TARGET asm PROPERTY required "-xassembler-with-cpp")
diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake
index 6646c06..88be5a0 100644
--- a/cmake/compiler/gcc/target.cmake
+++ b/cmake/compiler/gcc/target.cmake
@@ -113,17 +113,3 @@
   -Wl,--entry=0 # Set an entry point to avoid a warning
   )
 string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
-
-# Load toolchain_cc-family macros
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_freestanding.cmake)
-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)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_asm.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_baremetal.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_warnings.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_imacros.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_base.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_coverage.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_sanitizers.cmake)
diff --git a/cmake/compiler/gcc/target_asm.cmake b/cmake/compiler/gcc/target_asm.cmake
deleted file mode 100644
index b3c3d09..0000000
--- a/cmake/compiler/gcc/target_asm.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# See root CMakeLists.txt for description and expectations of this macro
-
-macro(toolchain_cc_asm_base_flags dest_var_name)
-  # Specify assembly as the source language for the preprocessor to expect
-  set_ifndef(${dest_var_name} "-xassembler-with-cpp")
-endmacro()
diff --git a/cmake/compiler/gcc/target_baremetal.cmake b/cmake/compiler/gcc/target_baremetal.cmake
deleted file mode 100644
index 41e6ce8..0000000
--- a/cmake/compiler/gcc/target_baremetal.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# See root CMakeLists.txt for description and expectations of these macros
-
-macro(toolchain_cc_nostdinc)
-
-  if (NOT CONFIG_NEWLIB_LIBC AND
-    NOT COMPILER STREQUAL "xcc" AND
-    NOT CONFIG_NATIVE_APPLICATION)
-    zephyr_compile_options( -nostdinc)
-    zephyr_system_include_directories(${NOSTDINC})
-  endif()
-
-endmacro()
-
-macro(toolchain_cc_freestanding)
-
-  zephyr_compile_options(-ffreestanding)
-
-endmacro()
diff --git a/cmake/compiler/gcc/target_base.cmake b/cmake/compiler/gcc/target_base.cmake
deleted file mode 100644
index a180962..0000000
--- a/cmake/compiler/gcc/target_base.cmake
+++ /dev/null
@@ -1,26 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# The intention with this file is, to have a common placeholder for macros
-# which does not fit into any of the categories defined by the existing
-# target_xxx.cmake files and which have a fairly high commonality between
-# toolchains.
-#
-# See root CMakeLists.txt for description and expectations of this macro
-
-macro(toolchain_cc_produce_debug_info)
-
-  zephyr_compile_options(-g) # TODO: build configuration enough?
-
-endmacro()
-
-macro(toolchain_cc_nocommon)
-
-  zephyr_compile_options(-fno-common)
-
-endmacro()
-
-macro(toolchain_cc_cstd_flag dest_var_name c_std)
-
-  set_ifndef(${dest_var_name} "-std=${c_std}")
-
-endmacro()
diff --git a/cmake/compiler/gcc/target_coverage.cmake b/cmake/compiler/gcc/target_coverage.cmake
deleted file mode 100644
index 5a7dc74..0000000
--- a/cmake/compiler/gcc/target_coverage.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-macro(toolchain_cc_coverage)
-
-zephyr_compile_options(
-  -fprofile-arcs
-  -ftest-coverage
-  -fno-inline
-)
-
-if (NOT CONFIG_COVERAGE_GCOV)
-
-  zephyr_link_libraries(
-    -lgcov
-  )
-
-endif()
-
-endmacro()
diff --git a/cmake/compiler/gcc/target_cpp.cmake b/cmake/compiler/gcc/target_cpp.cmake
deleted file mode 100644
index 1fd03c3..0000000
--- a/cmake/compiler/gcc/target_cpp.cmake
+++ /dev/null
@@ -1,36 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# 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/gcc/target_freestanding.cmake b/cmake/compiler/gcc/target_freestanding.cmake
deleted file mode 100644
index 3648ecf..0000000
--- a/cmake/compiler/gcc/target_freestanding.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) 2019 Intel Corporation.
-# SPDX-License-Identifier: Apache-2.0
-
-macro(toolchain_cc_no_freestanding_options)
-
-  zephyr_cc_option(-fno-freestanding)
-
-endmacro()
diff --git a/cmake/compiler/gcc/target_imacros.cmake b/cmake/compiler/gcc/target_imacros.cmake
deleted file mode 100644
index 0fba838..0000000
--- a/cmake/compiler/gcc/target_imacros.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# See root CMakeLists.txt for description and expectations of these macros
-
-macro(toolchain_cc_imacros header_file)
-
-  # We cannot use the "-imacros foo" form here as CMake insists on
-  # deduplicating arguments, meaning that subsequent usages after the
-  # first one will see the "-imacros " part removed.
-  # gcc and clang support the "--imacros=foo" form but not xcc.
-  # Let's use the "combined" form (without space) which is supported
-  # by everyone so far.
-  zephyr_compile_options(-imacros${header_file})
-
-endmacro()
diff --git a/cmake/compiler/gcc/target_optimizations.cmake b/cmake/compiler/gcc/target_optimizations.cmake
deleted file mode 100644
index 4deacc7..0000000
--- a/cmake/compiler/gcc/target_optimizations.cmake
+++ /dev/null
@@ -1,33 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# 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)
-  # -Og optimisation flag is only supported from gcc 4.8.0 and above.
-  # Fall back to using -O0 flag if running an older gcc version.
-  if(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.8.0")
-    set_ifndef(${dest_var_name}  "-O0")
-  else()
-    set_ifndef(${dest_var_name}  "-Og")
-  endif()
-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/gcc/target_sanitizers.cmake b/cmake/compiler/gcc/target_sanitizers.cmake
deleted file mode 100644
index 1661307..0000000
--- a/cmake/compiler/gcc/target_sanitizers.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-macro(toolchain_cc_asan)
-
-zephyr_compile_options(-fsanitize=address)
-zephyr_link_libraries(-lasan)
-zephyr_ld_options(-fsanitize=address)
-
-endmacro()
-
-macro(toolchain_cc_ubsan)
-
-zephyr_compile_options(-fsanitize=undefined)
-zephyr_ld_options(-fsanitize=undefined)
-
-endmacro()
diff --git a/cmake/compiler/gcc/target_security_canaries.cmake b/cmake/compiler/gcc/target_security_canaries.cmake
deleted file mode 100644
index 8db8d48..0000000
--- a/cmake/compiler/gcc/target_security_canaries.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# See root CMakeLists.txt for description and expectations of this macro
-macro(toolchain_cc_security_canaries)
-
-  zephyr_compile_options(-fstack-protector-all)
-
-  # Only a valid option with GCC 7.x and above
-  zephyr_cc_option(-mstack-protector-guard=global)
-
-endmacro()
diff --git a/cmake/compiler/gcc/target_security_fortify.cmake b/cmake/compiler/gcc/target_security_fortify.cmake
deleted file mode 100644
index 3aa0944..0000000
--- a/cmake/compiler/gcc/target_security_fortify.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# See root CMakeLists.txt for description and expectations of this macro
-macro(toolchain_cc_security_fortify)
-
-  if(NOT CONFIG_NO_OPTIMIZATIONS)
-    # _FORTIFY_SOURCE: Detect common-case buffer overflows for certain functions
-    # _FORTIFY_SOURCE=1 : Compile-time checks (requires -O1 at least)
-    # _FORTIFY_SOURCE=2 : Additional lightweight run-time checks
-    zephyr_compile_definitions(
-      _FORTIFY_SOURCE=2
-    )
-  endif()
-
-endmacro()
diff --git a/cmake/compiler/gcc/target_warnings.cmake b/cmake/compiler/gcc/target_warnings.cmake
deleted file mode 100644
index 2788a60..0000000
--- a/cmake/compiler/gcc/target_warnings.cmake
+++ /dev/null
@@ -1,129 +0,0 @@
-# SPDX-License-Identifier: Apache-2.0
-
-# See root CMakeLists.txt for description and expectations of these macros
-
-macro(toolchain_cc_warning_base)
-
-  zephyr_compile_options(
-    -Wall
-    -Wformat
-    -Wformat-security
-    -Wno-format-zero-length
-    -Wno-main
-  )
-
-if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9.1.0")
-  zephyr_compile_options(
-    # FIXME: Remove once #16587 is fixed
-    -Wno-address-of-packed-member
-  )
-endif()
-
-  zephyr_cc_option(-Wno-pointer-sign)
-
-  # Prohibit void pointer arithmetic. Illegal in C99
-  zephyr_cc_option(-Wpointer-arith)
-
-endmacro()
-
-macro(toolchain_cc_warning_dw_1)
-
-  zephyr_compile_options(
-    -Wextra
-    -Wunused
-    -Wno-unused-parameter
-    -Wmissing-declarations
-    -Wmissing-format-attribute
-    )
-  zephyr_cc_option(
-    -Wold-style-definition
-    -Wmissing-prototypes
-    -Wmissing-include-dirs
-    -Wunused-but-set-variable
-    -Wno-missing-field-initializers
-    )
-
-endmacro()
-
-macro(toolchain_cc_warning_dw_2)
-
-  zephyr_compile_options(
-    -Waggregate-return
-    -Wcast-align
-    -Wdisabled-optimization
-    -Wnested-externs
-    -Wshadow
-    )
-  zephyr_cc_option(
-    -Wlogical-op
-    -Wmissing-field-initializers
-    )
-
-endmacro()
-
-macro(toolchain_cc_warning_dw_3)
-
-  zephyr_compile_options(
-    -Wbad-function-cast
-    -Wcast-qual
-    -Wconversion
-    -Wpacked
-    -Wpadded
-    -Wpointer-arith
-    -Wredundant-decls
-    -Wswitch-default
-    )
-  zephyr_cc_option(
-    -Wpacked-bitfield-compat
-    -Wvla
-    )
-
-endmacro()
-
-macro(toolchain_cc_warning_extended)
-
-  zephyr_cc_option(
-    -Wno-unused-but-set-variable
-    )
-
-endmacro()
-
-macro(toolchain_cc_warning_error_implicit_int)
-
-  # Force an error when things like SYS_INIT(foo, ...) occur with a missing header
-  zephyr_cc_option(-Werror=implicit-int)
-
-endmacro()
-
-#
-# The following macros leaves it up to the root CMakeLists.txt to choose
-#  the variables in which to put the requested flags, and whether or not
-#  to call the macros
-#
-
-macro(toolchain_cc_warning_error_misra_sane dest_var_name)
-  set_ifndef(${dest_var_name} "-Werror=vla")
-endmacro()
-
-macro(toolchain_cc_cpp_warning_error_misra_sane dest_var_name)
-  set_ifndef(${dest_var_name} "-Werror=vla")
-endmacro()
-
-macro(toolchain_cc_warning_error_coding_guideline_check dest_var_name)
-  if (NOT ${dest_var_name})
-    set(${dest_var_name}
-      -Wvla
-      -Wimplicit-fallthrough=2
-      -Wconversion
-      -Woverride-init
-      )
-  endif()
-endmacro()
-
-# List the warnings that are not supported for C++ compilations
-
-list(APPEND CXX_EXCLUDED_OPTIONS
-  -Werror=implicit-int
-  -Wold-style-definition
-  -Wno-pointer-sign
-  )
diff --git a/cmake/compiler/host-gcc/compiler_flags.cmake b/cmake/compiler/host-gcc/compiler_flags.cmake
new file mode 100644
index 0000000..9203aa3
--- /dev/null
+++ b/cmake/compiler/host-gcc/compiler_flags.cmake
@@ -0,0 +1,3 @@
+# Load toolchain_cc-family compiler flags
+# Significant overlap with freestanding gcc compiler so reuse it
+include(${ZEPHYR_BASE}/cmake/compiler/gcc/compiler_flags.cmake)
diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake
index 11c8173..648bd31 100644
--- a/cmake/compiler/host-gcc/target.cmake
+++ b/cmake/compiler/host-gcc/target.cmake
@@ -51,18 +51,3 @@
 
   list(APPEND NOSTDINC ${_OUTPUT})
 endforeach()
-
-# Load toolchain_cc-family macros
-# Significant overlap with freestanding gcc compiler so reuse it
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_freestanding.cmake)
-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)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_asm.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_baremetal.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_warnings.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_imacros.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_base.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_coverage.cmake)
-include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_sanitizers.cmake)
diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake
index 94b5970..becfc3d 100644
--- a/cmake/extensions.cmake
+++ b/cmake/extensions.cmake
@@ -1402,6 +1402,111 @@
   set(${include_files} ${result} PARENT_SCOPE)
 endfunction()
 
+# 'check_set_linker_property' is a function that check the provided linker
+# flag and only set the linker property if the check succeeds
+#
+# This function is similar in nature to the CMake set_property function, but
+# with the extension that it will check that the linker supports the flag before
+# setting the property.
+#
+# APPEND: Flag indicated that the property should be appended to the existing
+#         value list for the property.
+# TARGET: Name of target on which to add the property (commonly: linker)
+# PROPERTY: Name of property with the value(s) following immediately after
+#           property name
+function(check_set_linker_property)
+  set(options APPEND)
+  set(single_args TARGET)
+  set(multi_args  PROPERTY)
+  cmake_parse_arguments(LINKER_PROPERTY "${options}" "${single_args}" "${multi_args}" ${ARGN})
+
+  if(LINKER_PROPERTY_APPEND)
+   set(APPEND "APPEND")
+  endif()
+
+  list(GET LINKER_PROPERTY_PROPERTY 0 property)
+  list(REMOVE_AT LINKER_PROPERTY_PROPERTY 0)
+  set(option ${LINKER_PROPERTY_PROPERTY})
+
+  string(MAKE_C_IDENTIFIER check${option} check)
+
+  set(SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${option}")
+  zephyr_check_compiler_flag(C "" ${check})
+  set(CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS})
+
+  if(${check})
+    set_property(TARGET ${LINKER_PROPERTY_TARGET} ${APPEND} PROPERTY ${property} ${option})
+  endif()
+endfunction()
+
+# 'set_compiler_property' is a function that sets the property for the C and
+# C++ property targets used for toolchain abstraction.
+#
+# This function is similar in nature to the CMake set_property function, but
+# with the extension that it will set the property on both the compile and
+# compiler-cpp targets.
+#
+# APPEND: Flag indicated that the property should be appended to the existing
+#         value list for the property.
+# PROPERTY: Name of property with the value(s) following immediately after
+#           property name
+function(set_compiler_property)
+  set(options APPEND)
+  set(multi_args  PROPERTY)
+  cmake_parse_arguments(COMPILER_PROPERTY "${options}" "${single_args}" "${multi_args}" ${ARGN})
+  if(COMPILER_PROPERTY_APPEND)
+   set(APPEND "APPEND")
+   set(APPEND-CPP "APPEND")
+  endif()
+
+  set_property(TARGET compiler ${APPEND} PROPERTY ${COMPILER_PROPERTY_PROPERTY})
+  set_property(TARGET compiler-cpp ${APPEND} PROPERTY ${COMPILER_PROPERTY_PROPERTY})
+endfunction()
+
+# 'check_set_compiler_property' is a function that check the provided compiler
+# flag and only set the compiler or compiler-cpp property if the check succeeds
+#
+# This function is similar in nature to the CMake set_property function, but
+# with the extension that it will check that the compiler supports the flag
+# before setting the property on compiler or compiler-cpp targets.
+#
+# APPEND: Flag indicated that the property should be appended to the existing
+#         value list for the property.
+# PROPERTY: Name of property with the value(s) following immediately after
+#           property name
+function(check_set_compiler_property)
+  set(options APPEND)
+  set(multi_args  PROPERTY)
+  cmake_parse_arguments(COMPILER_PROPERTY "${options}" "${single_args}" "${multi_args}" ${ARGN})
+  if(COMPILER_PROPERTY_APPEND)
+   set(APPEND "APPEND")
+   set(APPEND-CPP "APPEND")
+  endif()
+
+  list(GET COMPILER_PROPERTY_PROPERTY 0 property)
+  list(REMOVE_AT COMPILER_PROPERTY_PROPERTY 0)
+
+  foreach(option ${COMPILER_PROPERTY_PROPERTY})
+    if(CONFIG_CPLUSPLUS)
+      zephyr_check_compiler_flag(CXX ${option} check)
+
+      if(${check})
+        set_property(TARGET compiler-cpp ${APPEND-CPP} PROPERTY ${property} ${option})
+        set(APPEND-CPP "APPEND")
+      endif()
+    endif()
+
+    zephyr_check_compiler_flag(C ${option} check)
+
+    if(${check})
+      set_property(TARGET compiler ${APPEND} PROPERTY ${property} ${option})
+      set(APPEND "APPEND")
+    endif()
+  endforeach()
+endfunction()
+
+
 # 3.4. Debugging CMake
 
 # Usage:
diff --git a/cmake/linker/ld/clang/linker_flags.cmake b/cmake/linker/ld/clang/linker_flags.cmake
new file mode 100644
index 0000000..5f4c036
--- /dev/null
+++ b/cmake/linker/ld/clang/linker_flags.cmake
@@ -0,0 +1,9 @@
+# The coverage linker flag is specific for clang.
+if (NOT CONFIG_COVERAGE_GCOV)
+  set_property(TARGET linker PROPERTY coverage --coverage)
+endif()
+
+# ld/clang linker flags for sanitizing.
+check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -fsanitize=address)
+
+check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_undefined -fsanitize=undefined)
diff --git a/cmake/linker/ld/gcc/linker_flags.cmake b/cmake/linker/ld/gcc/linker_flags.cmake
new file mode 100644
index 0000000..82a526a
--- /dev/null
+++ b/cmake/linker/ld/gcc/linker_flags.cmake
@@ -0,0 +1,14 @@
+# The coverage linker flag is specific for gcc.
+
+# Using a config check is ok for now, but in future it would be desired if
+# linker flags themselves are not depending on actual configurations.
+# All flags should be described, and the caller should now the flag name to use.
+if (NOT CONFIG_COVERAGE_GCOV)
+  set_property(TARGET linker PROPERTY coverage -lgcov)
+endif()
+
+# ld/gcc linker flags for sanitizing.
+check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -lasan)
+check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_address -fsanitize=address)
+
+check_set_linker_property(TARGET linker APPEND PROPERTY sanitize_undefined -fsanitize=undefined)
diff --git a/cmake/linker/ld/host-gcc/linker_flags.cmake b/cmake/linker/ld/host-gcc/linker_flags.cmake
new file mode 100644
index 0000000..24b1e2f
--- /dev/null
+++ b/cmake/linker/ld/host-gcc/linker_flags.cmake
@@ -0,0 +1,2 @@
+# The host-gcc supports the same flags as any other gcc.
+include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/gcc/linker_flags.cmake)
diff --git a/cmake/linker/ld/linker_flags.cmake b/cmake/linker/ld/linker_flags.cmake
new file mode 100644
index 0000000..0b16f2b
--- /dev/null
+++ b/cmake/linker/ld/linker_flags.cmake
@@ -0,0 +1,8 @@
+check_set_linker_property(TARGET linker PROPERTY memusage "${LINKERFLAGPREFIX},--print-memory-usage")
+
+# Some linker flags might not be purely ld specific, but a combination of
+# linker and compiler, such as:
+# --coverage for clang
+# --gcov for gcc
+# So load those flags now.
+include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/${COMPILER}/linker_flags.cmake OPTIONAL)
diff --git a/cmake/target_toolchain.cmake b/cmake/target_toolchain.cmake
index a117538d..8737bcb 100644
--- a/cmake/target_toolchain.cmake
+++ b/cmake/target_toolchain.cmake
@@ -46,6 +46,8 @@
 # In Zephyr, toolchains require a port under cmake/toolchain/.
 # Each toolchain port must set COMPILER and LINKER.
 # E.g. toolchain/llvm may pick {clang, ld} or {clang, lld}.
+add_custom_target(bintools)
+
 include(${TOOLCHAIN_ROOT}/cmake/compiler/${COMPILER}/target.cmake OPTIONAL)
 include(${TOOLCHAIN_ROOT}/cmake/linker/${LINKER}/target.cmake OPTIONAL)
 include(${TOOLCHAIN_ROOT}/cmake/bintools/${BINTOOLS}/target.cmake OPTIONAL)
diff --git a/cmake/target_toolchain_flags.cmake b/cmake/target_toolchain_flags.cmake
new file mode 100644
index 0000000..66ce283
--- /dev/null
+++ b/cmake/target_toolchain_flags.cmake
@@ -0,0 +1,10 @@
+# Custom targets for compiler and linker flags.
+add_custom_target(asm)
+add_custom_target(compiler)
+add_custom_target(compiler-cpp)
+add_custom_target(linker)
+
+# Configure the toolchain flags based on what toolchain technology is used
+# (gcc, host-gcc etc.)
+include(${TOOLCHAIN_ROOT}/cmake/compiler/${COMPILER}/compiler_flags.cmake OPTIONAL)
+include(${TOOLCHAIN_ROOT}/cmake/linker/${LINKER}/linker_flags.cmake OPTIONAL)