blob: 3f89746eeb0d749e9ade94fdbff0f7df2a372d4a [file] [log] [blame]
Mate Toth-Pal83a45bd2023-09-01 11:17:19 +02001#
2# SPDX-License-Identifier: BSD-3-Clause
3# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4#
5
6#
7# Helper functions for collecting all the source files and include paths that
8# are used in the RMM build
9#
10
11function(is_valid_target_name target_name output_variable)
12 string(FIND ${target_name} "NOTFOUND" notfound_pos)
13 string(FIND ${target_name} "::@" link_addr_pos)
14 string(FIND ${target_name} "$<$<" gen_expr_pos)
15 if((NOT ${notfound_pos} EQUAL "-1") OR
16 (NOT ${link_addr_pos} EQUAL "-1") OR
17 (NOT ${gen_expr_pos} EQUAL "-1"))
18 set(${output_variable} FALSE PARENT_SCOPE)
19 else()
20 set(${output_variable} TRUE PARENT_SCOPE)
21 endif()
22endfunction()
23
24function(normalise_property_value target_name output_variable)
25 foreach(value_prefix "INSTALL_INTERFACE" "BUILD_INTERFACE" "LINK_ONLY")
26 string(REGEX REPLACE "^.*${value_prefix}:([^>]+)>$" "\\1" target_name ${target_name})
27 endforeach()
28 set(${output_variable} ${target_name} PARENT_SCOPE)
29endfunction()
30
31function(collect_targets_recursively collected_targets new_target output_variable)
32 normalise_property_value("${new_target}" new_target)
33
34 if ("${new_target}" IN_LIST collected_targets)
35 set("${output_variable}" "${collected_targets}" PARENT_SCOPE)
36 return()
37 endif()
38
39 set(extended_target_list "${collected_targets}")
40 list(APPEND extended_target_list "${new_target}")
41
42 foreach(link_property "INTERFACE_LINK_LIBRARIES" "LINK_LIBRARIES")
43 # workaround for cmake older than 3.19:
44 # INTERFACE_LIBRARY targets may only have whitelisted properties. This is typically
45 # property names starting with 'INTERFACE_'
46 get_target_property(target_type ${new_target} TYPE)
47 if(${target_type} STREQUAL "INTERFACE_LIBRARY")
48 string(FIND "${link_property}" "INTERFACE_" interface_pos)
49 if (NOT interface_pos EQUAL 0)
50 continue()
51 endif()
52 endif()
53
54 get_target_property(target_interface "${new_target}" "${link_property}")
55 if(NOT "${target_interface}" STREQUAL "target_interface-NOTFOUND")
56 foreach(target_lib ${target_interface})
57 is_valid_target_name(${target_lib} valid_target_name)
58 if (valid_target_name)
59 collect_targets_recursively("${extended_target_list}" "${target_lib}" extended_target_list)
60 endif()
61 endforeach()
62 endif()
63 endforeach()
64
65 set("${output_variable}" "${extended_target_list}" PARENT_SCOPE)
66endfunction()
67
68function(add_include_from_target target_name)
69 foreach(include_property "INTERFACE_INCLUDE_DIRECTORIES" "INCLUDE_DIRECTORIES")
70 # workaround for cmake older than 3.19:
71 # INTERFACE_LIBRARY targets may only have whitelisted properties. This is typically
72 # property names starting with 'INTERFACE_'
73 get_target_property(target_type ${target_name} TYPE)
74 if(${target_type} STREQUAL "INTERFACE_LIBRARY")
75 string(FIND "${include_property}" "INTERFACE_" interface_pos)
76 if (NOT interface_pos EQUAL 0)
77 continue()
78 endif()
79 endif()
80
81 get_target_property(target_includes_dir ${target_name} ${include_property})
82 if(NOT "${target_includes_dir}" STREQUAL "target_includes_dir-NOTFOUND")
83 foreach(target_includes_dir ${target_includes_dir})
84 normalise_property_value(${target_includes_dir} target_includes_dir)
85 list(APPEND rmm_implementation_includes "-I${target_includes_dir}")
86 endforeach()
87 set (rmm_implementation_includes ${rmm_implementation_includes} PARENT_SCOPE)
88 endif()
89 endforeach()
90endfunction()
91
92function(add_source_and_include_from_target target_name)
93 add_include_from_target(${target_name} ${level})
94 set (rmm_implementation_includes ${rmm_implementation_includes} PARENT_SCOPE)
95
96 # workaround for cmake older than 3.19:
97 # INTERFACE_LIBRARY targets may only have whitelisted properties. This is typically
98 # property names starting with 'INTERFACE_'. So SOURCES.* is not allowed.
99 get_target_property(target_type ${target_name} TYPE)
100 if(${target_type} STREQUAL "INTERFACE_LIBRARY")
101 return()
102 endif()
103
104 get_target_property(target_srcs ${target_name} SOURCES)
105 get_target_property(target_srcs_dir ${target_name} SOURCE_DIR)
106 if((NOT "${target_srcs}" STREQUAL "target_srcs-NOTFOUND") AND
107 (NOT "${target_srcs_dir}" STREQUAL "target_srcs_dir-NOTFOUND"))
108 foreach(target_src ${target_srcs})
109 list(APPEND rmm_implementation_srcs "${target_srcs_dir}/${target_src}")
110 endforeach()
111 set (rmm_implementation_srcs ${rmm_implementation_srcs} PARENT_SCOPE)
112 endif()
113endfunction()
114
115function(add_source_and_include_recursively target_name)
116 collect_targets_recursively("" "${target_name}" rmm_target_list)
117
118 foreach(target_lib ${rmm_target_list})
119 add_source_and_include_from_target("${target_lib}")
120 endforeach()
121
122 set (rmm_implementation_srcs ${rmm_implementation_srcs} PARENT_SCOPE)
123 set (rmm_implementation_includes ${rmm_implementation_includes} PARENT_SCOPE)
124endfunction()