1include(GNUInstallDirs) 2include(LLVMDistributionSupport) 3 4# Clear out any pre-existing compile_commands file before processing. This 5# allows for generating a clean compile_commands on each configure. 6file(REMOVE ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml) 7 8function(mlir_tablegen ofn) 9 tablegen(MLIR ${ARGV}) 10 set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} 11 PARENT_SCOPE) 12 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 "") 19 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() 26 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 ) 34endfunction() 35 36# Clear out any pre-existing compile_commands file before processing. This 37# allows for generating a clean compile_commands on each configure. 38file(REMOVE ${CMAKE_BINARY_DIR}/pdll_compile_commands.yml) 39 40# Declare a helper function/copy of tablegen rule for using tablegen without 41# additional tblgen specific flags when invoking PDLL generator. 42function(_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() 48 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() 73 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() 80 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() 89 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) 104 105 set(tablegen_exe ${${project}_TABLEGEN_EXE}) 106 set(tablegen_depends ${${project}_TABLEGEN_TARGET} ${tablegen_exe}) 107 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_TABLEGEN_FLAGS} 112 ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} 113 ${tblgen_change_flag} 114 ${additional_cmdline} 115 # The file in LLVM_TARGET_DEFINITIONS may be not in the current 116 # directory and local_tds may not contain it, so we must 117 # explicitly list it here: 118 DEPENDS ${ARG_DEPENDS} ${tablegen_depends} 119 ${local_tds} ${global_tds} 120 ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} 121 ${LLVM_TARGET_DEPENDS} 122 COMMENT "Building ${ofn}..." 123 ) 124 125 # `make clean' must remove all those generated files: 126 set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn}) 127 128 set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) 129 set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES 130 GENERATED 1) 131endfunction() 132 133# Declare a PDLL library in the current directory. 134function(add_mlir_pdll_library target inputFile ofn) 135 set(LLVM_TARGET_DEFINITIONS ${inputFile}) 136 137 _pdll_tablegen(MLIR_PDLL ${ofn} -x=cpp ${ARGN}) 138 set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} 139 PARENT_SCOPE) 140 141 # Get the current set of include paths for this pdll file. 142 cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN}) 143 get_directory_property(tblgen_includes INCLUDE_DIRECTORIES) 144 list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES}) 145 # Filter out any empty include items. 146 list(REMOVE_ITEM tblgen_includes "") 147 148 # Build the absolute path for the current input file. 149 if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) 150 set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${inputFile}) 151 else() 152 set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/${inputFile}) 153 endif() 154 155 # Append the includes used for this file to the pdll_compilation_commands 156 # file. 157 file(APPEND ${CMAKE_BINARY_DIR}/pdll_compile_commands.yml 158 "--- !FileInfo:\n" 159 " filepath: \"${LLVM_TARGET_DEFINITIONS_ABSOLUTE}\"\n" 160 " includes: \"${CMAKE_CURRENT_SOURCE_DIR};${tblgen_includes}\"\n" 161 ) 162 163 add_public_tablegen_target(${target}) 164endfunction() 165 166# Declare a dialect in the include directory 167function(add_mlir_dialect dialect dialect_namespace) 168 set(LLVM_TARGET_DEFINITIONS ${dialect}.td) 169 mlir_tablegen(${dialect}.h.inc -gen-op-decls) 170 mlir_tablegen(${dialect}.cpp.inc -gen-op-defs) 171 mlir_tablegen(${dialect}Types.h.inc -gen-typedef-decls -typedefs-dialect=${dialect_namespace}) 172 mlir_tablegen(${dialect}Types.cpp.inc -gen-typedef-defs -typedefs-dialect=${dialect_namespace}) 173 mlir_tablegen(${dialect}Dialect.h.inc -gen-dialect-decls -dialect=${dialect_namespace}) 174 mlir_tablegen(${dialect}Dialect.cpp.inc -gen-dialect-defs -dialect=${dialect_namespace}) 175 add_public_tablegen_target(MLIR${dialect}IncGen) 176 add_dependencies(mlir-headers MLIR${dialect}IncGen) 177endfunction() 178 179# Declare a dialect in the include directory 180function(add_mlir_interface interface) 181 set(LLVM_TARGET_DEFINITIONS ${interface}.td) 182 mlir_tablegen(${interface}.h.inc -gen-op-interface-decls) 183 mlir_tablegen(${interface}.cpp.inc -gen-op-interface-defs) 184 add_public_tablegen_target(MLIR${interface}IncGen) 185 add_dependencies(mlir-generic-headers MLIR${interface}IncGen) 186endfunction() 187 188 189# Generate Documentation 190function(add_mlir_doc doc_filename output_file output_directory command) 191 set(LLVM_TARGET_DEFINITIONS ${doc_filename}.td) 192 tablegen(MLIR ${output_file}.md ${command} ${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) 202endfunction() 203 204# Declare an mlir library which can be compiled in libMLIR.so 205# In addition to everything that llvm_add_librar accepts, this 206# also has the following option: 207# EXCLUDE_FROM_LIBMLIR 208# Don't include this library in libMLIR.so. This option should be used 209# for test libraries, executable-specific libraries, or rarely used libraries 210# with large dependencies. 211# ENABLE_AGGREGATION 212# Forces generation of an OBJECT library, exports additional metadata, 213# and installs additional object files needed to include this as part of an 214# aggregate shared library. 215# TODO: Make this the default for all MLIR libraries once all libraries 216# are compatible with building an object library. 217function(add_mlir_library name) 218 cmake_parse_arguments(ARG 219 "SHARED;INSTALL_WITH_TOOLCHAIN;EXCLUDE_FROM_LIBMLIR;DISABLE_INSTALL;ENABLE_AGGREGATION" 220 "" 221 "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS" 222 ${ARGN}) 223 set(srcs) 224 if(MSVC_IDE OR XCODE) 225 # Add public headers 226 file(RELATIVE_PATH lib_path 227 ${MLIR_SOURCE_DIR}/lib/ 228 ${CMAKE_CURRENT_SOURCE_DIR} 229 ) 230 if(NOT lib_path MATCHES "^[.][.]") 231 file( GLOB_RECURSE headers 232 ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.h 233 ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.def 234 ) 235 set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON) 236 237 file( GLOB_RECURSE tds 238 ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.td 239 ) 240 source_group("TableGen descriptions" FILES ${tds}) 241 set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON) 242 243 if(headers OR tds) 244 set(srcs ${headers} ${tds}) 245 endif() 246 endif() 247 endif(MSVC_IDE OR XCODE) 248 if(srcs OR ARG_ADDITIONAL_HEADERS) 249 set(srcs 250 ADDITIONAL_HEADERS 251 ${srcs} 252 ${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args. 253 ) 254 endif() 255 256 # Is an object library needed. 257 set(NEEDS_OBJECT_LIB OFF) 258 if(ARG_ENABLE_AGGREGATION) 259 set(NEEDS_OBJECT_LIB ON) 260 endif() 261 262 # Determine type of library. 263 if(ARG_SHARED) 264 set(LIBTYPE SHARED) 265 else() 266 # llvm_add_library ignores BUILD_SHARED_LIBS if STATIC is explicitly set, 267 # so we need to handle it here. 268 if(BUILD_SHARED_LIBS) 269 set(LIBTYPE SHARED) 270 else() 271 set(LIBTYPE STATIC) 272 endif() 273 # Test libraries and such shouldn't be include in libMLIR.so 274 if(NOT ARG_EXCLUDE_FROM_LIBMLIR) 275 set(NEEDS_OBJECT_LIB ON) 276 set_property(GLOBAL APPEND PROPERTY MLIR_STATIC_LIBS ${name}) 277 set_property(GLOBAL APPEND PROPERTY MLIR_LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS}) 278 set_property(GLOBAL APPEND PROPERTY MLIR_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS}) 279 endif() 280 endif() 281 282 if(NEEDS_OBJECT_LIB AND NOT XCODE) 283 # The Xcode generator doesn't handle object libraries correctly. 284 # We special case xcode when building aggregates. 285 list(APPEND LIBTYPE OBJECT) 286 endif() 287 288 # MLIR libraries uniformly depend on LLVMSupport. Just specify it once here. 289 list(APPEND ARG_LINK_COMPONENTS Support) 290 291 # LINK_COMPONENTS is necessary to allow libLLVM.so to be properly 292 # substituted for individual library dependencies if LLVM_LINK_LLVM_DYLIB 293 # Perhaps this should be in llvm_add_library instead? However, it fails 294 # on libclang-cpp.so 295 get_property(llvm_component_libs GLOBAL PROPERTY LLVM_COMPONENT_LIBS) 296 foreach(lib ${ARG_LINK_LIBS}) 297 if(${lib} IN_LIST llvm_component_libs) 298 message(SEND_ERROR "${name} specifies LINK_LIBS ${lib}, but LINK_LIBS cannot be used for LLVM libraries. Please use LINK_COMPONENTS instead.") 299 endif() 300 endforeach() 301 302 list(APPEND ARG_DEPENDS mlir-generic-headers) 303 llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs} DEPENDS ${ARG_DEPENDS} LINK_COMPONENTS ${ARG_LINK_COMPONENTS} LINK_LIBS ${ARG_LINK_LIBS}) 304 305 if(TARGET ${name}) 306 target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS}) 307 if(NOT ARG_DISABLE_INSTALL) 308 add_mlir_library_install(${name}) 309 endif() 310 else() 311 # Add empty "phony" target 312 add_custom_target(${name}) 313 endif() 314 set_target_properties(${name} PROPERTIES FOLDER "MLIR libraries") 315 316 # Setup aggregate. 317 if(ARG_ENABLE_AGGREGATION) 318 # Compute and store the properties needed to build aggregates. 319 set(AGGREGATE_OBJECTS) 320 set(AGGREGATE_OBJECT_LIB) 321 set(AGGREGATE_DEPS) 322 if(XCODE) 323 # XCode has limited support for object libraries. Instead, add dep flags 324 # that force the entire library to be embedded. 325 list(APPEND AGGREGATE_DEPS "-force_load" "${name}") 326 else() 327 list(APPEND AGGREGATE_OBJECTS "$<TARGET_OBJECTS:obj.${name}>") 328 list(APPEND AGGREGATE_OBJECT_LIB "obj.${name}") 329 endif() 330 331 # For each declared dependency, transform it into a generator expression 332 # which excludes it if the ultimate link target is excluding the library. 333 set(NEW_LINK_LIBRARIES) 334 get_target_property(CURRENT_LINK_LIBRARIES ${name} LINK_LIBRARIES) 335 get_mlir_filtered_link_libraries(NEW_LINK_LIBRARIES ${CURRENT_LINK_LIBRARIES}) 336 set_target_properties(${name} PROPERTIES LINK_LIBRARIES "${NEW_LINK_LIBRARIES}") 337 list(APPEND AGGREGATE_DEPS ${NEW_LINK_LIBRARIES}) 338 set_target_properties(${name} PROPERTIES 339 EXPORT_PROPERTIES "MLIR_AGGREGATE_OBJECT_LIB_IMPORTED;MLIR_AGGREGATE_DEP_LIBS_IMPORTED" 340 MLIR_AGGREGATE_OBJECTS "${AGGREGATE_OBJECTS}" 341 MLIR_AGGREGATE_DEPS "${AGGREGATE_DEPS}" 342 MLIR_AGGREGATE_OBJECT_LIB_IMPORTED "${AGGREGATE_OBJECT_LIB}" 343 MLIR_AGGREGATE_DEP_LIBS_IMPORTED "${CURRENT_LINK_LIBRARIES}" 344 ) 345 346 # In order for out-of-tree projects to build aggregates of this library, 347 # we need to install the OBJECT library. 348 if(MLIR_INSTALL_AGGREGATE_OBJECTS AND NOT ARG_DISABLE_INSTALL) 349 add_mlir_library_install(obj.${name}) 350 endif() 351 endif() 352endfunction(add_mlir_library) 353 354macro(add_mlir_tool name) 355 llvm_add_tool(MLIR ${ARGV}) 356endmacro() 357 358# Sets a variable with a transformed list of link libraries such individual 359# libraries will be dynamically excluded when evaluated on a final library 360# which defines an MLIR_AGGREGATE_EXCLUDE_LIBS which contains any of the 361# libraries. Each link library can be a generator expression but must not 362# resolve to an arity > 1 (i.e. it can be optional). 363function(get_mlir_filtered_link_libraries output) 364 set(_results) 365 foreach(linklib ${ARGN}) 366 # In English, what this expression does: 367 # For each link library, resolve the property MLIR_AGGREGATE_EXCLUDE_LIBS 368 # on the context target (i.e. the executable or shared library being linked) 369 # and, if it is not in that list, emit the library name. Otherwise, empty. 370 list(APPEND _results 371 "$<$<NOT:$<IN_LIST:${linklib},$<GENEX_EVAL:$<TARGET_PROPERTY:MLIR_AGGREGATE_EXCLUDE_LIBS>>>>:${linklib}>" 372 ) 373 endforeach() 374 set(${output} "${_results}" PARENT_SCOPE) 375endfunction(get_mlir_filtered_link_libraries) 376 377# Declares an aggregate library. Such a library is a combination of arbitrary 378# regular add_mlir_library() libraries with the special feature that they can 379# be configured to statically embed some subset of their dependencies, as is 380# typical when creating a .so/.dylib/.dll or a mondo static library. 381# 382# It is always safe to depend on the aggregate directly in order to compile/link 383# against the superset of embedded entities and transitive deps. 384# 385# Arguments: 386# PUBLIC_LIBS: list of dependent libraries to add to the 387# INTERFACE_LINK_LIBRARIES property, exporting them to users. This list 388# will be transitively filtered to exclude any EMBED_LIBS. 389# EMBED_LIBS: list of dependent libraries that should be embedded directly 390# into this library. Each of these must be an add_mlir_library() library 391# without DISABLE_AGGREGATE. 392# 393# Note: This is a work in progress and is presently only sufficient for certain 394# non nested cases involving the C-API. 395function(add_mlir_aggregate name) 396 cmake_parse_arguments(ARG 397 "SHARED;STATIC" 398 "" 399 "PUBLIC_LIBS;EMBED_LIBS" 400 ${ARGN}) 401 set(_libtype) 402 if(ARG_STATIC) 403 list(APPEND _libtype STATIC) 404 endif() 405 if(ARG_SHARED) 406 list(APPEND _libtype SHARED) 407 endif() 408 set(_debugmsg) 409 410 set(_embed_libs) 411 set(_objects) 412 set(_deps) 413 foreach(lib ${ARG_EMBED_LIBS}) 414 # We have to handle imported vs in-tree differently: 415 # in-tree: To support arbitrary ordering, the generator expressions get 416 # set on the dependent target when it is constructed and then just 417 # eval'd here. This means we can build an aggregate from targets that 418 # may not yet be defined, which is typical for in-tree. 419 # imported: Exported properties do not support generator expressions, so 420 # we imperatively query and manage the expansion here. This is fine 421 # because imported targets will always be found/configured first and 422 # do not need to support arbitrary ordering. If CMake every supports 423 # exporting generator expressions, then this can be simplified. 424 set(_is_imported OFF) 425 if(TARGET ${lib}) 426 get_target_property(_is_imported ${lib} IMPORTED) 427 endif() 428 429 if(NOT _is_imported) 430 # Evaluate the in-tree generator expressions directly (this allows target 431 # order independence, since these aren't evaluated until the generate 432 # phase). 433 # What these expressions do: 434 # In the context of this aggregate, resolve the list of OBJECTS and DEPS 435 # that each library advertises and patch it into the whole. 436 set(_local_objects $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${lib},MLIR_AGGREGATE_OBJECTS>>) 437 set(_local_deps $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${lib},MLIR_AGGREGATE_DEPS>>) 438 else() 439 # It is an imported target, which can only have flat strings populated 440 # (no generator expressions). 441 # Rebuild the generator expressions from the imported flat string lists. 442 if(NOT MLIR_INSTALL_AGGREGATE_OBJECTS) 443 message(SEND_ERROR "Cannot build aggregate from imported targets which were not installed via MLIR_INSTALL_AGGREGATE_OBJECTS (for ${lib}).") 444 endif() 445 446 get_property(_has_object_lib_prop TARGET ${lib} PROPERTY MLIR_AGGREGATE_OBJECT_LIB_IMPORTED SET) 447 get_property(_has_dep_libs_prop TARGET ${lib} PROPERTY MLIR_AGGREGATE_DEP_LIBS_IMPORTED SET) 448 if(NOT _has_object_lib_prop OR NOT _has_dep_libs_prop) 449 message(SEND_ERROR "Cannot create an aggregate out of imported ${lib}: It is missing properties indicating that it was built for aggregation") 450 endif() 451 get_target_property(_imp_local_object_lib ${lib} MLIR_AGGREGATE_OBJECT_LIB_IMPORTED) 452 get_target_property(_imp_dep_libs ${lib} MLIR_AGGREGATE_DEP_LIBS_IMPORTED) 453 set(_local_objects) 454 if(_imp_local_object_lib) 455 set(_local_objects "$<TARGET_OBJECTS:${_imp_local_object_lib}>") 456 endif() 457 # We should just be able to do this: 458 # get_mlir_filtered_link_libraries(_local_deps ${_imp_dep_libs}) 459 # However, CMake complains about the unqualified use of the one-arg 460 # $<TARGET_PROPERTY> expression. So we do the same thing but use the 461 # two-arg form which takes an explicit target. 462 foreach(_imp_dep_lib ${_imp_dep_libs}) 463 # In English, what this expression does: 464 # For each link library, resolve the property MLIR_AGGREGATE_EXCLUDE_LIBS 465 # on the context target (i.e. the executable or shared library being linked) 466 # and, if it is not in that list, emit the library name. Otherwise, empty. 467 list(APPEND _local_deps 468 "$<$<NOT:$<IN_LIST:${_imp_dep_lib},$<GENEX_EVAL:$<TARGET_PROPERTY:${name},MLIR_AGGREGATE_EXCLUDE_LIBS>>>>:${_imp_dep_lib}>" 469 ) 470 endforeach() 471 endif() 472 473 list(APPEND _embed_libs ${lib}) 474 list(APPEND _objects ${_local_objects}) 475 list(APPEND _deps ${_local_deps}) 476 477 string(APPEND _debugmsg 478 ": EMBED_LIB ${lib}:\n" 479 " OBJECTS = ${_local_objects}\n" 480 " DEPS = ${_local_deps}\n\n") 481 endforeach() 482 483 add_mlir_library(${name} 484 ${_libtype} 485 ${ARG_UNPARSED_ARGUMENTS} 486 PARTIAL_SOURCES_INTENDED 487 EXCLUDE_FROM_LIBMLIR 488 LINK_LIBS PRIVATE 489 ${_deps} 490 ${ARG_PUBLIC_LIBS} 491 ) 492 target_sources(${name} PRIVATE ${_objects}) 493 # TODO: Should be transitive. 494 set_target_properties(${name} PROPERTIES 495 MLIR_AGGREGATE_EXCLUDE_LIBS "${_embed_libs}") 496 if(MSVC) 497 set_property(TARGET ${name} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON) 498 endif() 499 500 # Debugging generator expressions can be hard. Uncomment the below to emit 501 # files next to the library with a lot of debug information: 502 # string(APPEND _debugmsg 503 # ": MAIN LIBRARY:\n" 504 # " OBJECTS = ${_objects}\n" 505 # " SOURCES = $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${name},SOURCES>>\n" 506 # " DEPS = ${_deps}\n" 507 # " LINK_LIBRARIES = $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${name},LINK_LIBRARIES>>\n" 508 # " MLIR_AGGREGATE_EXCLUDE_LIBS = $<TARGET_GENEX_EVAL:${name},$<TARGET_PROPERTY:${name},MLIR_AGGREGATE_EXCLUDE_LIBS>>\n" 509 # ) 510 # file(GENERATE OUTPUT 511 # "${CMAKE_CURRENT_BINARY_DIR}/${name}.aggregate_debug.txt" 512 # CONTENT "${_debugmsg}" 513 # ) 514endfunction(add_mlir_aggregate) 515 516# Adds an MLIR library target for installation. 517# This is usually done as part of add_mlir_library but is broken out for cases 518# where non-standard library builds can be installed. 519function(add_mlir_library_install name) 520 if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) 521 get_target_export_arg(${name} MLIR export_to_mlirtargets UMBRELLA mlir-libraries) 522 install(TARGETS ${name} 523 COMPONENT ${name} 524 ${export_to_mlirtargets} 525 LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} 526 ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} 527 RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" 528 # Note that CMake will create a directory like: 529 # objects-${CMAKE_BUILD_TYPE}/obj.LibName 530 # and put object files there. 531 OBJECTS DESTINATION lib${LLVM_LIBDIR_SUFFIX} 532 ) 533 534 if (NOT LLVM_ENABLE_IDE) 535 add_llvm_install_targets(install-${name} 536 DEPENDS ${name} 537 COMPONENT ${name}) 538 endif() 539 set_property(GLOBAL APPEND PROPERTY MLIR_ALL_LIBS ${name}) 540 endif() 541 set_property(GLOBAL APPEND PROPERTY MLIR_EXPORTS ${name}) 542endfunction() 543 544# Declare an mlir library which is part of the public C-API. 545function(add_mlir_public_c_api_library name) 546 add_mlir_library(${name} 547 ${ARGN} 548 EXCLUDE_FROM_LIBMLIR 549 ENABLE_AGGREGATION 550 ADDITIONAL_HEADER_DIRS 551 ${MLIR_MAIN_INCLUDE_DIR}/mlir-c 552 ) 553 # API libraries compile with hidden visibility and macros that enable 554 # exporting from the DLL. Only apply to the obj lib, which only affects 555 # the exports via a shared library. 556 set_target_properties(obj.${name} 557 PROPERTIES 558 CXX_VISIBILITY_PRESET hidden 559 ) 560 target_compile_definitions(obj.${name} 561 PRIVATE 562 -DMLIR_CAPI_BUILDING_LIBRARY=1 563 ) 564endfunction() 565 566# Declare the library associated with a dialect. 567function(add_mlir_dialect_library name) 568 set_property(GLOBAL APPEND PROPERTY MLIR_DIALECT_LIBS ${name}) 569 add_mlir_library(${ARGV} DEPENDS mlir-headers) 570endfunction(add_mlir_dialect_library) 571 572# Declare the library associated with a conversion. 573function(add_mlir_conversion_library name) 574 set_property(GLOBAL APPEND PROPERTY MLIR_CONVERSION_LIBS ${name}) 575 add_mlir_library(${ARGV} DEPENDS mlir-headers) 576endfunction(add_mlir_conversion_library) 577 578# Declare the library associated with a translation. 579function(add_mlir_translation_library name) 580 set_property(GLOBAL APPEND PROPERTY MLIR_TRANSLATION_LIBS ${name}) 581 add_mlir_library(${ARGV} DEPENDS mlir-headers) 582endfunction(add_mlir_translation_library) 583 584# Verification tools to aid debugging. 585function(mlir_check_link_libraries name) 586 if(TARGET ${name}) 587 get_target_property(type ${name} TYPE) 588 if (${type} STREQUAL "INTERFACE_LIBRARY") 589 get_target_property(libs ${name} INTERFACE_LINK_LIBRARIES) 590 else() 591 get_target_property(libs ${name} LINK_LIBRARIES) 592 endif() 593 # message("${name} libs are: ${libs}") 594 set(linking_llvm 0) 595 foreach(lib ${libs}) 596 if(lib) 597 if(${lib} MATCHES "^LLVM$") 598 set(linking_llvm 1) 599 endif() 600 if((${lib} MATCHES "^LLVM.+") AND ${linking_llvm}) 601 # This will almost always cause execution problems, since the 602 # same symbol might be loaded from 2 separate libraries. This 603 # often comes from referring to an LLVM library target 604 # explicitly in target_link_libraries() 605 message("WARNING: ${name} links LLVM and ${lib}!") 606 endif() 607 endif() 608 endforeach() 609 endif() 610endfunction(mlir_check_link_libraries) 611 612function(mlir_check_all_link_libraries name) 613 mlir_check_link_libraries(${name}) 614 if(TARGET ${name}) 615 get_target_property(libs ${name} LINK_LIBRARIES) 616 # message("${name} libs are: ${libs}") 617 foreach(lib ${libs}) 618 mlir_check_link_libraries(${lib}) 619 endforeach() 620 endif() 621endfunction(mlir_check_all_link_libraries) 622