[Reland][Runtimes] Merge 'compile_commands.json' files from runtimes build (#116303)
[llvm-project.git] / libc / cmake / modules / LLVMLibCHeaderRules.cmake
blob76c4e1f2d3244c15ad0fbf10ccfee8e6f0f4b584
1 # A rule for self contained header file targets.
2 # This rule merely copies the header file from the current source directory to
3 # the current binary directory.
4 # Usage:
5 #     add_header(
6 #       <target name>
7 #       HDR <header file>
8 #     )
9 function(add_header target_name)
10   cmake_parse_arguments(
11     "ADD_HEADER"
12     ""             # No optional arguments
13     "HDR;DEST_HDR" # Single value arguments
14     "DEPENDS"
15     ${ARGN}
16   )
17   if(NOT ADD_HEADER_HDR)
18     message(FATAL_ERROR "'add_header' rules requires the HDR argument specifying a headef file.")
19   endif()
21   if(ADD_HEADER_DEST_HDR)
22     set(dest_leaf_filename ${ADD_HEADER_DEST_HDR})
23   else()
24     set(dest_leaf_filename ${ADD_HEADER_HDR})
25   endif()
26   set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${dest_leaf_filename})
27   file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_SOURCE_DIR} ${absolute_path})
28   set(dest_file ${LIBC_INCLUDE_DIR}/${relative_path})
29   set(src_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_HEADER_HDR})
31   add_custom_command(
32     OUTPUT ${dest_file}
33     COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dest_file}
34     DEPENDS ${src_file}
35   )
37   get_fq_target_name(${target_name} fq_target_name)
38   set(copied_hdr_target ${fq_target_name}.__copied_hdr__)
39   add_custom_target(
40     ${copied_hdr_target}
41     DEPENDS ${dest_file}
42   )
44   if(ADD_HEADER_DEPENDS)
45     get_fq_deps_list(fq_deps_list ${ADD_HEADER_DEPENDS})
46     # Dependencies of a add_header target can only be another add_header target
47     # or an add_gen_header target.
48     foreach(dep IN LISTS fq_deps_list)
49       get_target_property(header_file ${dep} HEADER_FILE_PATH)
50       if(NOT header_file)
51         message(FATAL_ERROR "Invalid dependency '${dep}' for '${fq_target_name}'.")
52       endif()
53     endforeach()
54     add_dependencies(
55       ${copied_hdr_target} ${fq_deps_list}
56     )
57   endif()
59   add_header_library(
60     ${target_name}
61     HDRS
62       ${dest_file}
63     DEPENDS
64       ${copied_hdr_target}
65   )
66   set_target_properties(
67     ${fq_target_name}
68     PROPERTIES
69       HEADER_FILE_PATH ${dest_file}
70       DEPS "${fq_deps_list}"
71   )
72 endfunction(add_header)
74 function(add_gen_header2 target_name)
75   cmake_parse_arguments(
76     "ADD_GEN_HDR2"
77     "PUBLIC" # No optional arguments
78     "YAML_FILE;DEF_FILE;GEN_HDR" # Single value arguments
79     "DEPENDS"     # Multi value arguments
80     ${ARGN}
81   )
82   get_fq_target_name(${target_name} fq_target_name)
83   if(NOT LLVM_LIBC_FULL_BUILD)
84     add_library(${fq_target_name} INTERFACE)
85     return()
86   endif()
87   if(NOT ADD_GEN_HDR2_DEF_FILE)
88     message(FATAL_ERROR "`add_gen_hdr2` rule requires DEF_FILE to be specified.")
89   endif()
90   if(NOT ADD_GEN_HDR2_GEN_HDR)
91     message(FATAL_ERROR "`add_gen_hdr2` rule requires GEN_HDR to be specified.")
92   endif()
93   if(NOT ADD_GEN_HDR2_YAML_FILE)
94     message(FATAL_ERROR "`add_gen_hdr2` rule requires YAML_FILE to be specified.")
95   endif()
97   set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_GEN_HDR2_GEN_HDR})
98   file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_SOURCE_DIR} ${absolute_path})
99   set(out_file ${LIBC_INCLUDE_DIR}/${relative_path})
100   set(yaml_file ${CMAKE_SOURCE_DIR}/${ADD_GEN_HDR2_YAML_FILE})
101   set(def_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_GEN_HDR2_DEF_FILE})
103   set(fq_data_files "")
104   if(ADD_GEN_HDR2_DATA_FILES)
105     foreach(data_file IN LISTS ADD_GEN_HDR2_DATA_FILES)
106       list(APPEND fq_data_files "${CMAKE_CURRENT_SOURCE_DIR}/${data_file}")
107     endforeach(data_file)
108   endif()
110   set(entry_points "${TARGET_ENTRYPOINT_NAME_LIST}")
111   list(TRANSFORM entry_points PREPEND "--e=")
113   add_custom_command(
114     OUTPUT ${out_file}
115     COMMAND ${Python3_EXECUTABLE} ${LIBC_SOURCE_DIR}/newhdrgen/yaml_to_classes.py
116             ${yaml_file}
117             --h_def_file ${def_file}
118             ${entry_points}
119             --output_dir ${out_file}
120     DEPENDS ${yaml_file} ${def_file} ${fq_data_files}
121     COMMENT "Generating header ${ADD_GEN_HDR2_GEN_HDR} from ${yaml_file} and ${def_file}"
122   )
123   if(LIBC_TARGET_OS_IS_GPU)
124     file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-decls)
125     file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-decls/gpu)
126     set(decl_out_file ${LIBC_INCLUDE_DIR}/llvm-libc-decls/${relative_path})
127     add_custom_command(
128       OUTPUT ${decl_out_file}
129       COMMAND ${Python3_EXECUTABLE} ${LIBC_SOURCE_DIR}/newhdrgen/yaml_to_classes.py
130               ${yaml_file}
131               --export-decls
132               ${entry_points}
133               --output_dir ${decl_out_file}
134       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
135       DEPENDS ${yaml_file} ${fq_data_files}
136     )
137   endif()
139   if(ADD_GEN_HDR2_DEPENDS)
140     get_fq_deps_list(fq_deps_list ${ADD_GEN_HDR2_DEPENDS})
141     # Dependencies of a add_header target can only be another add_gen_header target
142     # or an add_header target.
143     foreach(dep IN LISTS fq_deps_list)
144       get_target_property(header_file ${dep} HEADER_FILE_PATH)
145       if(NOT header_file)
146         message(FATAL_ERROR "Invalid dependency '${dep}' for '${fq_target_name}'.")
147       endif()
148     endforeach()
149   endif()
150   set(generated_hdr_target ${fq_target_name}.__generated_hdr__)
151   add_custom_target(
152     ${generated_hdr_target}
153     DEPENDS ${out_file} ${fq_deps_list} ${decl_out_file}
154   )
156   add_header_library(
157     ${target_name}
158     HDRS
159       ${out_file}
160   )
162   add_dependencies(${fq_target_name} ${generated_hdr_target})
164   set_target_properties(
165     ${fq_target_name}
166     PROPERTIES
167       HEADER_FILE_PATH ${out_file}
168       DECLS_FILE_PATH "${decl_out_file}"
169       DEPS "${fq_deps_list}"
170   )
173 endfunction(add_gen_header2)
175 # Usage:
176 #     add_gen_header(
177 #       <target name>
178 #       DEF_FILE <.h.def file>
179 #       GEN_HDR <generated header file name>
180 #       PARAMS <list of name=value pairs>
181 #       DATA_FILES <list input data files>
182 #     )
183 function(add_gen_header target_name)
184   cmake_parse_arguments(
185     "ADD_GEN_HDR"
186     "PUBLIC" # No optional arguments
187     "DEF_FILE;GEN_HDR" # Single value arguments
188     "PARAMS;DATA_FILES;DEPENDS"     # Multi value arguments
189     ${ARGN}
190   )
191   get_fq_target_name(${target_name} fq_target_name)
192   if(NOT LLVM_LIBC_FULL_BUILD)
193     # We don't want to use generated headers if we are doing a non-full-build.
194     add_library(${fq_target_name} INTERFACE)
195     return()
196   endif()
197   if(NOT ADD_GEN_HDR_DEF_FILE)
198     message(FATAL_ERROR "`add_gen_hdr` rule requires DEF_FILE to be specified.")
199   endif()
200   if(NOT ADD_GEN_HDR_GEN_HDR)
201     message(FATAL_ERROR "`add_gen_hdr` rule requires GEN_HDR to be specified.")
202   endif()
204   set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_GEN_HDR_GEN_HDR})
205   file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_SOURCE_DIR} ${absolute_path})
206   set(out_file ${LIBC_INCLUDE_DIR}/${relative_path})
207   set(in_file ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_GEN_HDR_DEF_FILE})
209   set(fq_data_files "")
210   if(ADD_GEN_HDR_DATA_FILES)
211     foreach(data_file IN LISTS ADD_GEN_HDR_DATA_FILES)
212       list(APPEND fq_data_files "${CMAKE_CURRENT_SOURCE_DIR}/${data_file}")
213     endforeach(data_file)
214   endif()
216   set(replacement_params "")
217   if(ADD_GEN_HDR_PARAMS)
218     list(APPEND replacement_params "--args" ${ADD_GEN_HDR_PARAMS})
219   endif()
221   set(gen_hdr_script "${LIBC_BUILD_SCRIPTS_DIR}/gen_hdr.py")
223   file(GLOB td_includes ${LIBC_SOURCE_DIR}/spec/*.td)
225   set(ENTRYPOINT_NAME_LIST_ARG ${TARGET_ENTRYPOINT_NAME_LIST})
226   list(TRANSFORM ENTRYPOINT_NAME_LIST_ARG PREPEND "--e=")
228   if(LIBC_HDRGEN_EXE)
229     set(hdrgen_exe ${LIBC_HDRGEN_EXE})
230   else()
231     set(hdrgen_exe ${LIBC_TABLEGEN_EXE})
232     set(hdrgen_deps "${LIBC_TABLEGEN_EXE};${LIBC_TABLEGEN_TARGET}")
233   endif()
234   add_custom_command(
235     OUTPUT ${out_file}
236     COMMAND ${hdrgen_exe} -o ${out_file} --header ${ADD_GEN_HDR_GEN_HDR}
237             --def ${in_file} ${replacement_params} -I ${LIBC_SOURCE_DIR}
238            ${ENTRYPOINT_NAME_LIST_ARG}
239            ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
241     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
242     DEPENDS ${in_file} ${fq_data_files} ${td_includes}
243             ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
244             ${hdrgen_deps}
245   )
247   if(LIBC_TARGET_OS_IS_GPU)
248     file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-decls)
249     file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-decls/gpu)
250     set(decl_out_file ${LIBC_INCLUDE_DIR}/llvm-libc-decls/${relative_path})
251     add_custom_command(
252       OUTPUT ${decl_out_file}
253       COMMAND ${hdrgen_exe} -o ${decl_out_file}
254               --header ${ADD_GEN_HDR_GEN_HDR} --def ${in_file} --export-decls
255               ${replacement_params} -I ${LIBC_SOURCE_DIR} ${ENTRYPOINT_NAME_LIST_ARG}
256               ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
258       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
259       DEPENDS ${in_file} ${fq_data_files} ${td_includes}
260               ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
261               ${hdrgen_deps}
262     )
263   endif()
265   if(ADD_GEN_HDR_DEPENDS)
266     get_fq_deps_list(fq_deps_list ${ADD_GEN_HDR_DEPENDS})
267     # Dependencies of a add_header target can only be another add_gen_header target
268     # or an add_header target.
269     foreach(dep IN LISTS fq_deps_list)
270       get_target_property(header_file ${dep} HEADER_FILE_PATH)
271       if(NOT header_file)
272         message(FATAL_ERROR "Invalid dependency '${dep}' for '${fq_target_name}'.")
273       endif()
274     endforeach()
275   endif()
276   set(generated_hdr_target ${fq_target_name}.__generated_hdr__)
277   add_custom_target(
278     ${generated_hdr_target}
279     DEPENDS ${out_file} ${fq_deps_list} ${decl_out_file}
280   )
282   add_header_library(
283     ${target_name}
284     HDRS
285       ${out_file}
286   )
288   # We add the dependencies separately and not list under add_header_library's
289   # DEPENDS option above. This is because, deps of add_header_library are
290   # used with target_link_libraries.
291   add_dependencies(${fq_target_name} ${generated_hdr_target})
293   set_target_properties(
294     ${fq_target_name}
295     PROPERTIES
296       HEADER_FILE_PATH ${out_file}
297       DECLS_FILE_PATH "${decl_out_file}"
298       DEPS "${fq_deps_list}"
299   )
300 endfunction(add_gen_header)