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