1function(mlir_tablegen ofn)
2  tablegen(MLIR ${ARGV})
3  set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
4      PARENT_SCOPE)
5  include_directories(${CMAKE_CURRENT_BINARY_DIR})
6endfunction()
7
8# Declare a dialect in the include directory
9function(add_mlir_dialect dialect dialect_namespace)
10  set(LLVM_TARGET_DEFINITIONS ${dialect}.td)
11  mlir_tablegen(${dialect}.h.inc -gen-op-decls)
12  mlir_tablegen(${dialect}.cpp.inc -gen-op-defs)
13  mlir_tablegen(${dialect}Types.h.inc -gen-typedef-decls)
14  mlir_tablegen(${dialect}Types.cpp.inc -gen-typedef-defs)
15  mlir_tablegen(${dialect}Dialect.h.inc -gen-dialect-decls -dialect=${dialect_namespace})
16  add_public_tablegen_target(MLIR${dialect}IncGen)
17  add_dependencies(mlir-headers MLIR${dialect}IncGen)
18endfunction()
19
20# Declare a dialect in the include directory
21function(add_mlir_interface interface)
22  set(LLVM_TARGET_DEFINITIONS ${interface}.td)
23  mlir_tablegen(${interface}.h.inc -gen-op-interface-decls)
24  mlir_tablegen(${interface}.cpp.inc -gen-op-interface-defs)
25  add_public_tablegen_target(MLIR${interface}IncGen)
26  add_dependencies(mlir-generic-headers MLIR${interface}IncGen)
27endfunction()
28
29
30# Generate Documentation
31function(add_mlir_doc doc_filename output_file output_directory command)
32  set(LLVM_TARGET_DEFINITIONS ${doc_filename}.td)
33  tablegen(MLIR ${output_file}.md ${command} ${ARGN})
34  set(GEN_DOC_FILE ${MLIR_BINARY_DIR}/docs/${output_directory}${output_file}.md)
35  add_custom_command(
36          OUTPUT ${GEN_DOC_FILE}
37          COMMAND ${CMAKE_COMMAND} -E copy
38                  ${CMAKE_CURRENT_BINARY_DIR}/${output_file}.md
39                  ${GEN_DOC_FILE}
40          DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${output_file}.md)
41  add_custom_target(${output_file}DocGen DEPENDS ${GEN_DOC_FILE})
42  add_dependencies(mlir-doc ${output_file}DocGen)
43endfunction()
44
45# Declare an mlir library which can be compiled in libMLIR.so
46# In addition to everything that llvm_add_librar accepts, this
47# also has the following option:
48# EXCLUDE_FROM_LIBMLIR
49#   Don't include this library in libMLIR.so.  This option should be used
50#   for test libraries, executable-specific libraries, or rarely used libraries
51#   with large dependencies.
52function(add_mlir_library name)
53  cmake_parse_arguments(ARG
54    "SHARED;INSTALL_WITH_TOOLCHAIN;EXCLUDE_FROM_LIBMLIR"
55    ""
56    "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS"
57    ${ARGN})
58  set(srcs)
59  if(MSVC_IDE OR XCODE)
60    # Add public headers
61    file(RELATIVE_PATH lib_path
62      ${MLIR_SOURCE_DIR}/lib/
63      ${CMAKE_CURRENT_SOURCE_DIR}
64    )
65    if(NOT lib_path MATCHES "^[.][.]")
66      file( GLOB_RECURSE headers
67        ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.h
68        ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.def
69      )
70      set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON)
71
72      file( GLOB_RECURSE tds
73        ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.td
74      )
75      source_group("TableGen descriptions" FILES ${tds})
76      set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON)
77
78      if(headers OR tds)
79        set(srcs ${headers} ${tds})
80      endif()
81    endif()
82  endif(MSVC_IDE OR XCODE)
83  if(srcs OR ARG_ADDITIONAL_HEADERS)
84    set(srcs
85      ADDITIONAL_HEADERS
86      ${srcs}
87      ${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args.
88      )
89  endif()
90  if(ARG_SHARED)
91    set(LIBTYPE SHARED)
92  else()
93    # llvm_add_library ignores BUILD_SHARED_LIBS if STATIC is explicitly set,
94    # so we need to handle it here.
95    if(BUILD_SHARED_LIBS)
96      set(LIBTYPE SHARED)
97    else()
98      set(LIBTYPE STATIC)
99    endif()
100    if(NOT XCODE)
101      # The Xcode generator doesn't handle object libraries correctly.
102      list(APPEND LIBTYPE OBJECT)
103    endif()
104    # Test libraries and such shouldn't be include in libMLIR.so
105    if(NOT ARG_EXCLUDE_FROM_LIBMLIR)
106      set_property(GLOBAL APPEND PROPERTY MLIR_STATIC_LIBS ${name})
107      set_property(GLOBAL APPEND PROPERTY MLIR_LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
108      set_property(GLOBAL APPEND PROPERTY MLIR_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS})
109    endif()
110  endif()
111
112  # MLIR libraries uniformly depend on LLVMSupport.  Just specify it once here.
113  list(APPEND ARG_LINK_COMPONENTS Support)
114
115  # LINK_COMPONENTS is necessary to allow libLLVM.so to be properly
116  # substituted for individual library dependencies if LLVM_LINK_LLVM_DYLIB
117  # Perhaps this should be in llvm_add_library instead?  However, it fails
118  # on libclang-cpp.so
119  get_property(llvm_component_libs GLOBAL PROPERTY LLVM_COMPONENT_LIBS)
120  foreach(lib ${ARG_LINK_LIBS})
121    if(${lib} IN_LIST llvm_component_libs)
122      message(SEND_ERROR "${name} specifies LINK_LIBS ${lib}, but LINK_LIBS cannot be used for LLVM libraries.  Please use LINK_COMPONENTS instead.")
123    endif()
124  endforeach()
125
126  list(APPEND ARG_DEPENDS mlir-generic-headers)
127  llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs} DEPENDS ${ARG_DEPENDS} LINK_COMPONENTS ${ARG_LINK_COMPONENTS} LINK_LIBS ${ARG_LINK_LIBS})
128
129  if(TARGET ${name})
130    target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS})
131    add_mlir_library_install(${name})
132  else()
133    # Add empty "phony" target
134    add_custom_target(${name})
135  endif()
136  set_target_properties(${name} PROPERTIES FOLDER "MLIR libraries")
137endfunction(add_mlir_library)
138
139# Adds an MLIR library target for installation.
140# This is usually done as part of add_mlir_library but is broken out for cases
141# where non-standard library builds can be installed.
142function(add_mlir_library_install name)
143  if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
144  set(export_to_mlirtargets)
145  if (${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
146      "mlir-libraries" IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
147      NOT LLVM_DISTRIBUTION_COMPONENTS)
148      set(export_to_mlirtargets EXPORT MLIRTargets)
149    set_property(GLOBAL PROPERTY MLIR_HAS_EXPORTS True)
150  endif()
151
152  install(TARGETS ${name}
153    COMPONENT ${name}
154    ${export_to_mlirtargets}
155    LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
156    ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
157    RUNTIME DESTINATION bin)
158
159  if (NOT LLVM_ENABLE_IDE)
160    add_llvm_install_targets(install-${name}
161                            DEPENDS ${name}
162                            COMPONENT ${name})
163  endif()
164  set_property(GLOBAL APPEND PROPERTY MLIR_ALL_LIBS ${name})
165  endif()
166  set_property(GLOBAL APPEND PROPERTY MLIR_EXPORTS ${name})
167endfunction()
168
169# Declare an mlir library which is part of the public C-API and will be
170# compiled and exported into libMLIRPublicAPI.so/MLIRPublicAPI.dll.
171# This shared library is built regardless of the overall setting of building
172# libMLIR.so (which exports the C++ implementation).
173function(add_mlir_public_c_api_library name)
174  add_mlir_library(${name}
175    ${ARGN}
176    # NOTE: Generates obj.${name} which is used for shared library building.
177    OBJECT
178    EXCLUDE_FROM_LIBMLIR
179    ADDITIONAL_HEADER_DIRS
180    ${MLIR_MAIN_INCLUDE_DIR}/mlir-c
181  )
182  # API libraries compile with hidden visibility and macros that enable
183  # exporting from the DLL. Only apply to the obj lib, which only affects
184  # the exports via a shared library.
185  set_target_properties(obj.${name}
186    PROPERTIES
187    CXX_VISIBILITY_PRESET hidden
188  )
189  target_compile_definitions(obj.${name}
190    PRIVATE
191    -DMLIR_CAPI_BUILDING_LIBRARY=1
192  )
193  set_property(GLOBAL APPEND PROPERTY MLIR_PUBLIC_C_API_LIBS ${name})
194endfunction()
195
196# Declare the library associated with a dialect.
197function(add_mlir_dialect_library name)
198  set_property(GLOBAL APPEND PROPERTY MLIR_DIALECT_LIBS ${name})
199  add_mlir_library(${ARGV} DEPENDS mlir-headers)
200endfunction(add_mlir_dialect_library)
201
202# Declare the library associated with a conversion.
203function(add_mlir_conversion_library name)
204  set_property(GLOBAL APPEND PROPERTY MLIR_CONVERSION_LIBS ${name})
205  add_mlir_library(${ARGV} DEPENDS mlir-headers)
206endfunction(add_mlir_conversion_library)
207
208# Declare the library associated with a translation.
209function(add_mlir_translation_library name)
210  set_property(GLOBAL APPEND PROPERTY MLIR_TRANSLATION_LIBS ${name})
211  add_mlir_library(${ARGV} DEPENDS mlir-headers)
212endfunction(add_mlir_translation_library)
213
214# Verification tools to aid debugging.
215function(mlir_check_link_libraries name)
216  if(TARGET ${name})
217    get_target_property(type ${name} TYPE)
218    if (${type} STREQUAL "INTERFACE_LIBRARY")
219      get_target_property(libs ${name} INTERFACE_LINK_LIBRARIES)
220    else()
221      get_target_property(libs ${name} LINK_LIBRARIES)
222    endif()
223    # message("${name} libs are: ${libs}")
224    set(linking_llvm 0)
225    foreach(lib ${libs})
226      if(lib)
227        if(${lib} MATCHES "^LLVM$")
228          set(linking_llvm 1)
229        endif()
230        if((${lib} MATCHES "^LLVM.+") AND ${linking_llvm})
231          # This will almost always cause execution problems, since the
232          # same symbol might be loaded from 2 separate libraries.  This
233          # often comes from referring to an LLVM library target
234          # explicitly in target_link_libraries()
235          message("WARNING: ${name} links LLVM and ${lib}!")
236        endif()
237      endif()
238    endforeach()
239  endif()
240endfunction(mlir_check_link_libraries)
241
242function(mlir_check_all_link_libraries name)
243  mlir_check_link_libraries(${name})
244  if(TARGET ${name})
245    get_target_property(libs ${name} LINK_LIBRARIES)
246    # message("${name} libs are: ${libs}")
247    foreach(lib ${libs})
248      mlir_check_link_libraries(${lib})
249    endforeach()
250  endif()
251endfunction(mlir_check_all_link_libraries)
252