blob: 80439de6bb4b0828fff1d7a5b325a3034c680e55 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|
function(collect_object_file_deps target result)
# NOTE: This function does add entrypoint targets to |result|.
# It is expected that the caller adds them separately.
set(all_deps "")
get_target_property(target_type ${target} "TARGET_TYPE")
if(NOT target_type)
return()
endif()
if(${target_type} STREQUAL ${OBJECT_LIBRARY_TARGET_TYPE})
list(APPEND all_deps ${target})
get_target_property(deps ${target} "DEPS")
foreach(dep IN LISTS deps)
collect_object_file_deps(${dep} dep_targets)
list(APPEND all_deps ${dep_targets})
endforeach(dep)
list(REMOVE_DUPLICATES all_deps)
set(${result} ${all_deps} PARENT_SCOPE)
return()
endif()
if(${target_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})
set(entrypoint_target ${target})
get_target_property(is_alias ${entrypoint_target} "IS_ALIAS")
if(is_alias)
get_target_property(aliasee ${entrypoint_target} "DEPS")
if(NOT aliasee)
message(FATAL_ERROR
"Entrypoint alias ${entrypoint_target} does not have an aliasee.")
endif()
set(entrypoint_target ${aliasee})
endif()
get_target_property(deps ${target} "DEPS")
foreach(dep IN LISTS deps)
collect_object_file_deps(${dep} dep_targets)
list(APPEND all_deps ${dep_targets})
endforeach(dep)
list(REMOVE_DUPLICATES all_deps)
set(${result} ${all_deps} PARENT_SCOPE)
return()
endif()
if(${target_type} STREQUAL ${ENTRYPOINT_EXT_TARGET_TYPE})
# It is not possible to recursively extract deps of external dependencies.
# So, we just accumulate the direct dep and return.
get_target_property(deps ${target} "DEPS")
set(${result} ${deps} PARENT_SCOPE)
return()
endif()
endfunction(collect_object_file_deps)
function(get_all_object_file_deps result fq_deps_list)
set(all_deps "")
foreach(dep ${fq_deps_list})
get_target_property(dep_type ${dep} "TARGET_TYPE")
if(NOT ((${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}) OR
(${dep_type} STREQUAL ${ENTRYPOINT_EXT_TARGET_TYPE})))
message(FATAL_ERROR "Dependency '${dep}' of 'add_entrypoint_collection' is "
"not an 'add_entrypoint_object' or 'add_entrypoint_external' target.")
endif()
collect_object_file_deps(${dep} recursive_deps)
list(APPEND all_deps ${recursive_deps})
# Add the entrypoint object target explicitly as collect_object_file_deps
# only collects object files from non-entrypoint targets.
if(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})
set(entrypoint_target ${dep})
get_target_property(is_alias ${entrypoint_target} "IS_ALIAS")
if(is_alias)
get_target_property(aliasee ${entrypoint_target} "DEPS")
if(NOT aliasee)
message(FATAL_ERROR
"Entrypoint alias ${entrypoint_target} does not have an aliasee.")
endif()
set(entrypoint_target ${aliasee})
endif()
endif()
list(APPEND all_deps ${entrypoint_target})
endforeach(dep)
list(REMOVE_DUPLICATES all_deps)
set(${result} ${all_deps} PARENT_SCOPE)
endfunction()
# A rule to build a library from a collection of entrypoint objects and bundle
# it in a single LLVM-IR bitcode file.
# Usage:
# add_gpu_entrypoint_library(
# DEPENDS <list of add_entrypoint_object targets>
# )
function(add_bitcode_entrypoint_library target_name base_target_name)
cmake_parse_arguments(
"ENTRYPOINT_LIBRARY"
"" # No optional arguments
"" # No single value arguments
"DEPENDS" # Multi-value arguments
${ARGN}
)
if(NOT ENTRYPOINT_LIBRARY_DEPENDS)
message(FATAL_ERROR "'add_entrypoint_library' target requires a DEPENDS list "
"of 'add_entrypoint_object' targets.")
endif()
get_fq_deps_list(fq_deps_list ${ENTRYPOINT_LIBRARY_DEPENDS})
get_all_object_file_deps(all_deps "${fq_deps_list}")
set(objects "")
foreach(dep IN LISTS all_deps)
set(object $<$<STREQUAL:$<TARGET_NAME_IF_EXISTS:${dep}>,${dep}>:$<TARGET_OBJECTS:${dep}>>)
list(APPEND objects ${object})
endforeach()
add_executable(${target_name} ${objects})
target_link_options(${target_name} PRIVATE "${LIBC_COMPILE_OPTIONS_DEFAULT}"
"-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm")
endfunction(add_bitcode_entrypoint_library)
# A rule to build a library from a collection of entrypoint objects.
# Usage:
# add_entrypoint_library(
# DEPENDS <list of add_entrypoint_object targets>
# )
#
# NOTE: If one wants an entrypoint to be available in a library, then they will
# have to list the entrypoint target explicitly in the DEPENDS list. Implicit
# entrypoint dependencies will not be added to the library.
function(add_entrypoint_library target_name)
cmake_parse_arguments(
"ENTRYPOINT_LIBRARY"
"" # No optional arguments
"" # No single value arguments
"DEPENDS" # Multi-value arguments
${ARGN}
)
if(NOT ENTRYPOINT_LIBRARY_DEPENDS)
message(FATAL_ERROR "'add_entrypoint_library' target requires a DEPENDS list "
"of 'add_entrypoint_object' targets.")
endif()
get_fq_deps_list(fq_deps_list ${ENTRYPOINT_LIBRARY_DEPENDS})
get_all_object_file_deps(all_deps "${fq_deps_list}")
set(objects "")
foreach(dep IN LISTS all_deps)
list(APPEND objects $<$<STREQUAL:$<TARGET_NAME_IF_EXISTS:${dep}>,${dep}>:$<TARGET_OBJECTS:${dep}>>)
endforeach(dep)
add_library(
${target_name}
STATIC
${objects}
)
set_target_properties(${target_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR})
endfunction(add_entrypoint_library)
set(HDR_LIBRARY_TARGET_TYPE "HDR_LIBRARY")
# Internal function, used by `add_header_library`.
function(create_header_library fq_target_name)
cmake_parse_arguments(
"ADD_HEADER"
"" # Optional arguments
"" # Single value arguments
"HDRS;DEPENDS;FLAGS;COMPILE_OPTIONS" # Multi-value arguments
${ARGN}
)
if(NOT ADD_HEADER_HDRS)
message(FATAL_ERROR "'add_header_library' target requires a HDRS list of .h files.")
endif()
if(SHOW_INTERMEDIATE_OBJECTS)
message(STATUS "Adding header library ${fq_target_name}")
if(${SHOW_INTERMEDIATE_OBJECTS} STREQUAL "DEPS")
foreach(dep IN LISTS ADD_HEADER_DEPENDS)
message(STATUS " ${fq_target_name} depends on ${dep}")
endforeach()
endif()
endif()
add_library(${fq_target_name} INTERFACE)
target_sources(${fq_target_name} INTERFACE ${ADD_HEADER_HDRS})
if(ADD_HEADER_DEPENDS)
add_dependencies(${fq_target_name} ${ADD_HEADER_DEPENDS})
# `*.__copied_hdr__` is created only to copy the header files to the target
# location, not to be linked against.
set(link_lib "")
foreach(dep ${ADD_HEADER_DEPENDS})
if (NOT dep MATCHES "__copied_hdr__")
list(APPEND link_lib ${dep})
endif()
endforeach()
target_link_libraries(${fq_target_name} INTERFACE ${link_lib})
endif()
if(ADD_HEADER_COMPILE_OPTIONS)
target_compile_options(${fq_target_name} INTERFACE ${ADD_HEADER_COMPILE_OPTIONS})
endif()
set_target_properties(
${fq_target_name}
PROPERTIES
INTERFACE_FLAGS "${ADD_HEADER_FLAGS}"
TARGET_TYPE "${HDR_LIBRARY_TARGET_TYPE}"
DEPS "${ADD_HEADER_DEPENDS}"
FLAGS "${ADD_HEADER_FLAGS}"
)
endfunction(create_header_library)
# Rule to add header only libraries.
# Usage
# add_header_library(
# <target name>
# HDRS <list of .h files part of the library>
# DEPENDS <list of dependencies>
# FLAGS <list of flags>
# )
function(add_header_library target_name)
add_target_with_flags(
${target_name}
CREATE_TARGET create_header_library
${ARGN}
)
endfunction(add_header_library)
|