1 set(OBJECT_LIBRARY_TARGET_TYPE "OBJECT_LIBRARY")
3 # Rule which is essentially a wrapper over add_library to compile a set of
4 # sources to object files.
8 # HDRS <list of header files>
9 # SRCS <list of source files>
10 # DEPENDS <list of dependencies>
11 # COMPILE_OPTIONS <optional list of special compile options for this target>
12 function(add_object_library target_name)
13 cmake_parse_arguments(
15 "" # No option arguments
16 "" # Single value arguments
17 "SRCS;HDRS;COMPILE_OPTIONS;DEPENDS" # Multivalue arguments
21 if(NOT ADD_OBJECT_SRCS)
22 message(FATAL_ERROR "'add_object_library' rule requires SRCS to be specified.")
25 get_fq_target_name(${target_name} fq_target_name)
32 target_include_directories(
35 ${LIBC_BUILD_DIR}/include
39 if(ADD_OBJECT_COMPILE_OPTIONS)
40 target_compile_options(
42 PRIVATE ${ADD_OBJECT_COMPILE_OPTIONS}
46 get_fq_deps_list(fq_deps_list ${ADD_OBJECT_DEPENDS})
48 add_dependencies(${fq_target_name} ${fq_deps_list})
51 set_target_properties(
54 "TARGET_TYPE" ${OBJECT_LIBRARY_TARGET_TYPE}
55 "OBJECT_FILES" "$<TARGET_OBJECTS:${fq_target_name}>"
56 "DEPS" "${fq_deps_list}"
58 endfunction(add_object_library)
60 set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ")
62 # A rule for entrypoint object targets.
64 # add_entrypoint_object(
66 # [ALIAS|REDIRECTED] # Specified if the entrypoint is redirected or an alias.
67 # [NAME] <the C name of the entrypoint if different from target_name>
68 # SRCS <list of .cpp files>
69 # HDRS <list of .h files>
70 # DEPENDS <list of dependencies>
71 # COMPILE_OPTIONS <optional list of special compile options for this target>
72 # SPECIAL_OBJECTS <optional list of special object targets added by the rule `add_object`>
74 function(add_entrypoint_object target_name)
75 cmake_parse_arguments(
77 "ALIAS;REDIRECTED" # Optional argument
78 "NAME" # Single value arguments
79 "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi value arguments
83 get_fq_target_name(${target_name} fq_target_name)
85 if(ADD_ENTRYPOINT_OBJ_ALIAS)
86 # Alias targets help one add aliases to other entrypoint object targets.
87 # One can use alias targets setup OS/machine independent entrypoint targets.
88 list(LENGTH ADD_ENTRYPOINT_OBJ_DEPENDS deps_size)
89 if(NOT (${deps_size} EQUAL "1"))
90 message(FATAL_ERROR "An entrypoint alias should have exactly one dependency.")
92 list(GET ADD_ENTRYPOINT_OBJ_DEPENDS 0 dep_target)
93 get_fq_dep_name(fq_dep_name ${dep_target})
94 if(NOT TARGET ${fq_dep_name})
95 message(WARNING "Aliasee ${fq_dep_name} for entrypoint alias ${target_name} missing; "
96 "Target ${target_name} will be ignored.")
100 get_target_property(obj_type ${fq_dep_name} "TARGET_TYPE")
101 if((NOT obj_type) OR (NOT (${obj_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})))
102 message(FATAL_ERROR "The aliasee of an entrypoint alias should be an entrypoint.")
105 add_custom_target(${fq_target_name})
106 add_dependencies(${fq_target_name} ${fq_dep_name})
107 get_target_property(object_file ${fq_dep_name} "OBJECT_FILE")
108 get_target_property(object_file_raw ${fq_dep_name} "OBJECT_FILE_RAW")
109 set_target_properties(
112 "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
116 "DEPS" "${fq_dep_name}"
121 if(NOT ADD_ENTRYPOINT_OBJ_SRCS)
122 message(FATAL_ERROR "`add_entrypoint_object` rule requires SRCS to be specified.")
124 if(NOT ADD_ENTRYPOINT_OBJ_HDRS)
125 message(FATAL_ERROR "`add_entrypoint_object` rule requires HDRS to be specified.")
128 set(entrypoint_name ${target_name})
129 if(ADD_ENTRYPOINT_OBJ_NAME)
130 set(entrypoint_name ${ADD_ENTRYPOINT_OBJ_NAME})
133 set(objects_target_name "${fq_target_name}_objects")
136 ${objects_target_name}
137 # We want an object library as the objects will eventually get packaged into
138 # an archive (like libc.a).
140 ${ADD_ENTRYPOINT_OBJ_SRCS}
141 ${ADD_ENTRYPOINT_OBJ_HDRS}
143 target_compile_options(
144 ${objects_target_name}
147 -fpie ${LLVM_CXX_STD_default} -ffreestanding
149 target_include_directories(
150 ${objects_target_name}
152 ${LIBC_BUILD_DIR}/include
156 get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS})
158 ${objects_target_name}
159 libc.src.__support.common
163 if(ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS)
164 target_compile_options(
165 ${objects_target_name}
166 PRIVATE ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS}
170 set(object_file_raw "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_raw.o")
171 set(object_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.o")
173 set(input_objects $<TARGET_OBJECTS:${objects_target_name}>)
175 OUTPUT ${object_file_raw}
176 DEPENDS ${input_objects}
177 COMMAND ${CMAKE_LINKER} -r ${input_objects} -o ${object_file_raw}
180 set(alias_attributes "0,function,global")
181 if(ADD_ENTRYPOINT_OBJ_REDIRECTED)
182 set(alias_attributes "${alias_attributes},hidden")
186 OUTPUT ${object_file}
187 # We llvm-objcopy here as GNU-binutils objcopy does not support the 'hidden' flag.
188 DEPENDS ${object_file_raw} ${llvm-objcopy}
189 COMMAND $<TARGET_FILE:llvm-objcopy> --add-symbol
190 "${entrypoint_name}=.llvm.libc.entrypoint.${entrypoint_name}:${alias_attributes}"
191 ${object_file_raw} ${object_file}
197 DEPENDS ${object_file}
199 set_target_properties(
202 "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
203 "OBJECT_FILE" "${object_file}"
204 "OBJECT_FILE_RAW" "${object_file_raw}"
205 "DEPS" "${fq_deps_list}"
208 if(LLVM_LIBC_ENABLE_LINTING)
210 # We only want a second invocation of clang-tidy to run
211 # restrict-system-libc-headers if the compiler-resource-dir was set in
212 # order to prevent false-positives due to a mismatch between the host
213 # compiler and the compiled clang-tidy.
214 if(COMPILER_RESOURCE_DIR)
215 # We run restrict-system-libc-headers with --system-headers to prevent
216 # transitive inclusion through compler provided headers.
217 set(restrict_system_headers_check_invocation
218 COMMAND $<TARGET_FILE:clang-tidy> --system-headers
219 --checks="-*,llvmlibc-restrict-system-libc-headers"
220 # We explicitly set the resource dir here to match the
221 # resource dir of the host compiler.
222 "--extra-arg=-resource-dir=${COMPILER_RESOURCE_DIR}"
224 -p ${PROJECT_BINARY_DIR}
225 ${ADD_ENTRYPOINT_OBJ_SRCS}
228 set(restrict_system_headers_check_invocation
229 COMMAND ${CMAKE_COMMAND} -E echo "Header file check skipped")
232 set(lint_timestamp "${CMAKE_CURRENT_BINARY_DIR}/.${target_name}.__lint_timestamp__")
234 OUTPUT ${lint_timestamp}
235 # --quiet is used to surpress warning statistics from clang-tidy like:
236 # Suppressed X warnings (X in non-user code).
237 # There seems to be a bug in clang-tidy where by even with --quiet some
238 # messages from clang's own diagnostics engine leak through:
239 # X warnings generated.
240 # Until this is fixed upstream, we use -fno-caret-diagnostics to surpress
242 COMMAND $<TARGET_FILE:clang-tidy>
243 "--extra-arg=-fno-caret-diagnostics" --quiet
244 # Path to directory containing compile_commands.json
245 -p ${PROJECT_BINARY_DIR}
246 ${ADD_ENTRYPOINT_OBJ_SRCS}
247 # See above: this might be a second invocation of clang-tidy depending on
248 # the conditions above.
249 ${restrict_system_headers_check_invocation}
250 # We have two options for running commands, add_custom_command and
251 # add_custom_target. We don't want to run the linter unless source files
252 # have changed. add_custom_target explicitly runs everytime therefore we
253 # use add_custom_command. This function requires an output file and since
254 # linting doesn't produce a file, we create a dummy file using a
255 # crossplatform touch.
256 COMMAND "${CMAKE_COMMAND}" -E touch ${lint_timestamp}
257 COMMENT "Linting... ${target_name}"
258 DEPENDS ${clang-tidy} ${objects_target_name} ${ADD_ENTRYPOINT_OBJ_SRCS}
259 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
262 add_custom_target(${fq_target_name}.__lint__
263 DEPENDS ${lint_timestamp})
264 add_dependencies(lint-libc ${fq_target_name}.__lint__)
265 add_dependencies(${fq_target_name} ${fq_target_name}.__lint__)
268 endfunction(add_entrypoint_object)
270 # Rule build a redirector object file.
271 function(add_redirector_object target_name)
272 cmake_parse_arguments(
274 "" # No optional arguments
275 "SRC" # The cpp file in which the redirector is defined.
276 "" # No multivalue arguments
279 if(NOT REDIRECTOR_OBJECT_SRC)
280 message(FATAL_ERROR "'add_redirector_object' rule requires SRC option listing one source file.")
286 ${REDIRECTOR_OBJECT_SRC}
288 target_compile_options(
292 endfunction(add_redirector_object)