blob: 741042c14300e2dc7f0d10d9dc8362b2ff924882 [file] [log] [blame]
Gyorgy Szing30fa9872017-12-05 01:08:47 +00001#-------------------------------------------------------------------------------
Gyorgy Szing964c7d82019-04-11 15:16:09 +02002# Copyright (c) 2017-2019, Arm Limited. All rights reserved.
Gyorgy Szing30fa9872017-12-05 01:08:47 +00003#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6#-------------------------------------------------------------------------------
7
8#This file defines project-specific overrides to cmake default behaviour for:
9# * compiler detection
10# * target system detection
11cmake_minimum_required(VERSION 3.3) #IN_LIST was introduced in 3.3
12cmake_policy(SET CMP0057 NEW)
13
14Include(CMakeParseArguments)
15
16#The CMAKE_SYSTEM_XXX settings make cmake to stop applying some target system specific settings.
17#Tell cmake we are compiling for ARM chips.
18set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE INTERNAL "Set target processor type to force cmake include some of our scripts." FORCE)
19#Tell cmake this is an "Embedded" system
20set(CMAKE_SYSTEM_NAME "Embedded" CACHE INTERNAL "Set target system name to force cmake include some of our scripts." FORCE)
21
22#Stop built in CMakeDetermine<lang>.cmake scripts to run.
23set (CMAKE_CXX_COMPILER_ID_RUN 1)
24#Stop cmake run compiler tests.
25set (CMAKE_CXX_COMPILER_FORCED true)
26#Stop built in CMakeDetermine<lang>.cmake scripts to run.
27set (CMAKE_C_COMPILER_ID_RUN 1)
28#Stop cmake run compiler tests.
29set (CMAKE_C_COMPILER_FORCED true)
30
31#This macro is used to enforce the ARM project structure.
32#Inputs: (This macro uses some "global" variables)
33# global variable PROJ_CONFIG - a global configuration file to be used by all projects.
34# It overrides value of CONFIG parameter.
35# CONFIG - the configuration file which shall be used
36#Examples
37# To use global project config:
38# embedded_project_start()
39# To use config file relative to the top level CmakeLists.txt:
Ken Liue40f9a22019-06-03 16:42:47 +080040# embedded_project_start(./configs/ConfigDefault.cmake)
Gyorgy Szing30fa9872017-12-05 01:08:47 +000041# To use config file relative to the CmakeLists.txt file where this macro is used:
Ken Liue40f9a22019-06-03 16:42:47 +080042# embedded_project_start(${TFM_ROOT_DIR}/configs/ConfigDefault.cmake)
Gyorgy Szing30fa9872017-12-05 01:08:47 +000043macro(embedded_project_start)
44 #Default project configuration file
45 if (DEFINED PROJ_CONFIG) #Take the global setting as default value
46 set(_PROJ_CONFIG ${PROJ_CONFIG})
47 endif()
48
49 set( _OPTIONS_ARGS ) #No option (on/off) arguments
Mate Toth-Pal76867262018-03-09 13:15:36 +010050 set( _ONE_VALUE_ARGS CONFIG) #Single option arguments (e.g. PROJ_NAME "bubu_project")
51 set( _MULTI_VALUE_ARGS ) #One list argument (e.g. LANGUAGES C ASM CXX)
52 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
Gyorgy Szing30fa9872017-12-05 01:08:47 +000053
Ken Liue40f9a22019-06-03 16:42:47 +080054 #Check passed parameters
Gyorgy Szing30fa9872017-12-05 01:08:47 +000055 if(NOT _MY_PARAMS_CONFIG)
56 if(NOT DEFINED _PROJ_CONFIG)
Ken Liue40f9a22019-06-03 16:42:47 +080057 set(_PROJ_CONFIG "${TFM_ROOT_DIR}/configs/ConfigDefault.cmake")
Gyorgy Szing30fa9872017-12-05 01:08:47 +000058 message(STATUS "embedded_project_start: no project configuration file defined, falling back to default.")
59 endif()
60 elseif(NOT DEFINED PROJ_CONFIG)
61 set(_PROJ_CONFIG ${_MY_PARAMS_CONFIG})
62 endif()
63
64 get_filename_component(_ABS_PROJ_CONFIG ${_PROJ_CONFIG} ABSOLUTE)
Ken Liue40f9a22019-06-03 16:42:47 +080065 message(STATUS "embedded_project_start: using project specific config file (PROJ_CONFIG = ${_ABS_PROJ_CONFIG})")
Gyorgy Szing30fa9872017-12-05 01:08:47 +000066 include("${_PROJ_CONFIG}")
67endmacro()
68
69#Override CMake default behaviour
70macro(embedded_project_fixup)
71 get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
Gyorgy Szing30fa9872017-12-05 01:08:47 +000072
73 #Merge CPU and configuration specific compiler and linker flags.
74 foreach(LNG ${languages})
Gyorgy Szing964c7d82019-04-11 15:16:09 +020075 include(Common/CompilerDetermine${LNG})
76 #since all CMake "built in" scripts already executed, we need fo fix up some things here.
77 embedded_fixup_build_type_vars(${LNG})
78
Gyorgy Szing30fa9872017-12-05 01:08:47 +000079 #Apply CPU specific and configuration specific compile flags.
80 if(NOT CMAKE_${LNG}_FLAGS MATCHES ".*${CMAKE_${LNG}_FLAGS_CPU}.*")
81 set(CMAKE_${LNG}_FLAGS "${CMAKE_${LNG}_FLAGS} ${CMAKE_${LNG}_FLAGS_CPU}")
82 endif()
83 #Fix output file extension.
84 set (CMAKE_EXECUTABLE_SUFFIX_${LNG} ".axf")
85 unset(ALL_SRC_${LNG})
86 unset(ALL_SRC_${LNG}_S)
87 unset(ALL_SRC_${LNG}_NS)
88 endforeach()
89 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_LINK_FLAGS_CPU}")
90endmacro()
91
92#Allow project specific script to do configuration after all targets are specified; it has to be done for each target defined
93macro (embedded_project_end TARGET)
94 get_property(_MAC DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY MACROS)
95 if ("embedded_project_build_config_apply" IN_LIST _MAC)
96 message(WARNING "embedded_project_end(): macro embedded_project_build_config_apply() is defined. Your build config file may be out-dated.")
97 endif()
98
99 #Apply compile flags.
100 _embedded_apply_compile_flags(${TARGET})
101 #Apply macro definitions
102 _embedded_apply_compile_defines(${TARGET})
103 #Apply include paths
104 _embedded_apply_include_directories(${TARGET})
105 #Apply linker flags.
106 _embedded_apply_link_flags(${TARGET})
107 #If target is executable, apply linker command file setting.
108 get_property(_TGT_TYPE TARGET ${TARGET} PROPERTY TYPE)
109 if(_TGT_TYPE STREQUAL "EXECUTABLE")
110 _embedded_apply_linker_cmd_file_setting(${TARGET})
111 endif()
112endmacro()
113
114macro(embedded_fixup_build_type_vars LANG)
115 #since all CMake "built in" scripts already executed, we need fo fix up some things here.
Gyorgy Szing964c7d82019-04-11 15:16:09 +0200116 set (CMAKE_${LANG}_FLAGS_DEBUG "${CMAKE_${LANG}_FLAGS_DEBUG_INIT}" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
117 set (CMAKE_${LANG}_FLAGS_MINSIZEREL "${CMAKE_${LANG}_FLAGS_MINSIZEREL_INIT}" CACHE STRING "Flags used by the compiler during release builds for minimum size." FORCE)
118 set (CMAKE_${LANG}_FLAGS_RELEASE "${CMAKE_${LANG}_FLAGS_RELEASE_INIT}" CACHE STRING "Flags used by the compiler during release builds." FORCE)
119 set (CMAKE_${LANG}_FLAGS_RELWITHDEBINFO "${CMAKE_${LANG}_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING "Flags used by the compiler during release builds with debug info." FORCE)
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000120endmacro()
121
122
123#Convert a CMake list to a string
124#
125#Examples:
126# list_to_string(my_string 1 2 3 4)
127# list_to_string(my_string ${CMAKE_C_FLAGS})
128#
129#INPUTS:
130# RES - (mandatory) - name of variable to put result in
131# The list to be converted.
132#
133#OUTPUTS
134# List items concatenated to a string.
135#
136function(list_to_string RES)
137 foreach(_ITEM ${ARGN})
138 set(_RES "${_RES} ${_ITEM}")
139 endforeach()
140 set(${RES} "${_RES}" PARENT_SCOPE)
141endfunction()
142
143#Ensure current generator is supported.
144#
145# This function takes a list of supported generators (e.g. "Unix Makefiles") and
146# exits with fatal error is the current generator is not on the list.
147#Examples:
148# assert_generator_is("MSYS Makefiles" "MinGW Makefiles")
149#
150#INPUTS:
151# The list of supported generators.
152#
153#OUTPUTS
154# n/a
155#
156function(assert_generator_is)
157 if (NOT CMAKE_GENERATOR IN_LIST ARGN)
158 message(FATAL_ERROR "assert_generator_is(): Generator '${CMAKE_GENERATOR}' is not on the list of supported generators.")
159 endif()
160endfunction()
161
David Vincze54d05552019-08-05 12:58:47 +0200162#Check the value of a cache variable whether it is valid.
163#
164# This function currently only supports 'STRING' type variables and uses
165# the 'STRINGS' cache entry property as the validation list.
166#
167#Examples:
168# validate_cache_value(MCUBOOT_SIGNATURE_TYPE)
169#
170#INPUTS:
171# variable_name - (mandatory) - Name of the cache variable to be checked.
172#
173#OUTPUTS:
174# n/a
175#
176function(validate_cache_value variable_name)
177 #Check if the type of the variable is STRING.
178 get_property(_type CACHE ${variable_name} PROPERTY TYPE)
179 if(NOT ${_type} STREQUAL "STRING")
180 message(FATAL_ERROR "validate_cache_value: type of CACHE variable must be 'STRING', the type of '${variable_name}' variable is '${_type}'.")
181 endif()
182 get_property(_validation_list CACHE ${variable_name} PROPERTY STRINGS)
183 #Check if validation list is set.
184 if (NOT _validation_list)
185 message(FATAL_ERROR "validate_cache_value: CACHE variable '${variable_name}' has no 'STRINGS' validation list set.")
186 endif()
187 #See if the value of the variable is in the list.
188 if (NOT ${${variable_name}} IN_LIST _validation_list)
189 message(FATAL_ERROR "validate_cache_value: variable value '${${variable_name}}' of variable '${variable_name}' is not matching the validation list ${_validation_list}.")
190 endif()
191endfunction()
192
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000193#Specify an include path for the compiler
194#
195# Specify a global include directory for all non external targets in the current
196# build.
197# The parameter ABSOLUTE can be set to true to ask CMake to convert the PATH to
198# absolute. This gives better looking command line arguments, and also helps
199# removing duplicates.
200#
201#Examples:
202# embedded_include_directories(PATH "C:/fo/bar/include")
203# embedded_include_directories(PATH "C:/fo/bar/include" ABSOLUTE)
204#
205#INPUTS:
206# PATH - (mandatory) - the include path to add
207# ABSOLUTE - (optional) - whether the path shall be converted to absolute
208#
209#OUTPUTS
210# Modified list of include directories.
211#
212function (embedded_include_directories)
213 #Parse our arguments
214 set( _OPTIONS_ARGS ABSOLUTE) #Option (on/off) arguments (e.g. IGNORE_CASE)
215 set( _ONE_VALUE_ARGS PATH) #Single option arguments (e.g. PATH "./foo/bar")
216 set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
217 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
218
219 #Check mandatory parameters
220 if(NOT _MY_PARAMS_PATH)
221 failure("embedded_include_directories(): Missing PATH parameter!")
222 endif()
223
224 if(DEFINED _MY_PARAMS_ABSOLUTE AND ${_MY_PARAMS_ABSOLUTE})
225 get_filename_component(_MY_PARAMS_PATH ${_MY_PARAMS_PATH} ABSOLUTE)
226 endif()
227
228 include_directories(${_MY_PARAMS_PATH})
229endfunction()
230
231#Return the language of a source file.
232#
233# Language is either specified by the LANGUAGE property of the source file or
234# determined based on the extension of the file.
235# Search is limited for languages enabled in the current project.
236#
237#Examples:
238# To get language of "foo/bar.c" written into _LNG:
239# embedded_get_source_language("foo/bar.c" _LNG)
240#
241#INPUTS:
242# FILE - (mandatory) - The file to determine language of.
243# RES - (mandatory) - Name of the variable to write the result into.
244#
245#OUTPUTS
246# ${RES} - language string (e.g. "C", "CXX", "ASM"). empty string for files
247# with no language.
248#
249function(embedded_get_source_language FILE RES)
250 if (ARGN)
251 message(FATAL_ERROR "embedded_get_source_language(): too many parameters passed.")
252 endif()
253 #If language property is set, use that.
254 get_property(_LNG SOURCE ${_SRC} PROPERTY LANGUAGE)
255 if (NOT ${_LNG} STREQUAL "")
256 set(${RES} ${_LNG} PARENT_SCOPE)
257 else()
258 #Set empty return value.
259 set(${RES} "" PARENT_SCOPE)
260 #Property not set, use extension of the file to determine
261 #language.
262 string(REGEX MATCH "[^.]*$" _EXT "${_SRC}")
263 #Get list of enabled languages.
264 get_property(_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
265 foreach(_LNG ${_LANGUAGES})
266 #See if the extension is contained in the list of file extensions
267 #of this language.
268 if(_EXT IN_LIST CMAKE_${_LNG}_SOURCE_FILE_EXTENSIONS)
269 set(${RES} ${_LNG} PARENT_SCOPE)
270 break()
271 endif()
272 endforeach()
273 endif()
274endfunction()
275
276#Set compilation flags for the specified target.
277#
278# Store compilation flags for the specified target and language pair. Flags are
279# stored in a global property and will
280# be applied to source files in the current directory and sub-directories.
281# Property name must follow a specific scheme (see outputs).
282# See: _embedded_apply_compile_flags()
283#
284#Examples:
285# embedded_set_target_compile_flags(my_app C "-fchar-unsigned")
286# embedded_set_target_compile_flags(my_lib CXX "-fchar-unsigned")
287# embedded_set_target_compile_flags(my_app ASM "-fchar-unsigned")
288#
289#INPUTS:
290# TARGET - (mandatory) - The target to apply settings to.
291# LANGUAGE - (mandatory) - Programming language of source files settings shall
292# be applied to.
293# FLAGS - (mandatory) - List with the compiler flags.
294# APPEND - (optional) - True if FLAGS shall be appended.
295#
296#OUTPUTS
297# Directory property EMBEDDED_COMPILE_FLAGS_TTT_LLL is set, where TTT is the
298# target name, and LLL is the language.
299#
300function (embedded_set_target_compile_flags)
301 set( _OPTIONS_ARGS APPEND) #Option (on/off) arguments (e.g. IGNORE_CASE)
302 set( _ONE_VALUE_ARGS TARGET LANGUAGE) #Single option arguments (e.g. PATH "./foo/bar")
303 set( _MULTI_VALUE_ARGS FLAGS) #List arguments (e.g. LANGUAGES C ASM CXX)
304 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
305
306 if (NOT DEFINED _MY_PARAMS_TARGET)
307 message(FATAL_ERROR "embedded_set_target_compile_flags(): mandatory parameter 'TARGET' missing.")
308 endif()
309
310 if (NOT DEFINED _MY_PARAMS_LANGUAGE)
311 message(FATAL_ERROR "embedded_set_target_compile_flags(): mandatory parameter 'LANGUAGE' missing.")
312 endif()
313
314 if (NOT DEFINED _MY_PARAMS_FLAGS)
315 message(FATAL_ERROR "embedded_set_target_compile_flags(): mandatory parameter 'FLAGS' missing.")
316 endif()
317
318 if (_MY_PARAMS_APPEND)
319 set_property(GLOBAL APPEND PROPERTY EMBEDDED_COMPILE_FLAGS_${_MY_PARAMS_TARGET}_${_MY_PARAMS_LANGUAGE} ${_MY_PARAMS_FLAGS})
320 else()
321 set_property(GLOBAL PROPERTY EMBEDDED_COMPILE_FLAGS_${_MY_PARAMS_TARGET}_${_MY_PARAMS_LANGUAGE} ${_MY_PARAMS_FLAGS})
322 endif()
323endfunction()
324
325#Apply compilation flag settings for the specified target.
326#
327# Compilation flags stored in a global property and are applied to source files.
328# Note:
329# - Directory property name must follow a specific scheme.
330# - This is an internal function.
331# - This function only supports make and ninja generators.
332#
333# See: embedded_set_target_compile_flags()
334#
335#Examples:
336# _embedded_apply_compile_flags(my_app)
337#
338#INPUTS:
339# TARGET - (mandatory) - The target to apply settings to.
340# Directory property - (optional) - Flags to apply.
341#
342#OUTPUTS
343# n/a
344#
345function(_embedded_apply_compile_flags TARGET)
346 #Check if the parameter is a target.
347 if(NOT TARGET ${TARGET})
348 message(FATAL_ERROR "_embedded_apply_compile_flags(): target '${TARGET}' is not defined.")
349 endif()
350 #Get list of enabled languages.
351 get_property(_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
352 foreach(_LNG ${_LANGUAGES})
353 #Get the flags for this language.
354 get_property(_FLAGS GLOBAL PROPERTY EMBEDDED_COMPILE_FLAGS_${TARGET}_${_LNG})
355
356 #The generator expression below is only supported by the make and ninja
357 #generators.
358 assert_generator_is(_GENERATORS_OK "MSYS Makefiles" "MinGW Makefiles" "NMake Makefiles" "NMake Makefiles JOM" "Unix Makefiles" "Watcom WMake" "Ninja")
359 target_compile_options(${TARGET} PRIVATE $<$<COMPILE_LANGUAGE:${_LNG}>:${_FLAGS}>)
360 endforeach()
361endfunction()
362
363#Set compilation defines for the specified target.
364#
365# Store compilation defines for the specified target and language pair. Macros
366# are stored in a global property and will
367# be applied to source files in the current directory and sub-directories.
368# Property name must follow a specific scheme (see outputs).
369# See: _embedded_apply_compile_defines()
370#
371#Examples:
372# embedded_set_target_compile_defines(my_app C "FOO BAR=1")
373# embedded_set_target_compile_defines(my_lib CXX "FOO BAR=1")
374# embedded_set_target_compile_defines(my_app ASM "FOO BAR=1")
375#
376#INPUTS:
377# TARGET - (mandatory) - The target to apply settings to.
378# LANGUAGE - (mandatory) - Programming language of source files settings shall
379# be applied to.
380# DEFINES - (mandatory) - List with the compiler flags.
381# APPEND - (optional) - Present if FLAGS shall be appended.
382#
383#OUTPUTS
384# Directory property EMBEDDED_COMPILE_DEFINES_TTT_LLL is set, where TTT is the
385# target name, and LLL is the language.
386#
387function (embedded_set_target_compile_defines)
388 set( _OPTIONS_ARGS APPEND) #Option (on/off) arguments (e.g. IGNORE_CASE)
389 set( _ONE_VALUE_ARGS TARGET LANGUAGE) #Single option arguments (e.g. PATH "./foo/bar")
390 set( _MULTI_VALUE_ARGS DEFINES) #List arguments (e.g. LANGUAGES C ASM CXX)
391 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
392
393 if (NOT DEFINED _MY_PARAMS_TARGET)
394 message(FATAL_ERROR "embedded_set_target_compile_defines(): mandatory parameter 'TARGET' missing.")
395 endif()
396
397 if (NOT DEFINED _MY_PARAMS_LANGUAGE)
398 message(FATAL_ERROR "embedded_set_target_compile_defines(): mandatory parameter 'LANGUAGE' missing.")
399 endif()
400
401 if (NOT DEFINED _MY_PARAMS_DEFINES)
402 message(FATAL_ERROR "embedded_set_target_compile_defines(): mandatory parameter 'DEFINES' missing.")
403 endif()
404
405 if (_MY_PARAMS_APPEND)
406 set_property(GLOBAL APPEND PROPERTY EMBEDDED_COMPILE_DEFINES_${_MY_PARAMS_TARGET}_${_MY_PARAMS_LANGUAGE} ${_MY_PARAMS_DEFINES})
407 else()
408 set_property(GLOBAL PROPERTY EMBEDDED_COMPILE_DEFINES_${_MY_PARAMS_TARGET}_${_MY_PARAMS_LANGUAGE} ${_MY_PARAMS_DEFINES})
409 endif()
410endfunction()
411
412#Apply compilation defines for the specified target.
413#
414# Macro definitions are stored in a global property and are applied to
415# source files.
416#
417# Note:
418# - Directory property name must follow a specific scheme.
419# - This is an internal function.
420# - This function only supports make and ninja generators.
421#
422# See: embedded_set_target_compile_defines()
423#
424#Examples:
425# _embedded_apply_compile_defines(my_app)
426#
427#INPUTS:
428# TARGET - (mandatory) - The target to apply settings to.
429# Directory property - (optional) - Flags to apply.
430#
431#OUTPUTS
432# n/a
433#
434function(_embedded_apply_compile_defines TARGET)
435 #Check if the parameter is a target.
436 if(NOT TARGET ${TARGET})
437 message(FATAL_ERROR "_embedded_apply_compile_defines(): target '${TARGET}' is not defined.")
438 endif()
439 #Get list of enabled languages.
440 get_property(_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
441 foreach(_LNG ${_LANGUAGES})
442 #Get the flags for this language.
443 get_property(_FLAGS GLOBAL PROPERTY EMBEDDED_COMPILE_DEFINES_${TARGET}_${_LNG})
444 #The generator expression below is only supported by the make and ninja
445 #generators.
446 assert_generator_is(_GENERATORS_OK "MSYS Makefiles" "MinGW Makefiles" "NMake Makefiles" "NMake Makefiles JOM" "Unix Makefiles" "Watcom WMake" "Ninja")
447 target_compile_definitions(${TARGET} PRIVATE $<$<COMPILE_LANGUAGE:${_LNG}>:${_FLAGS}>)
448 endforeach()
449endfunction()
450
451#Specify an include path for the compiler affecting a specific build target (all
452# languages).
453#
454# Store include paths for the specified target. PATH is stored in a global
455# property. The property name must follow a specific scheme (see outputs).
456# See: _embedded_apply_include_directories()
457#
458#Examples:
459# embedded_target_include_directories(TARGET foo PATH "C:/fo/bar/include")
460# embedded_target_include_directories(TARGET foo PATH "C:/fo/bar/include" APPEND)
461# embedded_target_include_directories(TARGET foo PATH "C:/fo/bar/include" ABSOLUTE)
462#
463#INPUTS:
464# ABSOLUTE - (optional)- whether the path shall be converted to absolute
465# APPEND - (optional) - if set append path to existing values
466# PATH - (mandatory) - the include path to add
467# TARGET - (mandatory) - name of target to apply settings to
468#
469#OUTPUTS
470# Directory property EMBEDDED_COMPILE_INCLUDES_TTT is set, where TTT is
471# the target name.
472#
473function (embedded_target_include_directories)
474 #Parse our arguments
475 set( _OPTIONS_ARGS ABSOLUTE APPEND) #Option (on/off) arguments (e.g. IGNORE_CASE)
476 set( _ONE_VALUE_ARGS PATH TARGET) #Single option arguments (e.g. PATH "./foo/bar")
477 set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
478 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
479
480 #Check mandatory parameters
481 if(NOT _MY_PARAMS_PATH)
482 failure("embedded_target_include_directories(): Missing PATH parameter!")
483 endif()
484
485 if(NOT _MY_PARAMS_TARGET)
486 failure("embedded_target_include_directories(): Missing TARGET parameter!")
487 endif()
488
489 if(DEFINED _MY_PARAMS_ABSOLUTE AND ${_MY_PARAMS_ABSOLUTE})
490 get_filename_component(_MY_PARAMS_PATH ${_MY_PARAMS_PATH} ABSOLUTE)
491 endif()
492
493 if (_MY_PARAMS_APPEND)
494 set_property(GLOBAL APPEND PROPERTY EMBEDDED_COMPILE_INCLUDES_${_MY_PARAMS_TARGET} ${_MY_PARAMS_PATH})
495 else()
496 set_property(GLOBAL PROPERTY EMBEDDED_COMPILE_INCLUDES_${_MY_PARAMS_TARGET} ${_MY_PARAMS_PATH})
497 endif()
498endfunction()
499
500#Apply include path settings for the specified target.
501#
502# Include paths are stored in a global property and are applied to source files.
503# Note:
504# - Directory property name must follow a specific scheme.
505# - This is an internal function.
506#
507# See: embedded_target_include_directories()
508#
509#Examples:
510# _embedded_apply_include_directories(my_app)
511#
512#INPUTS:
513# TARGET - (mandatory) - The target to apply settings to.
514# Directory property - (optional) - Flags to apply.
515#
516#OUTPUTS
517# n/a
518#
519function(_embedded_apply_include_directories TARGET)
520 #Check if the parameter is a target.
521 if(NOT TARGET ${TARGET})
522 message(FATAL_ERROR "_embedded_apply_include_directories(): target '${TARGET}' is not defined.")
523 endif()
524 #Get the flags for this language.
525 get_property(_FLAGS GLOBAL PROPERTY EMBEDDED_COMPILE_INCLUDES_${TARGET})
526 #If we have flags to apply for this language.
527 if (NOT _FLAGS STREQUAL "")
528 target_include_directories(${TARGET} PRIVATE ${_FLAGS})
529 endif()
530endfunction()
531
532#Set linker flags for the specified target.
533#
534# Store linker flags for the specified target in a global property.
535# See: _embedded_apply_link_flags()
536#
537#Examples:
538# embedded_set_target_link_flags(my_app "-M my_map_file.map")
539#
540#INPUTS:
541# TARGET - (mandatory) - The target to apply settings to.
542# FLAGS - (mandatory) - List with the compiler flags.
543# APPEND - (optional) - True if FLAGS shall be appended.
544#
545#OUTPUTS
546# Directory property EMBEDDED_LINKER_FLAGS_TTT is set, where TTT is the
547# target name.
548#
549function(embedded_set_target_link_flags)
550 set( _OPTIONS_ARGS APPEND) #Option (on/off) arguments (e.g. IGNORE_CASE)
551 set( _ONE_VALUE_ARGS TARGET) #Single option arguments (e.g. PATH "./foo/bar")
552 set( _MULTI_VALUE_ARGS FLAGS) #List arguments (e.g. LANGUAGES C ASM CXX)
553 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
554
555 if (NOT DEFINED _MY_PARAMS_TARGET)
556 message(FATAL_ERROR "embedded_set_target_link_flags(): mandatory parameter 'TARGET' missing.")
557 endif()
558
559 if (NOT DEFINED _MY_PARAMS_FLAGS)
560 message(FATAL_ERROR "embedded_set_target_link_flags(): mandatory parameter 'FLAGS' missing.")
561 endif()
562
563 if (_MY_PARAMS_APPEND)
564 set_property(GLOBAL APPEND PROPERTY EMBEDDED_LINKER_FLAGS_${_MY_PARAMS_TARGET} ${_MY_PARAMS_FLAGS})
565 else()
566 set_property(GLOBAL PROPERTY EMBEDDED_LINKER_FLAGS_${_MY_PARAMS_TARGET} ${_MY_PARAMS_FLAGS})
567 endif()
568endfunction()
569
570#Apply linker flags for the specified target.
571#
572# Linker flags stored in a global property are applied.
573#
574# Note:
575# - Directory property name must follow a specific scheme.
576# - This is an internal function.
577#
578# See: embedded_set_target_link_flags()
579#
580#Examples:
581# _embedded_apply_link_flags(my_app)
582#
583#INPUTS:
584# TARGET - (mandatory) - The target to apply settings to.
585# Directory property - (optional) - Flags to apply.
586#
587#OUTPUTS
588# n/a
589#
590function(_embedded_apply_link_flags TARGET)
591 #Check if the parameter is a target.
592 if(NOT TARGET ${TARGET})
593 message(FATAL_ERROR "_embedded_apply_link_flags(): target '${TARGET}' is not defined.")
594 endif()
595 #Get the stored flags.
596 get_property(_FLAGS GLOBAL PROPERTY EMBEDDED_LINKER_FLAGS_${TARGET})
597 #Apply flags if defined.
598 if (NOT _FLAGS STREQUAL "")
599 list_to_string(_STR_FLAGS ${_FLAGS})
600 set_property(TARGET ${TARGET} APPEND_STRING PROPERTY LINK_FLAGS ${_STR_FLAGS})
601 endif()
602endfunction()
603
604#Set linker command file for the specified target.
605#
606# Store path to linker command file for the specified target in a global
607# property.
608#
609# See: _embedded_apply_linker_cmd_file_setting()
610#
611#Examples:
Mate Toth-Pal76867262018-03-09 13:15:36 +0100612# embedded_set_target_linker_file(TARGET my_app PATH "foo/my_linker_cmd.sct")
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000613#
614#INPUTS:
Mate Toth-Pal76867262018-03-09 13:15:36 +0100615# TARGET - (mandatory) - The target to apply settings to.
616# PATH - (mandatory) - Path to linker script.
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000617#
618#OUTPUTS
Mate Toth-Pal76867262018-03-09 13:15:36 +0100619# Directory property EMBEDDED_LINKER_CMD_FILE_TTT is set, where TTT is the
620# target name.
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000621#
622function(embedded_set_target_linker_file)
623 set( _OPTIONS_ARGS ) #Option (on/off) arguments (e.g. IGNORE_CASE)
624 set( _ONE_VALUE_ARGS TARGET PATH) #Single option arguments (e.g. PATH "./foo/bar")
625 set( _MULTI_VALUE_ARGS ) #List arguments (e.g. LANGUAGES C ASM CXX)
626 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
627
628 if (NOT DEFINED _MY_PARAMS_TARGET)
629 message(FATAL_ERROR "embedded_set_target_linker_file(): mandatory parameter 'TARGET' missing.")
630 endif()
631
632 if (NOT DEFINED _MY_PARAMS_PATH)
633 message(FATAL_ERROR "embedded_set_target_linker_file(): mandatory parameter 'PATH' missing.")
634 endif()
635
636 set_property(GLOBAL PROPERTY EMBEDDED_LINKER_CMD_FILE_${_MY_PARAMS_TARGET} ${_MY_PARAMS_PATH})
637endfunction()
638
Mate Toth-Pal76867262018-03-09 13:15:36 +0100639#Set pre-processor defines for the linker command file.
640#
641# Store preprocessor defines for the linker command file of the specified target
642# in a global property.
643#
644# See: _embedded_apply_linker_cmd_file_setting()
645#
646#Examples:
647# embedded_set_target_link_defines(my_app "BL2=1" "USE_TLS=1")
648#
649#INPUTS:
650# TARGET - (mandatory) - The target to apply settings to.
651# DEFINES - (mandatory) - List of macro value definitions.
652#
653#OUTPUTS
654# Directory property EMBEDDED_LINKER_DEFINES_TTT is set, where TTT is the
655# target name.
656#
657function(embedded_set_target_link_defines)
658 set( _OPTIONS_ARGS ) #Option (on/off) arguments (e.g. IGNORE_CASE)
David Vinczea3e84c72019-06-27 16:33:08 +0200659 set( _ONE_VALUE_ARGS TARGET) #Single option arguments (e.g. PATH "./foo/bar")
660 set( _MULTI_VALUE_ARGS DEFINES) #List arguments (e.g. LANGUAGES C ASM CXX)
Mate Toth-Pal76867262018-03-09 13:15:36 +0100661 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
662
663 if (NOT DEFINED _MY_PARAMS_TARGET)
664 message(FATAL_ERROR "embedded_set_target_link_defines(): mandatory parameter 'TARGET' missing.")
665 endif()
666
667 if (NOT DEFINED _MY_PARAMS_DEFINES)
668 message(FATAL_ERROR "embedded_set_target_link_defines(): mandatory parameter 'DEFINES' missing.")
669 endif()
670
671 set_property(GLOBAL APPEND PROPERTY EMBEDDED_LINKER_DEFINES_${_MY_PARAMS_TARGET} ${_MY_PARAMS_DEFINES})
672endfunction()
673
674
675#Set pre-processor include paths for the linker command file.
676#
677# Store preprocessor include paths for the linker command file of the specified
678# target in a global property.
679#
680# See: _embedded_apply_linker_cmd_file_setting()
681#
682#Examples:
683# embedded_set_target_link_includes(my_app "c:/foo" "../bar")
684#
685#INPUTS:
686# TARGET - (mandatory) - The target to apply settings to.
687# INCLUDES - (mandatory) - List of include paths.
688#
689#OUTPUTS
690# Directory property EMBEDDED_LINKER_INCLUDES_TTT is set, where TTT is the
691# target name.
692#
693function(embedded_set_target_link_includes)
694 set( _OPTIONS_ARGS ) #Option (on/off) arguments (e.g. IGNORE_CASE)
Gabor Kerteszfffaafb2018-06-27 17:13:13 +0200695 set( _ONE_VALUE_ARGS TARGET) #Single option arguments (e.g. PATH "./foo/bar")
696 set( _MULTI_VALUE_ARGS INCLUDES) #List arguments (e.g. LANGUAGES C ASM CXX)
Mate Toth-Pal76867262018-03-09 13:15:36 +0100697 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
698
699 if (NOT DEFINED _MY_PARAMS_TARGET)
700 message(FATAL_ERROR "embedded_set_target_link_includes(): mandatory parameter 'TARGET' missing.")
701 endif()
702
Gabor Kerteszfffaafb2018-06-27 17:13:13 +0200703 if (NOT DEFINED _MY_PARAMS_INCLUDES)
704 message(FATAL_ERROR "embedded_set_target_link_includes(): mandatory parameter 'INCLUDES' missing.")
Mate Toth-Pal76867262018-03-09 13:15:36 +0100705 endif()
706
Gabor Kerteszfffaafb2018-06-27 17:13:13 +0200707 set_property(GLOBAL APPEND PROPERTY EMBEDDED_LINKER_INCLUDES_${_MY_PARAMS_TARGET} ${_MY_PARAMS_INCLUDES})
Mate Toth-Pal76867262018-03-09 13:15:36 +0100708endfunction()
709
710
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000711#Apply linker linker command file setting for the specified target.
712#
Mate Toth-Pal76867262018-03-09 13:15:36 +0100713# Path to linker command file, macro definitions and include paths stored in
714# global properties are applied.
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000715#
716# Note:
Mate Toth-Pal76867262018-03-09 13:15:36 +0100717# - Directory property names must follow a specific scheme.
718# - This is an internal function.
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000719#
Mate Toth-Pal76867262018-03-09 13:15:36 +0100720# See: embedded_set_target_linker_file(), embedded_set_target_link_includes()
721# embedded_set_target_link_defines()
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000722#
723#Examples:
724# _embedded_apply_linker_cmd_file_setting(my_app)
725#
726#INPUTS:
Mate Toth-Pal76867262018-03-09 13:15:36 +0100727# TARGET - (mandatory) - The target to apply settings to.
728# Directory properties
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000729#
730#OUTPUTS
731# n/a
732#
733function(_embedded_apply_linker_cmd_file_setting TARGET)
734 #Check if the parameter is a target.
Mate Toth-Pal76867262018-03-09 13:15:36 +0100735 if(NOT TARGET ${TARGET})
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000736 message(FATAL_ERROR "_embedded_apply_linker_cmd_file_setting(): target '${TARGET}' is not defined.")
737 endif()
738 #Check if target is an executable.
739 get_property(_TGT_TYPE TARGET ${TARGET} PROPERTY TYPE)
740 if(NOT _TGT_TYPE STREQUAL "EXECUTABLE")
741 message(FATAL_ERROR "_embedded_apply_linker_cmd_file_setting(): target '${TARGET}' is not an executable.")
742 endif()
743
744 #Check if executable has a linker command file set.
745 get_property(_LINKER_CMD_FILE GLOBAL PROPERTY EMBEDDED_LINKER_CMD_FILE_${TARGET} SET)
746 if (NOT _LINKER_CMD_FILE)
747 message(FATAL_ERROR "_embedded_apply_linker_cmd_file_setting(): Please set linker command file for target '${TARGET}' using embedded_set_target_linker_file().")
748 endif()
749 #Get the path to the linker command file.
750 get_property(_LINKER_CMD_FILE GLOBAL PROPERTY EMBEDDED_LINKER_CMD_FILE_${TARGET})
Mate Toth-Pal76867262018-03-09 13:15:36 +0100751
752 #Get macro defines and include paths set for the target.
753 get_property(_LINKER_DEFINES GLOBAL PROPERTY EMBEDDED_LINKER_DEFINES_${TARGET})
754 get_property(_LINKER_INCLUDES GLOBAL PROPERTY EMBEDDED_LINKER_INCLUDES_${TARGET})
755 compiler_set_linkercmdfile(TARGET ${TARGET} PATH ${_LINKER_CMD_FILE} DEFINES ${_LINKER_DEFINES} INCLUDES ${_LINKER_INCLUDES})
Gyorgy Szing30fa9872017-12-05 01:08:47 +0000756endfunction()