blob: 43e1b90012febd6b8b311fbb346fec4dbbbbf9b4 [file] [log] [blame]
#-------------------------------------------------------------------------------
# Copyright (c) 2017, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#-------------------------------------------------------------------------------
#This file defines project-specific overrides to cmake default behaviour for:
# * compiler detection
# * target system detection
cmake_minimum_required(VERSION 3.3) #IN_LIST was introduced in 3.3
cmake_policy(SET CMP0057 NEW)
Include(CMakeParseArguments)
#The CMAKE_SYSTEM_XXX settings make cmake to stop applying some target system specific settings.
#Tell cmake we are compiling for ARM chips.
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE INTERNAL "Set target processor type to force cmake include some of our scripts." FORCE)
#Tell cmake this is an "Embedded" system
set(CMAKE_SYSTEM_NAME "Embedded" CACHE INTERNAL "Set target system name to force cmake include some of our scripts." FORCE)
#Stop built in CMakeDetermine<lang>.cmake scripts to run.
set (CMAKE_CXX_COMPILER_ID_RUN 1)
#Stop cmake run compiler tests.
set (CMAKE_CXX_COMPILER_FORCED true)
#Stop built in CMakeDetermine<lang>.cmake scripts to run.
set (CMAKE_C_COMPILER_ID_RUN 1)
#Stop cmake run compiler tests.
set (CMAKE_C_COMPILER_FORCED true)
#This macro is used to enforce the ARM project structure.
#Inputs: (This macro uses some "global" variables)
# global variable PROJ_CONFIG - a global configuration file to be used by all projects.
# It overrides value of CONFIG parameter.
# CONFIG - the configuration file which shall be used
#Examples
# To use global project config:
# embedded_project_start()
# To use config file relative to the top level CmakeLists.txt:
# embedded_project_start(./ConfigDefault.cmake)
# To use config file relative to the CmakeLists.txt file where this macro is used:
# embedded_project_start(${CMAKE_CURRENT_LIST_DIR}/ConfigDefault.cmake)
macro(embedded_project_start)
#Default project configuration file
if (DEFINED PROJ_CONFIG) #Take the global setting as default value
set(_PROJ_CONFIG ${PROJ_CONFIG})
endif()
set( _OPTIONS_ARGS ) #No option (on/off) arguments
set( _ONE_VALUE_ARGS CONFIG) #Single option arguments (e.g. PROJ_NAME "bubu_project")
set( _MULTI_VALUE_ARGS ) #One list argument (e.g. LANGUAGES C ASM CXX)
cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
#Cehck passed parameters
if(NOT _MY_PARAMS_CONFIG)
if(NOT DEFINED _PROJ_CONFIG)
set(_PROJ_CONFIG "./ConfigDefault.cmake")
message(STATUS "embedded_project_start: no project configuration file defined, falling back to default.")
endif()
elseif(NOT DEFINED PROJ_CONFIG)
set(_PROJ_CONFIG ${_MY_PARAMS_CONFIG})
endif()
get_filename_component(_ABS_PROJ_CONFIG ${_PROJ_CONFIG} ABSOLUTE)
message( STATUS "embedded_project_start: using project specific config file (PROJ_CONFIG = ${_ABS_PROJ_CONFIG})")
include("${_PROJ_CONFIG}")
endmacro()
#Override CMake default behaviour
macro(embedded_project_fixup)
get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
if("CXX" IN_LIST languages)
include(Common/CompilerDetermineCXX)
#since all CMake "built in" scripts already executed, we need fo fix up some things here.
embedded_fixup_build_type_vars(CXX)
endif()
if("C" IN_LIST languages)
include(Common/CompilerDetermineC)
embedded_fixup_build_type_vars(C)
endif()
#Merge CPU and configuration specific compiler and linker flags.
foreach(LNG ${languages})
#Apply CPU specific and configuration specific compile flags.
if(NOT CMAKE_${LNG}_FLAGS MATCHES ".*${CMAKE_${LNG}_FLAGS_CPU}.*")
set(CMAKE_${LNG}_FLAGS "${CMAKE_${LNG}_FLAGS} ${CMAKE_${LNG}_FLAGS_CPU}")
endif()
#Fix output file extension.
set (CMAKE_EXECUTABLE_SUFFIX_${LNG} ".axf")
unset(ALL_SRC_${LNG})
unset(ALL_SRC_${LNG}_S)
unset(ALL_SRC_${LNG}_NS)
endforeach()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_LINK_FLAGS_CPU}")
endmacro()
#Allow project specific script to do configuration after all targets are specified; it has to be done for each target defined
macro (embedded_project_end TARGET)
get_property(_MAC DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY MACROS)
if ("embedded_project_build_config_apply" IN_LIST _MAC)
message(WARNING "embedded_project_end(): macro embedded_project_build_config_apply() is defined. Your build config file may be out-dated.")
endif()
#Apply compile flags.
_embedded_apply_compile_flags(${TARGET})
#Apply macro definitions
_embedded_apply_compile_defines(${TARGET})
#Apply include paths
_embedded_apply_include_directories(${TARGET})
#Apply linker flags.
_embedded_apply_link_flags(${TARGET})
#If target is executable, apply linker command file setting.
get_property(_TGT_TYPE TARGET ${TARGET} PROPERTY TYPE)
if(_TGT_TYPE STREQUAL "EXECUTABLE")
_embedded_apply_linker_cmd_file_setting(${TARGET})
endif()
endmacro()
macro(embedded_fixup_build_type_vars LANG)
#since all CMake "built in" scripts already executed, we need fo fix up some things here.
set (CMAKE_${LANG}_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG_INIT}" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
set (CMAKE_${LANG}_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL_INIT}" CACHE STRING "Flags used by the compiler during release builds for minimum size." FORCE)
set (CMAKE_${LANG}_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE_INIT}" CACHE STRING "Flags used by the compiler during release builds." FORCE)
set (CMAKE_${LANG}_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING "Flags used by the compiler during release builds with debug info." FORCE)
endmacro()
#Convert a CMake list to a string
#
#Examples:
# list_to_string(my_string 1 2 3 4)
# list_to_string(my_string ${CMAKE_C_FLAGS})
#
#INPUTS:
# RES - (mandatory) - name of variable to put result in
# The list to be converted.
#
#OUTPUTS
# List items concatenated to a string.
#
function(list_to_string RES)
foreach(_ITEM ${ARGN})
set(_RES "${_RES} ${_ITEM}")
endforeach()
set(${RES} "${_RES}" PARENT_SCOPE)
endfunction()
#Ensure current generator is supported.
#
# This function takes a list of supported generators (e.g. "Unix Makefiles") and
# exits with fatal error is the current generator is not on the list.
#Examples:
# assert_generator_is("MSYS Makefiles" "MinGW Makefiles")
#
#INPUTS:
# The list of supported generators.
#
#OUTPUTS
# n/a
#
function(assert_generator_is)
if (NOT CMAKE_GENERATOR IN_LIST ARGN)
message(FATAL_ERROR "assert_generator_is(): Generator '${CMAKE_GENERATOR}' is not on the list of supported generators.")
endif()
endfunction()
#Specify an include path for the compiler
#
# Specify a global include directory for all non external targets in the current
# build.
# The parameter ABSOLUTE can be set to true to ask CMake to convert the PATH to
# absolute. This gives better looking command line arguments, and also helps
# removing duplicates.
#
#Examples:
# embedded_include_directories(PATH "C:/fo/bar/include")
# embedded_include_directories(PATH "C:/fo/bar/include" ABSOLUTE)
#
#INPUTS:
# PATH - (mandatory) - the include path to add
# ABSOLUTE - (optional) - whether the path shall be converted to absolute
#
#OUTPUTS
# Modified list of include directories.
#
function (embedded_include_directories)
#Parse our arguments
set( _OPTIONS_ARGS ABSOLUTE) #Option (on/off) arguments (e.g. IGNORE_CASE)
set( _ONE_VALUE_ARGS PATH) #Single option arguments (e.g. PATH "./foo/bar")
set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
#Check mandatory parameters
if(NOT _MY_PARAMS_PATH)
failure("embedded_include_directories(): Missing PATH parameter!")
endif()
if(DEFINED _MY_PARAMS_ABSOLUTE AND ${_MY_PARAMS_ABSOLUTE})
get_filename_component(_MY_PARAMS_PATH ${_MY_PARAMS_PATH} ABSOLUTE)
endif()
include_directories(${_MY_PARAMS_PATH})
endfunction()
#Return the language of a source file.
#
# Language is either specified by the LANGUAGE property of the source file or
# determined based on the extension of the file.
# Search is limited for languages enabled in the current project.
#
#Examples:
# To get language of "foo/bar.c" written into _LNG:
# embedded_get_source_language("foo/bar.c" _LNG)
#
#INPUTS:
# FILE - (mandatory) - The file to determine language of.
# RES - (mandatory) - Name of the variable to write the result into.
#
#OUTPUTS
# ${RES} - language string (e.g. "C", "CXX", "ASM"). empty string for files
# with no language.
#
function(embedded_get_source_language FILE RES)
if (ARGN)
message(FATAL_ERROR "embedded_get_source_language(): too many parameters passed.")
endif()
#If language property is set, use that.
get_property(_LNG SOURCE ${_SRC} PROPERTY LANGUAGE)
if (NOT ${_LNG} STREQUAL "")
set(${RES} ${_LNG} PARENT_SCOPE)
else()
#Set empty return value.
set(${RES} "" PARENT_SCOPE)
#Property not set, use extension of the file to determine
#language.
string(REGEX MATCH "[^.]*$" _EXT "${_SRC}")
#Get list of enabled languages.
get_property(_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(_LNG ${_LANGUAGES})
#See if the extension is contained in the list of file extensions
#of this language.
if(_EXT IN_LIST CMAKE_${_LNG}_SOURCE_FILE_EXTENSIONS)
set(${RES} ${_LNG} PARENT_SCOPE)
break()
endif()
endforeach()
endif()
endfunction()
#Set compilation flags for the specified target.
#
# Store compilation flags for the specified target and language pair. Flags are
# stored in a global property and will
# be applied to source files in the current directory and sub-directories.
# Property name must follow a specific scheme (see outputs).
# See: _embedded_apply_compile_flags()
#
#Examples:
# embedded_set_target_compile_flags(my_app C "-fchar-unsigned")
# embedded_set_target_compile_flags(my_lib CXX "-fchar-unsigned")
# embedded_set_target_compile_flags(my_app ASM "-fchar-unsigned")
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# LANGUAGE - (mandatory) - Programming language of source files settings shall
# be applied to.
# FLAGS - (mandatory) - List with the compiler flags.
# APPEND - (optional) - True if FLAGS shall be appended.
#
#OUTPUTS
# Directory property EMBEDDED_COMPILE_FLAGS_TTT_LLL is set, where TTT is the
# target name, and LLL is the language.
#
function (embedded_set_target_compile_flags)
set( _OPTIONS_ARGS APPEND) #Option (on/off) arguments (e.g. IGNORE_CASE)
set( _ONE_VALUE_ARGS TARGET LANGUAGE) #Single option arguments (e.g. PATH "./foo/bar")
set( _MULTI_VALUE_ARGS FLAGS) #List arguments (e.g. LANGUAGES C ASM CXX)
cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
if (NOT DEFINED _MY_PARAMS_TARGET)
message(FATAL_ERROR "embedded_set_target_compile_flags(): mandatory parameter 'TARGET' missing.")
endif()
if (NOT DEFINED _MY_PARAMS_LANGUAGE)
message(FATAL_ERROR "embedded_set_target_compile_flags(): mandatory parameter 'LANGUAGE' missing.")
endif()
if (NOT DEFINED _MY_PARAMS_FLAGS)
message(FATAL_ERROR "embedded_set_target_compile_flags(): mandatory parameter 'FLAGS' missing.")
endif()
if (_MY_PARAMS_APPEND)
set_property(GLOBAL APPEND PROPERTY EMBEDDED_COMPILE_FLAGS_${_MY_PARAMS_TARGET}_${_MY_PARAMS_LANGUAGE} ${_MY_PARAMS_FLAGS})
else()
set_property(GLOBAL PROPERTY EMBEDDED_COMPILE_FLAGS_${_MY_PARAMS_TARGET}_${_MY_PARAMS_LANGUAGE} ${_MY_PARAMS_FLAGS})
endif()
endfunction()
#Apply compilation flag settings for the specified target.
#
# Compilation flags stored in a global property and are applied to source files.
# Note:
# - Directory property name must follow a specific scheme.
# - This is an internal function.
# - This function only supports make and ninja generators.
#
# See: embedded_set_target_compile_flags()
#
#Examples:
# _embedded_apply_compile_flags(my_app)
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# Directory property - (optional) - Flags to apply.
#
#OUTPUTS
# n/a
#
function(_embedded_apply_compile_flags TARGET)
#Check if the parameter is a target.
if(NOT TARGET ${TARGET})
message(FATAL_ERROR "_embedded_apply_compile_flags(): target '${TARGET}' is not defined.")
endif()
#Get list of enabled languages.
get_property(_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(_LNG ${_LANGUAGES})
#Get the flags for this language.
get_property(_FLAGS GLOBAL PROPERTY EMBEDDED_COMPILE_FLAGS_${TARGET}_${_LNG})
#The generator expression below is only supported by the make and ninja
#generators.
assert_generator_is(_GENERATORS_OK "MSYS Makefiles" "MinGW Makefiles" "NMake Makefiles" "NMake Makefiles JOM" "Unix Makefiles" "Watcom WMake" "Ninja")
target_compile_options(${TARGET} PRIVATE $<$<COMPILE_LANGUAGE:${_LNG}>:${_FLAGS}>)
endforeach()
endfunction()
#Set compilation defines for the specified target.
#
# Store compilation defines for the specified target and language pair. Macros
# are stored in a global property and will
# be applied to source files in the current directory and sub-directories.
# Property name must follow a specific scheme (see outputs).
# See: _embedded_apply_compile_defines()
#
#Examples:
# embedded_set_target_compile_defines(my_app C "FOO BAR=1")
# embedded_set_target_compile_defines(my_lib CXX "FOO BAR=1")
# embedded_set_target_compile_defines(my_app ASM "FOO BAR=1")
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# LANGUAGE - (mandatory) - Programming language of source files settings shall
# be applied to.
# DEFINES - (mandatory) - List with the compiler flags.
# APPEND - (optional) - Present if FLAGS shall be appended.
#
#OUTPUTS
# Directory property EMBEDDED_COMPILE_DEFINES_TTT_LLL is set, where TTT is the
# target name, and LLL is the language.
#
function (embedded_set_target_compile_defines)
set( _OPTIONS_ARGS APPEND) #Option (on/off) arguments (e.g. IGNORE_CASE)
set( _ONE_VALUE_ARGS TARGET LANGUAGE) #Single option arguments (e.g. PATH "./foo/bar")
set( _MULTI_VALUE_ARGS DEFINES) #List arguments (e.g. LANGUAGES C ASM CXX)
cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
if (NOT DEFINED _MY_PARAMS_TARGET)
message(FATAL_ERROR "embedded_set_target_compile_defines(): mandatory parameter 'TARGET' missing.")
endif()
if (NOT DEFINED _MY_PARAMS_LANGUAGE)
message(FATAL_ERROR "embedded_set_target_compile_defines(): mandatory parameter 'LANGUAGE' missing.")
endif()
if (NOT DEFINED _MY_PARAMS_DEFINES)
message(FATAL_ERROR "embedded_set_target_compile_defines(): mandatory parameter 'DEFINES' missing.")
endif()
if (_MY_PARAMS_APPEND)
set_property(GLOBAL APPEND PROPERTY EMBEDDED_COMPILE_DEFINES_${_MY_PARAMS_TARGET}_${_MY_PARAMS_LANGUAGE} ${_MY_PARAMS_DEFINES})
else()
set_property(GLOBAL PROPERTY EMBEDDED_COMPILE_DEFINES_${_MY_PARAMS_TARGET}_${_MY_PARAMS_LANGUAGE} ${_MY_PARAMS_DEFINES})
endif()
endfunction()
#Apply compilation defines for the specified target.
#
# Macro definitions are stored in a global property and are applied to
# source files.
#
# Note:
# - Directory property name must follow a specific scheme.
# - This is an internal function.
# - This function only supports make and ninja generators.
#
# See: embedded_set_target_compile_defines()
#
#Examples:
# _embedded_apply_compile_defines(my_app)
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# Directory property - (optional) - Flags to apply.
#
#OUTPUTS
# n/a
#
function(_embedded_apply_compile_defines TARGET)
#Check if the parameter is a target.
if(NOT TARGET ${TARGET})
message(FATAL_ERROR "_embedded_apply_compile_defines(): target '${TARGET}' is not defined.")
endif()
#Get list of enabled languages.
get_property(_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(_LNG ${_LANGUAGES})
#Get the flags for this language.
get_property(_FLAGS GLOBAL PROPERTY EMBEDDED_COMPILE_DEFINES_${TARGET}_${_LNG})
#The generator expression below is only supported by the make and ninja
#generators.
assert_generator_is(_GENERATORS_OK "MSYS Makefiles" "MinGW Makefiles" "NMake Makefiles" "NMake Makefiles JOM" "Unix Makefiles" "Watcom WMake" "Ninja")
target_compile_definitions(${TARGET} PRIVATE $<$<COMPILE_LANGUAGE:${_LNG}>:${_FLAGS}>)
endforeach()
endfunction()
#Specify an include path for the compiler affecting a specific build target (all
# languages).
#
# Store include paths for the specified target. PATH is stored in a global
# property. The property name must follow a specific scheme (see outputs).
# See: _embedded_apply_include_directories()
#
#Examples:
# embedded_target_include_directories(TARGET foo PATH "C:/fo/bar/include")
# embedded_target_include_directories(TARGET foo PATH "C:/fo/bar/include" APPEND)
# embedded_target_include_directories(TARGET foo PATH "C:/fo/bar/include" ABSOLUTE)
#
#INPUTS:
# ABSOLUTE - (optional)- whether the path shall be converted to absolute
# APPEND - (optional) - if set append path to existing values
# PATH - (mandatory) - the include path to add
# TARGET - (mandatory) - name of target to apply settings to
#
#OUTPUTS
# Directory property EMBEDDED_COMPILE_INCLUDES_TTT is set, where TTT is
# the target name.
#
function (embedded_target_include_directories)
#Parse our arguments
set( _OPTIONS_ARGS ABSOLUTE APPEND) #Option (on/off) arguments (e.g. IGNORE_CASE)
set( _ONE_VALUE_ARGS PATH TARGET) #Single option arguments (e.g. PATH "./foo/bar")
set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
#Check mandatory parameters
if(NOT _MY_PARAMS_PATH)
failure("embedded_target_include_directories(): Missing PATH parameter!")
endif()
if(NOT _MY_PARAMS_TARGET)
failure("embedded_target_include_directories(): Missing TARGET parameter!")
endif()
if(DEFINED _MY_PARAMS_ABSOLUTE AND ${_MY_PARAMS_ABSOLUTE})
get_filename_component(_MY_PARAMS_PATH ${_MY_PARAMS_PATH} ABSOLUTE)
endif()
if (_MY_PARAMS_APPEND)
set_property(GLOBAL APPEND PROPERTY EMBEDDED_COMPILE_INCLUDES_${_MY_PARAMS_TARGET} ${_MY_PARAMS_PATH})
else()
set_property(GLOBAL PROPERTY EMBEDDED_COMPILE_INCLUDES_${_MY_PARAMS_TARGET} ${_MY_PARAMS_PATH})
endif()
endfunction()
#Apply include path settings for the specified target.
#
# Include paths are stored in a global property and are applied to source files.
# Note:
# - Directory property name must follow a specific scheme.
# - This is an internal function.
#
# See: embedded_target_include_directories()
#
#Examples:
# _embedded_apply_include_directories(my_app)
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# Directory property - (optional) - Flags to apply.
#
#OUTPUTS
# n/a
#
function(_embedded_apply_include_directories TARGET)
#Check if the parameter is a target.
if(NOT TARGET ${TARGET})
message(FATAL_ERROR "_embedded_apply_include_directories(): target '${TARGET}' is not defined.")
endif()
#Get the flags for this language.
get_property(_FLAGS GLOBAL PROPERTY EMBEDDED_COMPILE_INCLUDES_${TARGET})
#If we have flags to apply for this language.
if (NOT _FLAGS STREQUAL "")
target_include_directories(${TARGET} PRIVATE ${_FLAGS})
endif()
endfunction()
#Set linker flags for the specified target.
#
# Store linker flags for the specified target in a global property.
# See: _embedded_apply_link_flags()
#
#Examples:
# embedded_set_target_link_flags(my_app "-M my_map_file.map")
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# FLAGS - (mandatory) - List with the compiler flags.
# APPEND - (optional) - True if FLAGS shall be appended.
#
#OUTPUTS
# Directory property EMBEDDED_LINKER_FLAGS_TTT is set, where TTT is the
# target name.
#
function(embedded_set_target_link_flags)
set( _OPTIONS_ARGS APPEND) #Option (on/off) arguments (e.g. IGNORE_CASE)
set( _ONE_VALUE_ARGS TARGET) #Single option arguments (e.g. PATH "./foo/bar")
set( _MULTI_VALUE_ARGS FLAGS) #List arguments (e.g. LANGUAGES C ASM CXX)
cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
if (NOT DEFINED _MY_PARAMS_TARGET)
message(FATAL_ERROR "embedded_set_target_link_flags(): mandatory parameter 'TARGET' missing.")
endif()
if (NOT DEFINED _MY_PARAMS_FLAGS)
message(FATAL_ERROR "embedded_set_target_link_flags(): mandatory parameter 'FLAGS' missing.")
endif()
if (_MY_PARAMS_APPEND)
set_property(GLOBAL APPEND PROPERTY EMBEDDED_LINKER_FLAGS_${_MY_PARAMS_TARGET} ${_MY_PARAMS_FLAGS})
else()
set_property(GLOBAL PROPERTY EMBEDDED_LINKER_FLAGS_${_MY_PARAMS_TARGET} ${_MY_PARAMS_FLAGS})
endif()
endfunction()
#Apply linker flags for the specified target.
#
# Linker flags stored in a global property are applied.
#
# Note:
# - Directory property name must follow a specific scheme.
# - This is an internal function.
#
# See: embedded_set_target_link_flags()
#
#Examples:
# _embedded_apply_link_flags(my_app)
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# Directory property - (optional) - Flags to apply.
#
#OUTPUTS
# n/a
#
function(_embedded_apply_link_flags TARGET)
#Check if the parameter is a target.
if(NOT TARGET ${TARGET})
message(FATAL_ERROR "_embedded_apply_link_flags(): target '${TARGET}' is not defined.")
endif()
#Get the stored flags.
get_property(_FLAGS GLOBAL PROPERTY EMBEDDED_LINKER_FLAGS_${TARGET})
#Apply flags if defined.
if (NOT _FLAGS STREQUAL "")
list_to_string(_STR_FLAGS ${_FLAGS})
set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS ${_STR_FLAGS})
endif()
endfunction()
#Set linker command file for the specified target.
#
# Store path to linker command file for the specified target in a global
# property.
#
# See: _embedded_apply_linker_cmd_file_setting()
#
#Examples:
# embedded_set_target_linker_file(my_app "foo/my_linker_cmd.sct")
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# PATH - (mandatory) - Path to linker script.
#
#OUTPUTS
# Directory property EMBEDDED_LINKER_CMD_FILE_TTT is set, where TTT is the
# target name.
#
function(embedded_set_target_linker_file)
set( _OPTIONS_ARGS ) #Option (on/off) arguments (e.g. IGNORE_CASE)
set( _ONE_VALUE_ARGS TARGET PATH) #Single option arguments (e.g. PATH "./foo/bar")
set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
if (NOT DEFINED _MY_PARAMS_TARGET)
message(FATAL_ERROR "embedded_set_target_linker_file(): mandatory parameter 'TARGET' missing.")
endif()
if (NOT DEFINED _MY_PARAMS_PATH)
message(FATAL_ERROR "embedded_set_target_linker_file(): mandatory parameter 'PATH' missing.")
endif()
set_property(GLOBAL PROPERTY EMBEDDED_LINKER_CMD_FILE_${_MY_PARAMS_TARGET} ${_MY_PARAMS_PATH})
endfunction()
#Apply linker linker command file setting for the specified target.
#
# Path to linker command file stored in a global property is applied.
#
# Note:
# - Directory property name must follow a specific scheme.
# - This is an internal function.
#
# See: embedded_set_target_linker_file()
#
#Examples:
# _embedded_apply_linker_cmd_file_setting(my_app)
#
#INPUTS:
# TARGET - (mandatory) - The target to apply settings to.
# Directory property - (optional) - Flags to apply.
#
#OUTPUTS
# n/a
#
function(_embedded_apply_linker_cmd_file_setting TARGET)
#Check if the parameter is a target.
if(NOT TARGET ${TARGET})
message(FATAL_ERROR "_embedded_apply_linker_cmd_file_setting(): target '${TARGET}' is not defined.")
endif()
#Check if target is an executable.
get_property(_TGT_TYPE TARGET ${TARGET} PROPERTY TYPE)
if(NOT _TGT_TYPE STREQUAL "EXECUTABLE")
message(FATAL_ERROR "_embedded_apply_linker_cmd_file_setting(): target '${TARGET}' is not an executable.")
endif()
#Check if executable has a linker command file set.
get_property(_LINKER_CMD_FILE GLOBAL PROPERTY EMBEDDED_LINKER_CMD_FILE_${TARGET} SET)
if (NOT _LINKER_CMD_FILE)
message(FATAL_ERROR "_embedded_apply_linker_cmd_file_setting(): Please set linker command file for target '${TARGET}' using embedded_set_target_linker_file().")
endif()
#Get the path to the linker command file.
get_property(_LINKER_CMD_FILE GLOBAL PROPERTY EMBEDDED_LINKER_CMD_FILE_${TARGET})
#Set the path
compiler_set_linkercmdfile(${TARGET} ${_LINKER_CMD_FILE})
endfunction()