blob: b7705fd0074e25e258baf9ca9be1217352028d29 [file] [log] [blame]
Gyorgy Szing5e429cb2019-12-03 20:39:55 +01001#-------------------------------------------------------------------------------
2# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6#-------------------------------------------------------------------------------
7
8#[===[.rst:
9STGT utility file
10-----------------
11The STGT ("simple target") API is a collection of functions which wrap the CMake
12target functions and extend the built-in functionality. The main purpose of this
13utility is to connect the :cmake:module:`group`\s and the build targets. It
14handles the creation of new build targets, collecting the groups that will be
15applied on the target, and setting the target type. Also it provides functions
16to add source files and include paths in view of the properties already applied
17to the target, assign a linker script to the target, etc.
18
19After the configuration step, the targets created by STGT are the same, in the
20end, as normal CMake binary targets. However, the concept of STGT is to have
21"virtual" targets when collecting the setting groups, etc. and only "tie" them
22to a CMake target at the end of setup. This provides more flexibilty and
23expandabilty for the future, without additional complexity to the user, because
24the functionality is hidden behind the API.
25
26Internally the utility uses global properties and groups. Global property
27``STGT.<name of target>`` is defined to indicate that the target is defined.
28Global property ``STGT.<name of target>.GROUPS`` stores the list of groups added
29to the target. Adding a group to a target only results in modifying this list,
30the parameters stored in the group are actually applied only by the
31:cmake:command:`stgt_set_target` function. This function creates a normal CMake
32binary target for the STGT target and calls :cmake:command:`group_apply`, which
33transfers all the parameters stored in the groups selected for the STGT target
34into normal CMake target properties (compile flags, defines, etc.).
35
36.. todo:: How to include compiler file?
37
38#]===]
39
40include_guard(DIRECTORY)
41include(Common/Group)
42include(Common/Utils)
43
44#[===[.rst:
45.. cmake:command:: stgt_create
46
47 .. code-block:: cmake
48
49 stgt_create(NAME foo)
50
51 Create new target.
52
53 Inputs:
54
55 ``NAME``
56 Name of the new target, use |C identifier like string|. The name must be
57 unique within the global namespace, otherwise an error is generated.
58
59 .. todo:: TYPE and SRCS properties unused.
60
61#]===]
62function(stgt_create)
63 set(_OPTIONS_ARGS)
64 set(_ONE_VALUE_ARGS NAME)
65 set(_MULTI_VALUE_ARGS)
66 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
67
68 check_args(stgt_create NAME)
69
70 set(_null " ")
71 define_property(GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME} BRIEF_DOCS ${_null} FULL_DOCS ${_null})
72 foreach(_type IN ITEMS GROUPS TYPE SRCS)
73 define_property(GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME}.${_type} BRIEF_DOCS ${_null} FULL_DOCS ${_null})
74 endforeach()
75endfunction()
76
77#[===[.rst:
78.. cmake:command:: stgt_is_defined
79
80 .. code-block:: cmake
81
82 stgt_is_defined(NAME foo RET ret)
83
84 Helper function to check if a target has been defined.
85
86 Inputs:
87
88 ``NAME``
89 Name of the target.
90
91 Outputs:
92
93 ``RET``
94 Name of the variable in the parent scope, where the return value is written.
95
96#]===]
97function(stgt_is_defined)
98 set(_OPTIONS_ARGS)
99 set(_ONE_VALUE_ARGS NAME RET)
100 set(_MULTI_VALUE_ARGS)
101 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
102
103 check_args(stgt_is_defined NAME RET)
104
105 get_property(_is_defined GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME} DEFINED)
106 set(${_MY_PARAMS_RET} ${_is_defined} PARENT_SCOPE)
107endfunction()
108
109#[===[.rst:
110.. cmake:command:: stgt_add_setting
111
112 .. code-block:: cmake
113
114 stgt_add_setting(NAME foo GROUPS group1 group2)
115
116 Add setting groups to a target. The groups are not applied yet, only collected
117 to the group list of the target. Multiple groups can be added in one call.
118
119 Inputs:
120
121 ``NAME``
122 Name of the target.
123
124 ``GROUPS`` (multi)
125 Name of the groups.
126
127#]===]
128function(stgt_add_setting)
129 set(_OPTIONS_ARGS)
130 set(_ONE_VALUE_ARGS NAME)
131 set(_MULTI_VALUE_ARGS GROUPS)
132 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
133
134 check_args(stgt_add_setting NAME GROUPS)
135
136 stgt_is_defined(NAME ${_MY_PARAMS_NAME} RET _is_stgt_defined)
137 if(NOT _is_stgt_defined)
138 message(FATAL_ERROR "stgt_add_setting(): '${_MY_PARAMS_NAME}' stgt is not defined.")
139 endif()
140
141 foreach(_group IN LISTS _MY_PARAMS_GROUPS)
142 group_is_defined(NAME ${_group} RET _is_group_defined)
143 if(NOT _is_group_defined)
144 message(FATAL_ERROR "stgt_add_setting(): '${_group}' group is not defined.")
145 endif()
146 endforeach()
147
148 get_property(_groups GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME}.GROUPS)
149 list(APPEND _groups "${_MY_PARAMS_GROUPS}")
150 set_property(GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME}.GROUPS ${_groups})
151endfunction()
152
153#[===[.rst:
154.. cmake:command:: stgt_set_target
155
156 .. code-block:: cmake
157
158 stgt_set_target(NAME foo TYPE lib [ARGS arg1 ...])
159
160 Set target type. This function creates a normal CMake binary target, and
161 applies the list of groups previously associated to the target.
162
163 Inputs:
164
165 ``NAME``
166 Name of the target.
167
168 ``TYPE``
169 Type can be EXE, LIB, OBJLIB.
170
171 ``ARGS`` (multi)
172 Additional arguments to pass through to add_executable or add_library
173
174 .. todo:: New functionality might be needed to handle situations when order of
175 include paths matters.
176
177#]===]
178function(stgt_set_target)
179 set(_OPTIONS_ARGS)
180 set(_ONE_VALUE_ARGS NAME TYPE)
181 set(_MULTI_VALUE_ARGS ARGS)
182 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
183
184 check_args(stgt_set_target NAME TYPE)
185
186 string(TOUPPER ${_MY_PARAMS_TYPE} _type)
187 if(_type STREQUAL "EXE")
188 add_executable(${_MY_PARAMS_NAME} ${_MY_PARAMS_ARGS})
189 elseif(_type STREQUAL "LIB")
190 add_library(${_MY_PARAMS_NAME} STATIC ${_MY_PARAMS_ARGS})
191 elseif(_type STREQUAL "OBJLIB")
192 add_library(${_MY_PARAMS_NAME} OBJECT ${_MY_PARAMS_ARGS})
193 else()
194 message(FATAL_ERROR "stgt_set_target(): '${_MY_PARAMS_TYPE}' target type is invalid.")
195 endif()
196
197 get_property(_groups GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME}.GROUPS)
198 foreach(_group IN LISTS _groups)
199 group_apply(NAME ${_group} TARGETS ${_MY_PARAMS_NAME})
200 endforeach()
201endfunction()
202
203#[===[.rst:
204.. cmake:command:: stgt_get_param
205
206 .. code-block:: cmake
207
208 stgt_get_param(NAME foo KEY one RET ret)
209
210 Get the value of a property on a specific target.
211
212 Inputs:
213
214 ``NAME``
215 Name of the target.
216
217 ``KEY``
218 Which property to read.
219
220 Outputs:
221
222 ``RET``
223 Name of the variable in the parent scope, where the return value is written.
224
225#]===]
226function(stgt_get_param)
227 set(_OPTIONS_ARGS)
228 set(_ONE_VALUE_ARGS NAME KEY RET)
229 set(_MULTI_VALUE_ARGS)
230 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
231
232 check_args(stgt_get_param NAME KEY RET)
233
234 stgt_is_defined(NAME ${_MY_PARAMS_NAME} RET _is_stgt_defined)
235 if(NOT _is_stgt_defined)
236 message(FATAL_ERROR "stgt_get_param(): '${_MY_PARAMS_NAME}' stgt is not defined.")
237 endif()
238
239 get_target_property(_val ${_MY_PARAMS_NAME} ${_MY_PARAMS_KEY})
240 if(_val MATCHES ".*-NOTFOUND")
241 message(FATAL_ERROR "stgt_get_param(): parameter '${_MY_PARAMS_KEY}' of target
242 '${_MY_PARAMS_NAME}' is missing.")
243 endif()
244
245 set(${_MY_PARAMS_RET} ${_val} PARENT_SCOPE)
246endfunction()
247
248#[===[.rst:
249.. cmake:command:: stgt_add_src
250
251 .. code-block:: cmake
252
253 stgt_add_src(NAME foo SRC main.c)
254
255 Add source files to a target. Multiple source files can be added to multiple
256 targets in one call.
257
258 Inputs:
259
260 ``NAME`` (multi)
261 Name of the targets.
262
263 ``SRC`` (multi)
264 Source files to add.
265
266#]===]
267function(stgt_add_src)
268 set(_OPTIONS_ARGS)
269 set(_ONE_VALUE_ARGS)
270 set(_MULTI_VALUE_ARGS NAME SRC)
271 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
272
273 check_args(stgt_add_src NAME SRC)
274
275 foreach(_target IN LISTS _MY_PARAMS_NAME)
276 if(NOT TARGET ${_target})
277 message(FATAL_ERROR "stgt_add_src(): '${_target}' target is not defined.")
278 endif()
279
280 get_property(_object_lib TARGET "${_target}" PROPERTY "OBJECT_LIB")
281 if(_object_lib)
282 target_sources(${_object_lib} PRIVATE ${_MY_PARAMS_SRC})
283 else()
284 target_sources(${_target} PRIVATE ${_MY_PARAMS_SRC})
285 endif()
286 endforeach()
287endfunction()
288
289#[===[.rst:
290.. cmake:command:: stgt_add_src_cond
291
292 .. code-block:: cmake
293
294 stgt_add_src_cond(NAME foo bar SRC uart.c spi.c KEY one VAL 1)
295 stgt_add_src_cond(NAME foo bar SRC uart.c spi.c KEY one VAL 1 OPTIONAL true)
296
297 Add source files to a target based on a condition: if value of KEY property on
298 the target equals VAL, the source files will be added. Multiple source files
299 can be added to multiple targets in one call. In this case the condition is
300 evaluated for each target separately. If the KEY property is not defined for
301 the target and OPTIONAL is not true, an error will be generated.
302
303 Inputs:
304
305 ``NAME`` (multi)
306 Name of the targets.
307
308 ``SRC`` (multi)
309 Source files to add.
310
311 ``KEY``
312 Which property to read.
313
314 ``VAL``
315 Condition is true if value of KEY equals this value.
316
317 ``OPTIONAL`` (bool)
318 If true, no error will be generated if KEY is not defined for the target.
319 Can be omitted, default value is false.
320
321#]===]
322function(stgt_add_src_cond)
323 set(_OPTIONS_ARGS OPTIONAL)
324 set(_ONE_VALUE_ARGS KEY VAL)
325 set(_MULTI_VALUE_ARGS NAME SRC)
326 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
327
328 check_args(stgt_add_src_cond NAME KEY VAL SRC)
329
330 foreach(_target IN LISTS _MY_PARAMS_NAME)
331 get_target_property(_val ${_target} ${_MY_PARAMS_KEY})
332 if((_val MATCHES ".*-NOTFOUND") AND (NOT _MY_PARAMS_OPTIONAL))
333 message(FATAL_ERROR "stgt_add_src_cond: mandatory parameter '${_MY_PARAMS_KEY}'
334 of target '${_target}' is missing.")
335 endif()
336
337 if(${_val} STREQUAL ${_MY_PARAMS_VAL})
338 stgt_add_src(NAME ${_target} SRC ${_MY_PARAMS_SRC})
339 endif()
340 endforeach()
341endfunction()
342
343#[===[.rst:
344.. cmake:command:: stgt_add_src_param
345
346 .. code-block:: cmake
347
348 stgt_add_src_param(NAME foo bar SRC ../@prop_name@/uart.c KEY prop_name)
349
350 Add source files to a target using a parameter dependent path. The name of KEY
351 can be used in the path of the source file with the @prop_name@ syntax. This
352 field will be replaced by the value of the property on the target. Multiple
353 source files can be added to multiple targets in one call. In this case the
354 parameter value is evaluated for each target separately.
355
356 Inputs:
357
358 ``NAME`` (multi)
359 Name of the targets.
360
361 ``SRC`` (multi)
362 Source files to add.
363
364 ``KEY``
365 Which property to read.
366
367 .. todo:: Fix syntax highlight warning.
368
369#]===]
370function(stgt_add_src_param)
371 set(_OPTIONS_ARGS)
372 set(_ONE_VALUE_ARGS KEY)
373 set(_MULTI_VALUE_ARGS NAME SRC)
374 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
375
376 check_args(stgt_add_src_param NAME KEY SRC)
377
378 foreach(_target IN LISTS _MY_PARAMS_NAME)
379 get_target_property(_val ${_target} ${_MY_PARAMS_KEY})
380 if(_val MATCHES ".*-NOTFOUND")
381 message(FATAL_ERROR "stgt_add_src_param: mandatory parameter '${_MY_PARAMS_KEY}'
382 of target '${_target}' is missing.")
383 endif()
384
385 set(_src ${_MY_PARAMS_SRC})
386 list(TRANSFORM _src REPLACE @${_MY_PARAMS_KEY}@ ${_val})
387 stgt_add_src(NAME ${_target} SRC ${_src})
388 endforeach()
389endfunction()
390
391#[===[.rst:
392.. cmake:command:: stgt_add_inc
393
394 .. code-block:: cmake
395
396 stgt_add_inc(NAME foo INC ${ROOT_DIR}/include)
397
398 Add include paths to a target. Multiple paths can be added to a target in one
399 call.
400
401 Inputs:
402
403 ``NAME``
404 Name of the target.
405
406 ``INC`` (multi)
407 Include paths to add.
408
409#]===]
410function(stgt_add_inc)
411 set(_OPTIONS_ARGS)
412 set(_ONE_VALUE_ARGS NAME)
413 set(_MULTI_VALUE_ARGS INC)
414 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
415
416 check_args(stgt_add_inc NAME INC)
417
418 if(NOT TARGET ${_MY_PARAMS_NAME})
419 message(FATAL_ERROR "stgt_add_inc(): '${_MY_PARAMS_NAME}' target is not defined.")
420 endif()
421
422 target_include_directories(${_MY_PARAMS_NAME} PRIVATE ${_MY_PARAMS_INC})
423endfunction()
424
425#[===[.rst:
426.. cmake:command:: stgt_add_inc_cond
427
428 .. code-block:: cmake
429
430 stgt_add_inc_cond(NAME foo INC ${ROOT_DIR}/include KEY one VAL 1)
431 stgt_add_inc_cond(NAME foo INC ${ROOT_DIR}/include KEY one VAL 1 OPTIONAL true)
432
433 Add include paths to a target based on a condition: if value of KEY property
434 on the target equals VAL, the include paths will be added. Multiple paths can
435 be added in one call. If the KEY property is not defined for the target and
436 OPTIONAL is not true, an error will be generated.
437
438 Inputs:
439
440 ``NAME``
441 Name of the target.
442
443 ``INC`` (multi)
444 Include paths to add.
445
446 ``KEY``
447 Which property to read.
448
449 ``VAL``
450 Condition is true if value of KEY equals this value.
451
452 ``OPTIONAL`` (bool)
453 If true, no error will be generated if KEY is not defined for the target.
454 Can be omitted, default value is false.
455
456#]===]
457function(stgt_add_inc_cond)
458 set(_OPTIONS_ARGS OPTIONAL)
459 set(_ONE_VALUE_ARGS NAME KEY VAL)
460 set(_MULTI_VALUE_ARGS INC)
461 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
462
463 check_args(stgt_add_inc_cond NAME KEY VAL INC)
464
465 get_target_property(_val ${_MY_PARAMS_NAME} ${_MY_PARAMS_KEY})
466 if(NOT (_val OR _MY_PARAMS_OPTIONAL))
467 message(FATAL_ERROR "stgt_add_inc_cond: mandatory parameter '${_MY_PARAMS_KEY}'
468 of target '${_MY_PARAMS_NAME}' is missing.")
469 endif()
470
471 if(${_val} STREQUAL ${_MY_PARAMS_VAL})
472 stgt_add_inc(NAME ${_MY_PARAMS_NAME} INC ${_MY_PARAMS_INC})
473 endif()
474endfunction()
475
476#[===[.rst:
477.. cmake:command:: stgt_add_inc_param
478
479 .. code-block:: cmake
480
481 stgt_add_inc_param(NAME foo INC ../@prop_name@/include KEY prop_name)
482
483 Add include paths to a target using a parameter dependent path. The name of
484 KEY can be used in the include path with the @prop_name@ syntax. This field
485 will be replaced by the value of the property on the target. Multiple paths
486 can be added in one call.
487
488 Inputs:
489
490 ``NAME``
491 Name of the target.
492
493 ``INC`` (multi)
494 Include paths to add.
495
496 ``KEY``
497 Which property to read.
498
499 .. todo:: Fix syntax highlight warning.
500
501#]===]
502function(stgt_add_inc_param)
503 set(_OPTIONS_ARGS)
504 set(_ONE_VALUE_ARGS NAME KEY)
505 set(_MULTI_VALUE_ARGS INC)
506 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
507
508 check_args(stgt_add_inc_param NAME KEY INC)
509
510 get_target_property(_val ${_MY_PARAMS_NAME} ${_MY_PARAMS_KEY})
511 if(NOT _val)
512 message(FATAL_ERROR "stgt_add_inc_param: mandatory parameter '${_MY_PARAMS_KEY}'
513 of target '${_MY_PARAMS_NAME}' is missing.")
514 endif()
515
516 list(TRANSFORM _MY_PARAMS_INC REPLACE @${_MY_PARAMS_KEY}@ ${_val})
517 stgt_add_inc(NAME ${_MY_PARAMS_NAME} INC ${_MY_PARAMS_INC})
518endfunction()
519
520#[===[.rst:
521.. cmake:command:: stgt_link_libraries
522
523 .. code-block:: cmake
524
525 stgt_link_libraries(NAME foo LIBS lib1 lib2)
526
527 Link libraries to target. Multiple libraries can be linked in one call.
528
529 Inputs:
530
531 ``NAME``
532 Name of the target.
533
534 ``LIBS`` (multi)
535 Libraries to link.
536
537#]===]
538function(stgt_link_libraries)
539 set(_OPTIONS_ARGS)
540 set(_ONE_VALUE_ARGS NAME)
541 set(_MULTI_VALUE_ARGS LIBS)
542 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
543
544 check_args(stgt_link_libraries NAME LIBS)
545
546 target_link_libraries(${_MY_PARAMS_NAME} PRIVATE ${_MY_PARAMS_LIBS})
547
548 get_property(_object_lib TARGET "${_MY_PARAMS_NAME}" PROPERTY "OBJECT_LIB")
549 if(_object_lib)
550 get_property(_sources TARGET "${_MY_PARAMS_NAME}" PROPERTY "SOURCES")
551 set_property(TARGET "${_object_lib}" APPEND PROPERTY "SOURCES" "$<TARGET_GENEX_EVAL:${_MY_PARAMS_NAME},${_sources}>")
552 set_property(TARGET "${_MY_PARAMS_NAME}" PROPERTY "SOURCES" "")
553
554 set(_deps "${_MY_PARAMS_LIBS}")
555 foreach(_lib ${_MY_PARAMS_LIBS})
556 get_target_property(_type "${_lib}" "TYPE")
557 if(_type STREQUAL "OBJECT_LIBRARY")
558 list(APPEND _deps "$<TARGET_OBJECTS:${_lib}>")
559 else()
560 list(APPEND _deps "$<TARGET_FILE:${_lib}>")
561 endif()
562 endforeach()
563
564 get_property(_build_messages TARGET "${_MY_PARAMS_NAME}" PROPERTY "BUILD_MESSAGES")
565 foreach(_message ${_build_messages})
566 set_property(TARGET "${_message}" APPEND PROPERTY "BUILD_MESSAGE_DEPENDS" "${_deps}")
567 endforeach()
568 endif()
569endfunction()
570
571#[===[.rst:
572.. cmake:command:: stgt_link_build_messages
573
574 .. code-block:: cmake
575
576 stgt_link_build_messages(NAME target LIBS msg1 [msg2 ...])
577
578 Link one or more object libraries to the target, treating them as "build messages".
579 This function configures the libraries as order-only dependencies of the target,
580 and appends the list of all (non-build message) libraries linked to the target,
581 as well as their output files to the property named BUILD_MESSAGE_DEPENDS, found
582 on the build message libraries.
583
584 This property can be used with add_custom_command to cause the build message to rebuild
585 if any of these linker-input files are modified in the following way:
586
587 .. code-block:: cmake
588
589 add_custom_command([...] DEPENDS "$<TARGET_GENEX_EVAL:msg1,$<TARGET_PROPERTY:msg1,BUILD_MESSAGE_DEPENDS>>")
590
591 Calling this function on a target causes it to be split into two targets behind the scenes:
592 an object library, which compiles all the source files, and the original target, which
593 performs the linking step.
594
595 The practical implication of this is that the SOURCES property on the original target will
596 appear empty. Please refrain from updating this property directly, or using native
597 CMake commands that update this variable. Use the equivalent STGT functions instead.
598
599 If you need to use the value of the SOURCES property, you can check for the presence
600 of the OBJECT_LIB property. This will contain the name of the object library target, which
601 will have its SOURCES property populated normally.
602
603 With generator expressions you would acomplish this in the following way:
604
605 .. code-block:: cmake
606
607 set(foo_src_tgt "$<IF:$<BOOL:$<TARGET_PROPERTY:foo,OBJECT_LIB>>,$<TARGET_PROPERTY:foo,OBJECT_LIB>,foo>")
608 $<TARGET_GENEX_EVAL:${foo_src_tgt},$<TARGET_PROPERTY:${foo_src_tgt},SOURCES>>
609
610 Inputs:
611
612 ``NAME``
613 Name of the target.
614
615 ``LIBS`` (multi)
616 Libraries to link.
617
618#]===]
619function(stgt_link_build_messages)
620 set(_OPTIONS_ARGS)
621 set(_ONE_VALUE_ARGS NAME)
622 set(_MULTI_VALUE_ARGS LIBS)
623 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
624
625 check_args(stgt_add_build_message NAME LIBS)
626
627 get_property(_OBJECT_LIB TARGET "${_MY_PARAMS_NAME}" PROPERTY "OBJECT_LIB")
628 if(NOT _OBJECT_LIB)
629 set(_OBJECT_LIB "${_MY_PARAMS_NAME}_o")
630 set_property(TARGET "${_MY_PARAMS_NAME}" PROPERTY "OBJECT_LIB" "${_OBJECT_LIB}")
631
632 stgt_create(NAME "${_OBJECT_LIB}")
633 stgt_set_target(NAME "${_OBJECT_LIB}" TYPE objlib ARGS EXCLUDE_FROM_ALL)
634
635 get_property(_sources TARGET "${_MY_PARAMS_NAME}" PROPERTY "SOURCES")
636 set_property(TARGET "${_OBJECT_LIB}" PROPERTY "SOURCES" "$<TARGET_GENEX_EVAL:${_MY_PARAMS_NAME},${_sources}>")
637 set_property(TARGET "${_MY_PARAMS_NAME}" PROPERTY "SOURCES" "")
638
639 foreach(_prop "COMPILE_DEFINITIONS" "COMPILE_OPTIONS" "LINK_OPTIONS" "INCLUDE_DIRECTORIES")
640 set_property(TARGET "${_OBJECT_LIB}" PROPERTY "${_prop}" "$<TARGET_GENEX_EVAL:${_MY_PARAMS_NAME},$<TARGET_PROPERTY:${_MY_PARAMS_NAME},${_prop}>>")
641 endforeach()
642
643 stgt_link_libraries(NAME "${_MY_PARAMS_NAME}" LIBS "${_OBJECT_LIB}")
644 endif()
645
646 set_property(TARGET "${_MY_PARAMS_NAME}" APPEND PROPERTY "BUILD_MESSAGES" "${_MY_PARAMS_LIBS}")
647
648 get_property(_libs TARGET "${_MY_PARAMS_NAME}" PROPERTY "LINK_LIBRARIES")
649 set(_deps "${_libs}" "$<TARGET_GENEX_EVAL:${_MY_PARAMS_NAME},$<TARGET_PROPERTY:${_MY_PARAMS_NAME},LINK_DEPENDS>>")
650 foreach(_lib ${_libs})
651 get_target_property(_type "${_lib}" "TYPE")
652 if(_type STREQUAL "OBJECT_LIBRARY")
653 list(APPEND _deps "$<TARGET_OBJECTS:${_lib}>")
654 else()
655 list(APPEND _deps "$<TARGET_FILE:${_lib}>")
656 endif()
657 endforeach()
658
659 foreach(_message ${_MY_PARAMS_LIBS})
660 set_property(TARGET "${_message}" APPEND PROPERTY "BUILD_MESSAGE_DEPENDS" "${_deps}")
661 target_link_options("${_MY_PARAMS_NAME}" PRIVATE "$<TARGET_OBJECTS:${_message}>")
662 endforeach()
663
664 add_dependencies("${_MY_PARAMS_NAME}" ${_MY_PARAMS_LIBS})
665endfunction()
666
667#[===[.rst:
668.. cmake:command:: stgt_set_linker_script
669
670 .. code-block:: cmake
671
672 stgt_set_linker_script(NAME foo FILE foo.ld)
673 stgt_set_linker_script(NAME foo FILE foo.ld.S DEF RAM_SIZE=1024 INC include/mem)
674
675 Set linker file for target. FILE will be assigned to the target as linker
676 script. The function uses the compiler_set_linker_script() function call,
677 therefore the compiler abstraction API should be included. DEF and INC are
678 also passed to this function, which should use them when preprocessing the
679 linker script. The compiler_set_linker_script() function should add an LDFLAG
680 using the toolchain specific syntax to the TARGET_linker_script group.
681
682 Inputs:
683
684 ``NAME``
685 Name of the target.
686
687 ``FILE``
688 Linker script file for the target.
689
690 ``DEF`` (multi, optional)
691 Defines for the linker script preprocessor.
692
693 ``INC`` (multi, optional)
694 Include paths for the linker script preprocessor.
695
696#]===]
697function(stgt_set_linker_script)
698 set(_OPTIONS_ARGS)
699 set(_ONE_VALUE_ARGS NAME FILE)
700 set(_MULTI_VALUE_ARGS DEF INC)
701 cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
702
703 check_args(stgt_set_linker_script NAME FILE)
704
705 if(NOT TARGET ${_MY_PARAMS_NAME})
706 message(FATAL_ERROR "stgt_set_linker_script(): '${_MY_PARAMS_NAME}' target is not defined.")
707 endif()
708
709 group_new(NAME "${_MY_PARAMS_NAME}_linker_script")
710 compiler_set_linker_script(
711 TARGET "${_MY_PARAMS_NAME}"
712 FILE "${_MY_PARAMS_FILE}"
713 DEF "${_MY_PARAMS_DEF}"
714 INC "${_MY_PARAMS_INC}"
715 )
716 group_apply(NAME "${_MY_PARAMS_NAME}_linker_script" TARGETS "${_MY_PARAMS_NAME}")
717endfunction()