Build: add build type support

Refactor cmake files to support setting the "build type" following CMake
idioms. A "build type" is a set of compiler flags controlling code
optimization and debug information generation. For more information on
the supported types and their meaning please refer to the documentation.

This change extends build type support to external components too. The
build type of each component can be independently controlled using
command line settings. For details about the supported types and
settings, please refer to the cmake file of the external component and
the documentation of the external project.

This change tries to be backwards compatible and selects the default
build type to be "Debug". This may change in the future.

Change-Id: Ic041140bb8d4aaf0f07be9c4cac0638c03996eb5
Signed-off-by: Gyorgy Szing <Gyorgy.Szing@arm.com>
diff --git a/environments/arm-linux/default_toolchain_file.cmake b/environments/arm-linux/default_toolchain_file.cmake
index 85de9df..e77d355 100644
--- a/environments/arm-linux/default_toolchain_file.cmake
+++ b/environments/arm-linux/default_toolchain_file.cmake
@@ -4,6 +4,11 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# Since we append to default compilation flags stop multiple inclusion to avoid
+# flags being added multiple times.
+include_guard(GLOBAL)
+
 if(NOT CROSS_COMPILE AND NOT DEFINED ENV{CROSS_COMPILE})
 	set(CROSS_COMPILE "aarch64-linux-gnu-;aarch64-none-linux-gnu-" CACHE STRING "List of GCC prefix triplets to use.")
 endif()
@@ -12,15 +17,40 @@
 set(CMAKE_SYSTEM_NAME Linux)
 set(CMAKE_SYSTEM_PROCESSOR arm)
 
-string(APPEND CMAKE_C_FLAGS_INIT " -fdiagnostics-show-option -gdwarf-2 -mstrict-align -O0 -DARM64=1")
-string(APPEND CMAKE_CXX_FLAGS_INIT " -fdiagnostics-show-option -gdwarf-2 -mstrict-align -O0 -DARM64=1")
+set(TS_DEBUG_INFO_FLAGS "-fdiagnostics-show-option -gdwarf-2" CACHE STRING "Compiler flags to add debug information.")
+set(TS_MANDATORY_AARCH_FLAGS "-mstrict-align -DARM64=1" CACHE STRING "Compiler flags configuring architecture specific ")
+set(TS_WARNING_FLAGS "-Wall" CACHE STRING "Compiler flags affecting generating warning messages.")
+set(TS_MANDATORY_LINKER_FLAGS "" CACHE STRING "Linker flags needed for correct builds.")
 
-# Set compiler warning level for the root build context. External components
-# are responsible for setting their own warning level.
-if(DEFINED TS_ROOT)
-    string(APPEND CMAKE_C_FLAGS_INIT " -Wall")
-    string(APPEND CMAKE_CXX_FLAGS_INIT " -Wall")
-endif()
+# Set flags affecting all build types
+foreach(_b_type IN ITEMS DEBUG MINSIZEREL MINSIZWITHDEBINFO RELEASE RELWITHDEBINFO)
+	string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+	string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+	string(APPEND CMAKE_EXE_LINKER_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
+	if(DEFINED TS_ROOT)
+		# Flags not to be used with external components.
+		string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
+		string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
+	endif()
+endforeach()
+
+# Set flags affecting all build types supporting debugging.
+foreach(_b_type IN ITEMS DEBUG RELWITHDEBINFO MINSIZWITHDEBINFO)
+	string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_DEBUG_INFO_FLAGS}")
+	string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_DEBUG_INFO_FLAGS}")
+endforeach()
+
+# Build type specific flags
+string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -O0")
+string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT  " -Os")
+string(APPEND CMAKE_C_FLAGS_MINSIZWITHDEBINFO_INIT " -Os")
+string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -O2")
+string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -O2")
+string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " -O0")
+string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT  " -Os")
+string(APPEND CMAKE_CXX_FLAGS_MINSIZWITHDEBINFO_INIT " -Os")
+string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -O2")
+string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -O2")
 
 include($ENV{TS_ROOT}/tools/cmake/compiler/GCC.cmake REQUIRED)
 include($ENV{TS_ROOT}/tools/cmake/compiler/config_iface.cmake REQUIRED)