[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / mlir / cmake / modules / AddMLIR.cmake
blob544abe43688820e37db81ee08bfc165cc0328f26
1 include(GNUInstallDirs)
2 include(LLVMDistributionSupport)
4 # Clear out any pre-existing compile_commands file before processing. This
5 # allows for generating a clean compile_commands on each configure.
6 file(REMOVE ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml)
8 function(mlir_tablegen ofn)
9   tablegen(MLIR ${ARGV})
10   set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
11       PARENT_SCOPE)
13   # Get the current set of include paths for this td file.
14   cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN})
15   get_directory_property(tblgen_includes INCLUDE_DIRECTORIES)
16   list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES})
17   # Filter out any empty include items.
18   list(REMOVE_ITEM tblgen_includes "")
20   # Build the absolute path for the current input file.
21   if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
22     set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
23   else()
24     set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS})
25   endif()
27   # Append the includes used for this file to the tablegen_compile_commands
28   # file.
29   file(APPEND ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml
30       "--- !FileInfo:\n"
31       "  filepath: \"${LLVM_TARGET_DEFINITIONS_ABSOLUTE}\"\n"
32       "  includes: \"${CMAKE_CURRENT_SOURCE_DIR};${tblgen_includes}\"\n"
33   )
34 endfunction()
36 # Clear out any pre-existing compile_commands file before processing. This
37 # allows for generating a clean compile_commands on each configure.
38 file(REMOVE ${CMAKE_BINARY_DIR}/pdll_compile_commands.yml)
40 # Declare a helper function/copy of tablegen rule for using tablegen without
41 # additional tblgen specific flags when invoking PDLL generator.
42 function(_pdll_tablegen project ofn)
43   cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN})
44   # Validate calling context.
45   if(NOT ${project}_TABLEGEN_EXE)
46     message(FATAL_ERROR "${project}_TABLEGEN_EXE not set")
47   endif()
49   # Use depfile instead of globbing arbitrary *.td(s) for Ninja.
50   if(CMAKE_GENERATOR MATCHES "Ninja")
51     # Make output path relative to build.ninja, assuming located on
52     # ${CMAKE_BINARY_DIR}.
53     # CMake emits build targets as relative paths but Ninja doesn't identify
54     # absolute path (in *.d) as relative path (in build.ninja)
55     # Note that tblgen is executed on ${CMAKE_BINARY_DIR} as working directory.
56     file(RELATIVE_PATH ofn_rel
57       ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${ofn})
58     set(additional_cmdline
59       -o ${ofn_rel}
60       -d ${ofn_rel}.d
61       WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
62       DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.d
63       )
64     set(local_tds)
65     set(global_tds)
66   else()
67     file(GLOB local_tds "*.td")
68     file(GLOB_RECURSE global_tds "${LLVM_MAIN_INCLUDE_DIR}/llvm/*.td")
69     set(additional_cmdline
70       -o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
71       )
72   endif()
74   if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
75     set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
76   else()
77     set(LLVM_TARGET_DEFINITIONS_ABSOLUTE
78       ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS})
79   endif()
81   if (CMAKE_GENERATOR MATCHES "Visual Studio")
82     # Visual Studio has problems with llvm-tblgen's native --write-if-changed
83     # behavior. Since it doesn't do restat optimizations anyway, just don't
84     # pass --write-if-changed there.
85     set(tblgen_change_flag)
86   else()
87     set(tblgen_change_flag "--write-if-changed")
88   endif()
90   # We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the  DEPENDS list
91   # (both the target and the file) to have .inc files rebuilt on
92   # a tablegen change, as cmake does not propagate file-level dependencies
93   # of custom targets. See the following ticket for more information:
94   # https://cmake.org/Bug/view.php?id=15858
95   # The dependency on both, the target and the file, produces the same
96   # dependency twice in the result file when
97   # ("${${project}_TABLEGEN_TARGET}" STREQUAL "${${project}_TABLEGEN_EXE}")
98   # but lets us having smaller and cleaner code here.
99   get_directory_property(tblgen_includes INCLUDE_DIRECTORIES)
100   list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES})
101   # Filter out empty items before prepending each entry with -I
102   list(REMOVE_ITEM tblgen_includes "")
103   list(TRANSFORM tblgen_includes PREPEND -I)
105   set(tablegen_exe ${${project}_TABLEGEN_EXE})
106   set(tablegen_depends ${${project}_TABLEGEN_TARGET} ${tablegen_exe})
108   add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
109     COMMAND ${tablegen_exe} ${ARG_UNPARSED_ARGUMENTS} -I ${CMAKE_CURRENT_SOURCE_DIR}
110     ${tblgen_includes}
111     ${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
112     ${tblgen_change_flag}
113     ${additional_cmdline}
114     # The file in LLVM_TARGET_DEFINITIONS may be not in the current
115     # directory and local_tds may not contain it, so we must
116     # explicitly list it here:
117     DEPENDS ${ARG_DEPENDS} ${tablegen_depends}
118       ${local_tds} ${global_tds}
119     ${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
120     ${LLVM_TARGET_DEPENDS}
121     COMMENT "Building ${ofn}..."
122     )
124   # `make clean' must remove all those generated files:
125   set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn})
127   set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE)
128   set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES
129     GENERATED 1)
130 endfunction()
132 # Declare a PDLL library in the current directory.
133 function(add_mlir_pdll_library target inputFile ofn)
134   set(LLVM_TARGET_DEFINITIONS ${inputFile})
136   _pdll_tablegen(MLIR_PDLL ${ofn} -x=cpp ${ARGN})
137   set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
138       PARENT_SCOPE)
140   # Get the current set of include paths for this pdll file.
141   cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN})
142   get_directory_property(tblgen_includes INCLUDE_DIRECTORIES)
143   list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES})
144   # Filter out any empty include items.
145   list(REMOVE_ITEM tblgen_includes "")
147   # Build the absolute path for the current input file.
148   if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
149     set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${inputFile})
150   else()
151     set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/${inputFile})
152   endif()
154   # Append the includes used for this file to the pdll_compilation_commands
155   # file.
156   file(APPEND ${CMAKE_BINARY_DIR}/pdll_compile_commands.yml
157       "--- !FileInfo:\n"
158       "  filepath: \"${LLVM_TARGET_DEFINITIONS_ABSOLUTE}\"\n"
159       "  includes: \"${CMAKE_CURRENT_SOURCE_DIR};${tblgen_includes}\"\n"
160   )
162   add_public_tablegen_target(${target})
163 endfunction()
165 # Declare a dialect in the include directory
166 function(add_mlir_dialect dialect dialect_namespace)
167   set(LLVM_TARGET_DEFINITIONS ${dialect}.td)
168   mlir_tablegen(${dialect}.h.inc -gen-op-decls)
169   mlir_tablegen(${dialect}.cpp.inc -gen-op-defs)
170   mlir_tablegen(${dialect}Types.h.inc -gen-typedef-decls -typedefs-dialect=${dialect_namespace})
171   mlir_tablegen(${dialect}Types.cpp.inc -gen-typedef-defs -typedefs-dialect=${dialect_namespace})
172   mlir_tablegen(${dialect}Dialect.h.inc -gen-dialect-decls -dialect=${dialect_namespace})
173   mlir_tablegen(${dialect}Dialect.cpp.inc -gen-dialect-defs -dialect=${dialect_namespace})
174   add_public_tablegen_target(MLIR${dialect}IncGen)
175   add_dependencies(mlir-headers MLIR${dialect}IncGen)
176 endfunction()
178 # Declare a dialect in the include directory
179 function(add_mlir_interface interface)
180   set(LLVM_TARGET_DEFINITIONS ${interface}.td)
181   mlir_tablegen(${interface}.h.inc -gen-op-interface-decls)
182   mlir_tablegen(${interface}.cpp.inc -gen-op-interface-defs)
183   add_public_tablegen_target(MLIR${interface}IncGen)
184   add_dependencies(mlir-generic-headers MLIR${interface}IncGen)
185 endfunction()
188 # Generate Documentation
189 function(add_mlir_doc doc_filename output_file output_directory command)
190   set(LLVM_TARGET_DEFINITIONS ${doc_filename}.td)
191   # The MLIR docs use Hugo, so we allow Hugo specific features here.
192   tablegen(MLIR ${output_file}.md ${command} -allow-hugo-specific-features ${ARGN})
193   set(GEN_DOC_FILE ${MLIR_BINARY_DIR}/docs/${output_directory}${output_file}.md)
194   add_custom_command(
195           OUTPUT ${GEN_DOC_FILE}
196           COMMAND ${CMAKE_COMMAND} -E copy
197                   ${CMAKE_CURRENT_BINARY_DIR}/${output_file}.md
198                   ${GEN_DOC_FILE}
199           DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${output_file}.md)
200   add_custom_target(${output_file}DocGen DEPENDS ${GEN_DOC_FILE})
201   add_dependencies(mlir-doc ${output_file}DocGen)
202 endfunction()
204 # Sets ${srcs} to contain the list of additional headers for the target. Extra
205 # arguments are included into the list of additional headers.
206 function(_set_mlir_additional_headers_as_srcs)
207   set(srcs)
208   if(MSVC_IDE OR XCODE)
209     # Add public headers
210     file(RELATIVE_PATH lib_path
211       ${MLIR_SOURCE_DIR}/lib/
212       ${CMAKE_CURRENT_SOURCE_DIR}
213     )
214     if(NOT lib_path MATCHES "^[.][.]")
215       file( GLOB_RECURSE headers
216         ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.h
217         ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.def
218       )
219       set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON)
221       file( GLOB_RECURSE tds
222         ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.td
223       )
224       source_group("TableGen descriptions" FILES ${tds})
225       set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON)
227       if(headers OR tds)
228         set(srcs ${headers} ${tds})
229       endif()
230     endif()
231   endif(MSVC_IDE OR XCODE)
232   if(srcs OR ARGN)
233     set(srcs
234       ADDITIONAL_HEADERS
235       ${srcs}
236       ${ARGN} # It may contain unparsed unknown args.
237       PARENT_SCOPE
238       )
239   endif()
240 endfunction()
242 # Checks that the LLVM components are not listed in the extra arguments,
243 # assumed to be coming from the LINK_LIBS variable.
244 function(_check_llvm_components_usage name)
245   # LINK_COMPONENTS is necessary to allow libLLVM.so to be properly
246   # substituted for individual library dependencies if LLVM_LINK_LLVM_DYLIB
247   # Perhaps this should be in llvm_add_library instead?  However, it fails
248   # on libclang-cpp.so
249   get_property(llvm_component_libs GLOBAL PROPERTY LLVM_COMPONENT_LIBS)
250   foreach(lib ${ARGN})
251     if(${lib} IN_LIST llvm_component_libs)
252       message(SEND_ERROR "${name} specifies LINK_LIBS ${lib}, but LINK_LIBS cannot be used for LLVM libraries.  Please use LINK_COMPONENTS instead.")
253     endif()
254   endforeach()
255 endfunction()
257 function(add_mlir_example_library name)
258   cmake_parse_arguments(ARG
259     "SHARED;DISABLE_INSTALL"
260     ""
261     "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS"
262     ${ARGN})
263   _set_mlir_additional_headers_as_srcs(${ARG_ADDITIONAL_HEADERS})
264   if (ARG_SHARED)
265     set(LIBTYPE SHARED)
266   else()
267     if(BUILD_SHARED_LIBS)
268       set(LIBTYPE SHARED)
269     else()
270       set(LIBTYPE STATIC)
271     endif()
272   endif()
274   # MLIR libraries uniformly depend on LLVMSupport.  Just specify it once here.
275   list(APPEND ARG_LINK_COMPONENTS Support)
276   _check_llvm_components_usage(${name} ${ARG_LINK_LIBS})
278   list(APPEND ARG_DEPENDS mlir-generic-headers)
280   llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs} DEPENDS ${ARG_DEPENDS} LINK_COMPONENTS ${ARG_LINK_COMPONENTS} LINK_LIBS ${ARG_LINK_LIBS})
281   set_target_properties(${name} PROPERTIES FOLDER "Examples")
282   if (LLVM_BUILD_EXAMPLES AND NOT ${ARG_DISABLE_INSTALL})
283     add_mlir_library_install(${name})
284   else()
285     set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL ON)
286   endif()
287 endfunction()
289 # Declare an mlir library which can be compiled in libMLIR.so
290 # In addition to everything that llvm_add_library accepts, this
291 # also has the following option:
292 # EXCLUDE_FROM_LIBMLIR
293 #   Don't include this library in libMLIR.so.  This option should be used
294 #   for test libraries, executable-specific libraries, or rarely used libraries
295 #   with large dependencies.
296 # ENABLE_AGGREGATION
297 #   Forces generation of an OBJECT library, exports additional metadata,
298 #   and installs additional object files needed to include this as part of an
299 #   aggregate shared library.
300 #   TODO: Make this the default for all MLIR libraries once all libraries
301 #   are compatible with building an object library.
302 function(add_mlir_library name)
303   cmake_parse_arguments(ARG
304     "SHARED;INSTALL_WITH_TOOLCHAIN;EXCLUDE_FROM_LIBMLIR;DISABLE_INSTALL;ENABLE_AGGREGATION"
305     ""
306     "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS"
307     ${ARGN})
308   _set_mlir_additional_headers_as_srcs(${ARG_ADDITIONAL_HEADERS})
310   # Is an object library needed.
311   set(NEEDS_OBJECT_LIB OFF)
312   if(ARG_ENABLE_AGGREGATION)
313     set(NEEDS_OBJECT_LIB ON)
314   endif()
316   # Determine type of library.
317   if(ARG_SHARED)
318     set(LIBTYPE SHARED)
319   else()
320     # llvm_add_library ignores BUILD_SHARED_LIBS if STATIC is explicitly set,
321     # so we need to handle it here.
322     if(BUILD_SHARED_LIBS)
323       set(LIBTYPE SHARED)
324     else()
325       set(LIBTYPE STATIC)
326     endif()
327     # Test libraries and such shouldn't be include in libMLIR.so
328     if(NOT ARG_EXCLUDE_FROM_LIBMLIR)
329       set(NEEDS_OBJECT_LIB ON)
330       set_property(GLOBAL APPEND PROPERTY MLIR_STATIC_LIBS ${name})
331       set_property(GLOBAL APPEND PROPERTY MLIR_LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
332       set_property(GLOBAL APPEND PROPERTY MLIR_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS})
333     endif()
334   endif()
336   if(NEEDS_OBJECT_LIB AND NOT XCODE)
337     # The Xcode generator doesn't handle object libraries correctly.
338     # We special case xcode when building aggregates.
339     list(APPEND LIBTYPE OBJECT)
340   endif()
342   # MLIR libraries uniformly depend on LLVMSupport.  Just specify it once here.
343   list(APPEND ARG_LINK_COMPONENTS Support)
344   _check_llvm_components_usage(${name} ${ARG_LINK_LIBS})
346   list(APPEND ARG_DEPENDS mlir-generic-headers)
347   llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs} DEPENDS ${ARG_DEPENDS} LINK_COMPONENTS ${ARG_LINK_COMPONENTS} LINK_LIBS ${ARG_LINK_LIBS})
349   if(TARGET ${name})
350     target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS})
351     if(NOT ARG_DISABLE_INSTALL)
352       add_mlir_library_install(${name})
353     endif()
354   else()
355     # Add empty "phony" target
356     add_custom_target(${name})
357   endif()
358   set_target_properties(${name} PROPERTIES FOLDER "MLIR libraries")
360   # Setup aggregate.
361   if(ARG_ENABLE_AGGREGATION)
362     # Compute and store the properties needed to build aggregates.
363     set(AGGREGATE_OBJECTS)
364     set(AGGREGATE_OBJECT_LIB)
365     set(AGGREGATE_DEPS)
366     if(XCODE)
367       # XCode has limited support for object libraries. Instead, add dep flags
368       # that force the entire library to be embedded.
369       list(APPEND AGGREGATE_DEPS "-force_load" "${name}")
370     else()
371       list(APPEND AGGREGATE_OBJECTS "$<TARGET_OBJECTS:obj.${name}>")
372       list(APPEND AGGREGATE_OBJECT_LIB "obj.${name}")
373     endif()
375     # For each declared dependency, transform it into a generator expression
376     # which excludes it if the ultimate link target is excluding the library.
377     set(NEW_LINK_LIBRARIES)
378     get_target_property(CURRENT_LINK_LIBRARIES  ${name} LINK_LIBRARIES)
379     get_mlir_filtered_link_libraries(NEW_LINK_LIBRARIES ${CURRENT_LINK_LIBRARIES})
380     set_target_properties(${name} PROPERTIES LINK_LIBRARIES "${NEW_LINK_LIBRARIES}")
381     list(APPEND AGGREGATE_DEPS ${NEW_LINK_LIBRARIES})
382     set_target_properties(${name} PROPERTIES
383       EXPORT_PROPERTIES "MLIR_AGGREGATE_OBJECT_LIB_IMPORTED;MLIR_AGGREGATE_DEP_LIBS_IMPORTED"
384       MLIR_AGGREGATE_OBJECTS "${AGGREGATE_OBJECTS}"
385       MLIR_AGGREGATE_DEPS "${AGGREGATE_DEPS}"
386       MLIR_AGGREGATE_OBJECT_LIB_IMPORTED "${AGGREGATE_OBJECT_LIB}"
387       MLIR_AGGREGATE_DEP_LIBS_IMPORTED "${CURRENT_LINK_LIBRARIES}"
388     )
390     # In order for out-of-tree projects to build aggregates of this library,
391     # we need to install the OBJECT library.
392     if(MLIR_INSTALL_AGGREGATE_OBJECTS AND NOT ARG_DISABLE_INSTALL)
393       add_mlir_library_install(obj.${name})
394     endif()
395   endif()
396 endfunction(add_mlir_library)
398 macro(add_mlir_tool name)
399   llvm_add_tool(MLIR ${ARGV})
400 endmacro()
402 # Sets a variable with a transformed list of link libraries such individual
403 # libraries will be dynamically excluded when evaluated on a final library
404 # which defines an MLIR_AGGREGATE_EXCLUDE_LIBS which contains any of the
405 # libraries. Each link library can be a generator expression but must not
406 # resolve to an arity > 1 (i.e. it can be optional).
407 function(get_mlir_filtered_link_libraries output)
408   set(_results)
409   foreach(linklib ${ARGN})
410     # In English, what this expression does:
411     # For each link library, resolve the property MLIR_AGGREGATE_EXCLUDE_LIBS
412     # on the context target (i.e. the executable or shared library being linked)
413     # and, if it is not in that list, emit the library name. Otherwise, empty.
414     list(APPEND _results
415       "$<$<NOT:$<IN_LIST:${linklib},$<GENEX_EVAL:$<TARGET_PROPERTY:MLIR_AGGREGATE_EXCLUDE_LIBS>>>>:${linklib}>"
416     )
417   endforeach()
418   set(${output} "${_results}" PARENT_SCOPE)
419 endfunction(get_mlir_filtered_link_libraries)
421 # Declares an aggregate library. Such a library is a combination of arbitrary
422 # regular add_mlir_library() libraries with the special feature that they can
423 # be configured to statically embed some subset of their dependencies, as is
424 # typical when creating a .so/.dylib/.dll or a mondo static library.
426 # It is always safe to depend on the aggregate directly in order to compile/link
427 # against the superset of embedded entities and transitive deps.
429 # Arguments:
430 #   PUBLIC_LIBS: list of dependent libraries to add to the
431 #     INTERFACE_LINK_LIBRARIES property, exporting them to users. This list
432 #     will be transitively filtered to exclude any EMBED_LIBS.
433 #   EMBED_LIBS: list of dependent libraries that should be embedded directly
434 #     into this library. Each of these must be an add_mlir_library() library
435 #     without DISABLE_AGGREGATE.
437 # Note: This is a work in progress and is presently only sufficient for certain
438 # non nested cases involving the C-API.
439 function(add_mlir_aggregate name)
440   cmake_parse_arguments(ARG
441     "SHARED;STATIC"
442     ""
443     "PUBLIC_LIBS;EMBED_LIBS"
444     ${ARGN})
445   set(_libtype)
446   if(ARG_STATIC)
447     list(APPEND _libtype STATIC)
448   endif()
449   if(ARG_SHARED)
450     list(APPEND _libtype SHARED)
451   endif()
452   set(_debugmsg)
454   set(_embed_libs)
455   set(_objects)
456   set(_deps)
457   foreach(lib ${ARG_EMBED_LIBS})
458     # We have to handle imported vs in-tree differently:
459     #   in-tree: To support arbitrary ordering, the generator expressions get
460     #     set on the dependent target when it is constructed and then just
461     #     eval'd here. This means we can build an aggregate from targets that
462     #     may not yet be defined, which is typical for in-tree.
463     #   imported: Exported properties do not support generator expressions, so
464     #     we imperatively query and manage the expansion here. This is fine
465     #     because imported targets will always be found/configured first and
466     #     do not need to support arbitrary ordering. If CMake every supports
467     #     exporting generator expressions, then this can be simplified.
468     set(_is_imported OFF)
469     if(TARGET ${lib})
470       get_target_property(_is_imported ${lib} IMPORTED)
471     endif()
473     if(NOT _is_imported)
474       # Evaluate the in-tree generator expressions directly (this allows target
475       # order independence, since these aren't evaluated until the generate
476       # phase).
477       # What these expressions do:
478       # In the context of this aggregate, resolve the list of OBJECTS and DEPS
479       # that each library advertises and patch it into the whole.
480       set(_local_objects $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${lib},MLIR_AGGREGATE_OBJECTS>>)
481       set(_local_deps $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${lib},MLIR_AGGREGATE_DEPS>>)
482     else()
483       # It is an imported target, which can only have flat strings populated
484       # (no generator expressions).
485       # Rebuild the generator expressions from the imported flat string lists.
486       if(NOT MLIR_INSTALL_AGGREGATE_OBJECTS)
487         message(SEND_ERROR "Cannot build aggregate from imported targets which were not installed via MLIR_INSTALL_AGGREGATE_OBJECTS (for ${lib}).")
488       endif()
490       get_property(_has_object_lib_prop TARGET ${lib} PROPERTY MLIR_AGGREGATE_OBJECT_LIB_IMPORTED SET)
491       get_property(_has_dep_libs_prop TARGET ${lib} PROPERTY MLIR_AGGREGATE_DEP_LIBS_IMPORTED SET)
492       if(NOT _has_object_lib_prop OR NOT _has_dep_libs_prop)
493         message(SEND_ERROR "Cannot create an aggregate out of imported ${lib}: It is missing properties indicating that it was built for aggregation")
494       endif()
495       get_target_property(_imp_local_object_lib ${lib} MLIR_AGGREGATE_OBJECT_LIB_IMPORTED)
496       get_target_property(_imp_dep_libs ${lib} MLIR_AGGREGATE_DEP_LIBS_IMPORTED)
497       set(_local_objects)
498       if(_imp_local_object_lib)
499         set(_local_objects "$<TARGET_OBJECTS:${_imp_local_object_lib}>")
500       endif()
501       # We should just be able to do this:
502       #   get_mlir_filtered_link_libraries(_local_deps ${_imp_dep_libs})
503       # However, CMake complains about the unqualified use of the one-arg
504       # $<TARGET_PROPERTY> expression. So we do the same thing but use the
505       # two-arg form which takes an explicit target.
506       foreach(_imp_dep_lib ${_imp_dep_libs})
507         # In English, what this expression does:
508         # For each link library, resolve the property MLIR_AGGREGATE_EXCLUDE_LIBS
509         # on the context target (i.e. the executable or shared library being linked)
510         # and, if it is not in that list, emit the library name. Otherwise, empty.
511         list(APPEND _local_deps
512           "$<$<NOT:$<IN_LIST:${_imp_dep_lib},$<GENEX_EVAL:$<TARGET_PROPERTY:${name},MLIR_AGGREGATE_EXCLUDE_LIBS>>>>:${_imp_dep_lib}>"
513         )
514       endforeach()
515     endif()
517     list(APPEND _embed_libs ${lib})
518     list(APPEND _objects ${_local_objects})
519     list(APPEND _deps ${_local_deps})
521     string(APPEND _debugmsg
522       ": EMBED_LIB ${lib}:\n"
523       "    OBJECTS = ${_local_objects}\n"
524       "    DEPS = ${_local_deps}\n\n")
525   endforeach()
527   add_mlir_library(${name}
528     ${_libtype}
529     ${ARG_UNPARSED_ARGUMENTS}
530     PARTIAL_SOURCES_INTENDED
531     EXCLUDE_FROM_LIBMLIR
532     LINK_LIBS PRIVATE
533     ${_deps}
534     ${ARG_PUBLIC_LIBS}
535   )
536   target_sources(${name} PRIVATE ${_objects})
538   # Linux defaults to allowing undefined symbols in shared libraries whereas
539   # many other platforms are more strict. We want these libraries to be
540   # self contained, and we want any undefined symbols to be reported at
541   # library construction time, not at library use, so make Linux strict too.
542   # We make an exception for sanitizer builds, since the AddressSanitizer
543   # run-time doesn't get linked into shared libraries.
544   if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND (NOT LLVM_USE_SANITIZER))
545     target_link_options(${name} PRIVATE
546       "LINKER:-z,defs"
547     )
548   endif()
550   # TODO: Should be transitive.
551   set_target_properties(${name} PROPERTIES
552     MLIR_AGGREGATE_EXCLUDE_LIBS "${_embed_libs}")
553   if(MSVC)
554     set_property(TARGET ${name} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON)
555   endif()
557   # Debugging generator expressions can be hard. Uncomment the below to emit
558   # files next to the library with a lot of debug information:
559   # string(APPEND _debugmsg
560   #   ": MAIN LIBRARY:\n"
561   #   "    OBJECTS = ${_objects}\n"
562   #   "    SOURCES = $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${name},SOURCES>>\n"
563   #   "    DEPS = ${_deps}\n"
564   #   "    LINK_LIBRARIES = $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${name},LINK_LIBRARIES>>\n"
565   #   "    MLIR_AGGREGATE_EXCLUDE_LIBS = $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${name},MLIR_AGGREGATE_EXCLUDE_LIBS>>\n"
566   # )
567   # file(GENERATE OUTPUT
568   #   "${CMAKE_CURRENT_BINARY_DIR}/${name}.aggregate_debug.txt"
569   #   CONTENT "${_debugmsg}"
570   # )
571 endfunction(add_mlir_aggregate)
573 # Adds an MLIR library target for installation.
574 # This is usually done as part of add_mlir_library but is broken out for cases
575 # where non-standard library builds can be installed.
576 function(add_mlir_library_install name)
577   if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
578   get_target_export_arg(${name} MLIR export_to_mlirtargets UMBRELLA mlir-libraries)
579   install(TARGETS ${name}
580     COMPONENT ${name}
581     ${export_to_mlirtargets}
582     LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
583     ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
584     RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
585     # Note that CMake will create a directory like:
586     #   objects-${CMAKE_BUILD_TYPE}/obj.LibName
587     # and put object files there.
588     OBJECTS DESTINATION lib${LLVM_LIBDIR_SUFFIX}
589   )
591   if (NOT LLVM_ENABLE_IDE)
592     add_llvm_install_targets(install-${name}
593                             DEPENDS ${name}
594                             COMPONENT ${name})
595   endif()
596   set_property(GLOBAL APPEND PROPERTY MLIR_ALL_LIBS ${name})
597   endif()
598   set_property(GLOBAL APPEND PROPERTY MLIR_EXPORTS ${name})
599 endfunction()
601 # Declare an mlir library which is part of the public C-API.
602 function(add_mlir_public_c_api_library name)
603   add_mlir_library(${name}
604     ${ARGN}
605     EXCLUDE_FROM_LIBMLIR
606     ENABLE_AGGREGATION
607     ADDITIONAL_HEADER_DIRS
608     ${MLIR_MAIN_INCLUDE_DIR}/mlir-c
609   )
610   # API libraries compile with hidden visibility and macros that enable
611   # exporting from the DLL. Only apply to the obj lib, which only affects
612   # the exports via a shared library.
613   set_target_properties(obj.${name}
614     PROPERTIES
615     CXX_VISIBILITY_PRESET hidden
616   )
617   target_compile_definitions(obj.${name}
618     PRIVATE
619     -DMLIR_CAPI_BUILDING_LIBRARY=1
620   )
621 endfunction()
623 # Declare the library associated with a dialect.
624 function(add_mlir_dialect_library name)
625   set_property(GLOBAL APPEND PROPERTY MLIR_DIALECT_LIBS ${name})
626   add_mlir_library(${ARGV} DEPENDS mlir-headers)
627 endfunction(add_mlir_dialect_library)
629 # Declare the library associated with a conversion.
630 function(add_mlir_conversion_library name)
631   set_property(GLOBAL APPEND PROPERTY MLIR_CONVERSION_LIBS ${name})
632   add_mlir_library(${ARGV} DEPENDS mlir-headers)
633 endfunction(add_mlir_conversion_library)
635 # Declare the library associated with an extension.
636 function(add_mlir_extension_library name)
637   set_property(GLOBAL APPEND PROPERTY MLIR_EXTENSION_LIBS ${name})
638   add_mlir_library(${ARGV} DEPENDS mlir-headers)
639 endfunction(add_mlir_extension_library)
641 # Declare the library associated with a translation.
642 function(add_mlir_translation_library name)
643   set_property(GLOBAL APPEND PROPERTY MLIR_TRANSLATION_LIBS ${name})
644   add_mlir_library(${ARGV} DEPENDS mlir-headers)
645 endfunction(add_mlir_translation_library)
647 # Verification tools to aid debugging.
648 function(mlir_check_link_libraries name)
649   if(TARGET ${name})
650     get_target_property(type ${name} TYPE)
651     if (${type} STREQUAL "INTERFACE_LIBRARY")
652       get_target_property(libs ${name} INTERFACE_LINK_LIBRARIES)
653     else()
654       get_target_property(libs ${name} LINK_LIBRARIES)
655     endif()
656     # message("${name} libs are: ${libs}")
657     set(linking_llvm 0)
658     foreach(lib ${libs})
659       if(lib)
660         if(${lib} MATCHES "^LLVM$")
661           set(linking_llvm 1)
662         endif()
663         if((${lib} MATCHES "^LLVM.+") AND ${linking_llvm})
664           # This will almost always cause execution problems, since the
665           # same symbol might be loaded from 2 separate libraries.  This
666           # often comes from referring to an LLVM library target
667           # explicitly in target_link_libraries()
668           message("WARNING: ${name} links LLVM and ${lib}!")
669         endif()
670       endif()
671     endforeach()
672   endif()
673 endfunction(mlir_check_link_libraries)
675 function(mlir_check_all_link_libraries name)
676   mlir_check_link_libraries(${name})
677   if(TARGET ${name})
678     get_target_property(libs ${name} LINK_LIBRARIES)
679     # message("${name} libs are: ${libs}")
680     foreach(lib ${libs})
681       mlir_check_link_libraries(${lib})
682     endforeach()
683   endif()
684 endfunction(mlir_check_all_link_libraries)