1 function(collect_object_file_deps target result)
2 # NOTE: This function does add entrypoint targets to |result|.
3 # It is expected that the caller adds them separately.
5 get_target_property(target_type ${target} "TARGET_TYPE")
10 if(${target_type} STREQUAL ${OBJECT_LIBRARY_TARGET_TYPE})
11 list(APPEND all_deps ${target})
12 get_target_property(deps ${target} "DEPS")
13 foreach(dep IN LISTS deps)
14 collect_object_file_deps(${dep} dep_targets)
15 list(APPEND all_deps ${dep_targets})
17 list(REMOVE_DUPLICATES all_deps)
18 set(${result} ${all_deps} PARENT_SCOPE)
22 if(${target_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE} OR
23 ${target_type} STREQUAL ${ENTRYPOINT_OBJ_VENDOR_TARGET_TYPE})
24 set(entrypoint_target ${target})
25 get_target_property(is_alias ${entrypoint_target} "IS_ALIAS")
27 get_target_property(aliasee ${entrypoint_target} "DEPS")
30 "Entrypoint alias ${entrypoint_target} does not have an aliasee.")
32 set(entrypoint_target ${aliasee})
34 get_target_property(deps ${target} "DEPS")
35 foreach(dep IN LISTS deps)
36 collect_object_file_deps(${dep} dep_targets)
37 list(APPEND all_deps ${dep_targets})
39 list(REMOVE_DUPLICATES all_deps)
40 set(${result} ${all_deps} PARENT_SCOPE)
44 if(${target_type} STREQUAL ${ENTRYPOINT_EXT_TARGET_TYPE})
45 # It is not possible to recursively extract deps of external dependencies.
46 # So, we just accumulate the direct dep and return.
47 get_target_property(deps ${target} "DEPS")
48 set(${result} ${deps} PARENT_SCOPE)
51 endfunction(collect_object_file_deps)
53 # A rule to build a library from a collection of entrypoint objects.
55 # add_entrypoint_library(
56 # DEPENDS <list of add_entrypoint_object targets>
59 # NOTE: If one wants an entrypoint to be available in a library, then they will
60 # have to list the entrypoint target explicitly in the DEPENDS list. Implicit
61 # entrypoint dependencies will not be added to the library.
62 function(add_entrypoint_library target_name)
63 cmake_parse_arguments(
65 "" # No optional arguments
66 "" # No single value arguments
67 "DEPENDS" # Multi-value arguments
70 if(NOT ENTRYPOINT_LIBRARY_DEPENDS)
71 message(FATAL_ERROR "'add_entrypoint_library' target requires a DEPENDS list "
72 "of 'add_entrypoint_object' targets.")
75 get_fq_deps_list(fq_deps_list ${ENTRYPOINT_LIBRARY_DEPENDS})
77 foreach(dep IN LISTS fq_deps_list)
78 get_target_property(dep_type ${dep} "TARGET_TYPE")
79 if(NOT ((${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}) OR
80 (${dep_type} STREQUAL ${ENTRYPOINT_EXT_TARGET_TYPE}) OR
81 (${dep_type} STREQUAL ${ENTRYPOINT_OBJ_VENDOR_TARGET_TYPE})))
82 message(FATAL_ERROR "Dependency '${dep}' of 'add_entrypoint_collection' is "
83 "not an 'add_entrypoint_object' or 'add_entrypoint_external' target.")
85 collect_object_file_deps(${dep} recursive_deps)
86 list(APPEND all_deps ${recursive_deps})
87 # Add the entrypoint object target explicitly as collect_object_file_deps
88 # only collects object files from non-entrypoint targets.
89 if(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE} OR
90 ${dep_type} STREQUAL ${ENTRYPOINT_OBJ_VENDOR_TARGET_TYPE})
91 set(entrypoint_target ${dep})
92 get_target_property(is_alias ${entrypoint_target} "IS_ALIAS")
94 get_target_property(aliasee ${entrypoint_target} "DEPS")
97 "Entrypoint alias ${entrypoint_target} does not have an aliasee.")
99 set(entrypoint_target ${aliasee})
102 list(APPEND all_deps ${entrypoint_target})
104 list(REMOVE_DUPLICATES all_deps)
106 foreach(dep IN LISTS all_deps)
107 list(APPEND objects $<$<STREQUAL:$<TARGET_NAME_IF_EXISTS:${dep}>,${dep}>:$<TARGET_OBJECTS:${dep}>>)
115 set_target_properties(${target_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR})
116 endfunction(add_entrypoint_library)
118 # Rule to build a shared library of redirector objects.
119 function(add_redirector_library target_name)
120 cmake_parse_arguments(
129 foreach(dep IN LISTS REDIRECTOR_LIBRARY_DEPENDS)
130 # TODO: Ensure that each dep is actually a add_redirector_object target.
131 list(APPEND obj_files $<TARGET_OBJECTS:${dep}>)
134 # TODO: Call the linker explicitly instead of calling the compiler driver to
135 # prevent DT_NEEDED on C++ runtime.
142 set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR})
143 target_link_libraries(${target_name} -nostdlib -lc -lm)
144 set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE "C")
145 endfunction(add_redirector_library)
147 set(HDR_LIBRARY_TARGET_TYPE "HDR_LIBRARY")
149 # Internal function, used by `add_header_library`.
150 function(create_header_library fq_target_name)
151 cmake_parse_arguments(
153 "" # Optional arguments
154 "" # Single value arguments
155 "HDRS;DEPENDS;FLAGS;COMPILE_OPTIONS" # Multi-value arguments
159 if(NOT ADD_HEADER_HDRS)
160 message(FATAL_ERROR "'add_header_library' target requires a HDRS list of .h files.")
163 if(SHOW_INTERMEDIATE_OBJECTS)
164 message(STATUS "Adding header library ${fq_target_name}")
165 if(${SHOW_INTERMEDIATE_OBJECTS} STREQUAL "DEPS")
166 foreach(dep IN LISTS ADD_HEADER_DEPENDS)
167 message(STATUS " ${fq_target_name} depends on ${dep}")
172 add_library(${fq_target_name} INTERFACE)
173 target_sources(${fq_target_name} INTERFACE ${ADD_HEADER_HDRS})
174 if(ADD_HEADER_DEPENDS)
175 add_dependencies(${fq_target_name} ${ADD_HEADER_DEPENDS})
176 target_link_libraries(${fq_target_name} INTERFACE ${ADD_HEADER_DEPENDS})
178 if(ADD_HEADER_COMPILE_OPTIONS)
179 target_compile_options(${fq_target_name} INTERFACE ${ADD_HEADER_COMPILE_OPTIONS})
181 set_target_properties(
184 INTERFACE_FLAGS "${ADD_HEADER_FLAGS}"
185 TARGET_TYPE "${HDR_LIBRARY_TARGET_TYPE}"
186 DEPS "${ADD_HEADER_DEPENDS}"
187 FLAGS "${ADD_HEADER_FLAGS}"
189 endfunction(create_header_library)
191 # Rule to add header only libraries.
193 # add_header_library(
195 # HDRS <list of .h files part of the library>
196 # DEPENDS <list of dependencies>
197 # FLAGS <list of flags>
200 # Internal function, used by `add_header_library`.
201 function(expand_flags_for_header_library target_name flags)
202 cmake_parse_arguments(
204 "IGNORE_MARKER" # Optional arguments
205 "" # Single-value arguments
206 "DEPENDS;FLAGS" # Multi-value arguments
210 list(LENGTH flags nflags)
212 create_header_library(
214 DEPENDS ${EXPAND_FLAGS_DEPENDS}
215 FLAGS ${EXPAND_FLAGS_FLAGS}
216 ${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
221 list(GET flags 0 flag)
222 list(REMOVE_AT flags 0)
223 extract_flag_modifier(${flag} real_flag modifier)
225 if(NOT "${modifier}" STREQUAL "NO")
226 expand_flags_for_header_library(
229 DEPENDS ${EXPAND_FLAGS_DEPENDS} IGNORE_MARKER
230 FLAGS ${EXPAND_FLAGS_FLAGS} IGNORE_MARKER
231 ${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
235 if("${real_flag}" STREQUAL "" OR "${modifier}" STREQUAL "ONLY")
239 set(NEW_FLAGS ${EXPAND_FLAGS_FLAGS})
240 list(REMOVE_ITEM NEW_FLAGS ${flag})
241 get_fq_dep_list_without_flag(NEW_DEPS ${real_flag} ${EXPAND_FLAGS_DEPENDS})
243 # Only target with `flag` has `.__NO_flag` target, `flag__NO` and
244 # `flag__ONLY` do not.
245 if("${modifier}" STREQUAL "")
246 set(TARGET_NAME "${target_name}.__NO_${flag}")
248 set(TARGET_NAME "${target_name}")
251 expand_flags_for_header_library(
254 DEPENDS ${NEW_DEPS} IGNORE_MARKER
255 FLAGS ${NEW_FLAGS} IGNORE_MARKER
256 ${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
258 endfunction(expand_flags_for_header_library)
260 function(add_header_library target_name)
261 cmake_parse_arguments(
263 "" # Optional arguments
264 "" # Single value arguments
265 "DEPENDS;FLAGS" # Multi-value arguments
269 get_fq_target_name(${target_name} fq_target_name)
271 if(ADD_TO_EXPAND_DEPENDS AND ("${SHOW_INTERMEDIATE_OBJECTS}" STREQUAL "DEPS"))
272 message(STATUS "Gathering FLAGS from dependencies for ${fq_target_name}")
275 get_fq_deps_list(fq_deps_list ${ADD_TO_EXPAND_DEPENDS})
276 get_flags_from_dep_list(deps_flag_list ${fq_deps_list})
278 list(APPEND ADD_TO_EXPAND_FLAGS ${deps_flag_list})
279 remove_duplicated_flags("${ADD_TO_EXPAND_FLAGS}" flags)
282 if(SHOW_INTERMEDIATE_OBJECTS AND flags)
283 message(STATUS "Header library ${fq_target_name} has FLAGS: ${flags}")
286 expand_flags_for_header_library(
289 DEPENDS ${fq_deps_list} IGNORE_MARKER
290 FLAGS ${flags} IGNORE_MARKER
291 ${ADD_TO_EXPAND_UNPARSED_ARGUMENTS}
293 endfunction(add_header_library)