include(GNUInstallDirs) include(LLVMDistributionSupport) # Clear out any pre-existing compile_commands file before processing. This # allows for generating a clean compile_commands on each configure. file(REMOVE ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml) function(mlir_tablegen ofn) tablegen(MLIR ${ARGV}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) # Get the current set of include paths for this td file. cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN}) get_directory_property(tblgen_includes INCLUDE_DIRECTORIES) list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES}) # Filter out any empty include items. list(REMOVE_ITEM tblgen_includes "") # Build the absolute path for the current input file. if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) else() set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS}) endif() # Append the includes used for this file to the tablegen_compile_commands # file. file(APPEND ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml "--- !FileInfo:\n" " filepath: \"${LLVM_TARGET_DEFINITIONS_ABSOLUTE}\"\n" " includes: \"${CMAKE_CURRENT_SOURCE_DIR};${tblgen_includes}\"\n" ) endfunction() # Clear out any pre-existing compile_commands file before processing. This # allows for generating a clean compile_commands on each configure. file(REMOVE ${CMAKE_BINARY_DIR}/pdll_compile_commands.yml) # Declare a helper function/copy of tablegen rule for using tablegen without # additional tblgen specific flags when invoking PDLL generator. function(_pdll_tablegen project ofn) cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN}) # Validate calling context. if(NOT ${project}_TABLEGEN_EXE) message(FATAL_ERROR "${project}_TABLEGEN_EXE not set") endif() # Use depfile instead of globbing arbitrary *.td(s) for Ninja. if(CMAKE_GENERATOR MATCHES "Ninja") # Make output path relative to build.ninja, assuming located on # ${CMAKE_BINARY_DIR}. # CMake emits build targets as relative paths but Ninja doesn't identify # absolute path (in *.d) as relative path (in build.ninja) # Note that tblgen is executed on ${CMAKE_BINARY_DIR} as working directory. file(RELATIVE_PATH ofn_rel ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}) set(additional_cmdline -o ${ofn_rel} -d ${ofn_rel}.d WORKING_DIRECTORY ${CMAKE_BINARY_DIR} DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.d ) set(local_tds) set(global_tds) else() file(GLOB local_tds "*.td") file(GLOB_RECURSE global_tds "${LLVM_MAIN_INCLUDE_DIR}/llvm/*.td") set(additional_cmdline -o ${CMAKE_CURRENT_BINARY_DIR}/${ofn} ) endif() if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) else() set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS}) endif() if (CMAKE_GENERATOR MATCHES "Visual Studio") # Visual Studio has problems with llvm-tblgen's native --write-if-changed # behavior. Since it doesn't do restat optimizations anyway, just don't # pass --write-if-changed there. set(tblgen_change_flag) else() set(tblgen_change_flag "--write-if-changed") endif() # We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the DEPENDS list # (both the target and the file) to have .inc files rebuilt on # a tablegen change, as cmake does not propagate file-level dependencies # of custom targets. See the following ticket for more information: # https://cmake.org/Bug/view.php?id=15858 # The dependency on both, the target and the file, produces the same # dependency twice in the result file when # ("${${project}_TABLEGEN_TARGET}" STREQUAL "${${project}_TABLEGEN_EXE}") # but lets us having smaller and cleaner code here. get_directory_property(tblgen_includes INCLUDE_DIRECTORIES) list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES}) # Filter out empty items before prepending each entry with -I list(REMOVE_ITEM tblgen_includes "") list(TRANSFORM tblgen_includes PREPEND -I) set(tablegen_exe ${${project}_TABLEGEN_EXE}) set(tablegen_depends ${${project}_TABLEGEN_TARGET} ${tablegen_exe}) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} COMMAND ${tablegen_exe} ${ARG_UNPARSED_ARGUMENTS} -I ${CMAKE_CURRENT_SOURCE_DIR} ${tblgen_includes} ${LLVM_TABLEGEN_FLAGS} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} ${tblgen_change_flag} ${additional_cmdline} # The file in LLVM_TARGET_DEFINITIONS may be not in the current # directory and local_tds may not contain it, so we must # explicitly list it here: DEPENDS ${ARG_DEPENDS} ${tablegen_depends} ${local_tds} ${global_tds} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} ${LLVM_TARGET_DEPENDS} COMMENT "Building ${ofn}..." ) # `make clean' must remove all those generated files: set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES GENERATED 1) endfunction() # Declare a PDLL library in the current directory. function(add_mlir_pdll_library target inputFile ofn) set(LLVM_TARGET_DEFINITIONS ${inputFile}) _pdll_tablegen(MLIR_PDLL ${ofn} -x=cpp ${ARGN}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) # Get the current set of include paths for this pdll file. cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN}) get_directory_property(tblgen_includes INCLUDE_DIRECTORIES) list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES}) # Filter out any empty include items. list(REMOVE_ITEM tblgen_includes "") # Build the absolute path for the current input file. if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${inputFile}) else() set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/${inputFile}) endif() # Append the includes used for this file to the pdll_compilation_commands # file. file(APPEND ${CMAKE_BINARY_DIR}/pdll_compile_commands.yml "--- !FileInfo:\n" " filepath: \"${LLVM_TARGET_DEFINITIONS_ABSOLUTE}\"\n" " includes: \"${CMAKE_CURRENT_SOURCE_DIR};${tblgen_includes}\"\n" ) add_public_tablegen_target(${target}) endfunction() # Declare a dialect in the include directory function(add_mlir_dialect dialect dialect_namespace) set(LLVM_TARGET_DEFINITIONS ${dialect}.td) mlir_tablegen(${dialect}.h.inc -gen-op-decls) mlir_tablegen(${dialect}.cpp.inc -gen-op-defs) mlir_tablegen(${dialect}Types.h.inc -gen-typedef-decls -typedefs-dialect=${dialect_namespace}) mlir_tablegen(${dialect}Types.cpp.inc -gen-typedef-defs -typedefs-dialect=${dialect_namespace}) mlir_tablegen(${dialect}Dialect.h.inc -gen-dialect-decls -dialect=${dialect_namespace}) mlir_tablegen(${dialect}Dialect.cpp.inc -gen-dialect-defs -dialect=${dialect_namespace}) add_public_tablegen_target(MLIR${dialect}IncGen) add_dependencies(mlir-headers MLIR${dialect}IncGen) endfunction() # Declare a dialect in the include directory function(add_mlir_interface interface) set(LLVM_TARGET_DEFINITIONS ${interface}.td) mlir_tablegen(${interface}.h.inc -gen-op-interface-decls) mlir_tablegen(${interface}.cpp.inc -gen-op-interface-defs) add_public_tablegen_target(MLIR${interface}IncGen) add_dependencies(mlir-generic-headers MLIR${interface}IncGen) endfunction() # Generate Documentation function(add_mlir_doc doc_filename output_file output_directory command) set(LLVM_TARGET_DEFINITIONS ${doc_filename}.td) tablegen(MLIR ${output_file}.md ${command} ${ARGN}) set(GEN_DOC_FILE ${MLIR_BINARY_DIR}/docs/${output_directory}${output_file}.md) add_custom_command( OUTPUT ${GEN_DOC_FILE} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${output_file}.md ${GEN_DOC_FILE} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${output_file}.md) add_custom_target(${output_file}DocGen DEPENDS ${GEN_DOC_FILE}) add_dependencies(mlir-doc ${output_file}DocGen) endfunction() # Sets ${srcs} to contain the list of additional headers for the target. Extra # arguments are included into the list of additional headers. function(_set_mlir_additional_headers_as_srcs) set(srcs) if(MSVC_IDE OR XCODE) # Add public headers file(RELATIVE_PATH lib_path ${MLIR_SOURCE_DIR}/lib/ ${CMAKE_CURRENT_SOURCE_DIR} ) if(NOT lib_path MATCHES "^[.][.]") file( GLOB_RECURSE headers ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.h ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.def ) set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON) file( GLOB_RECURSE tds ${MLIR_SOURCE_DIR}/include/mlir/${lib_path}/*.td ) source_group("TableGen descriptions" FILES ${tds}) set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON) if(headers OR tds) set(srcs ${headers} ${tds}) endif() endif() endif(MSVC_IDE OR XCODE) if(srcs OR ARGN) set(srcs ADDITIONAL_HEADERS ${srcs} ${ARGN} # It may contain unparsed unknown args. PARENT_SCOPE ) endif() endfunction() # Checks that the LLVM components are not listed in the extra arguments, # assumed to be coming from the LINK_LIBS variable. function(_check_llvm_components_usage name) # LINK_COMPONENTS is necessary to allow libLLVM.so to be properly # substituted for individual library dependencies if LLVM_LINK_LLVM_DYLIB # Perhaps this should be in llvm_add_library instead? However, it fails # on libclang-cpp.so get_property(llvm_component_libs GLOBAL PROPERTY LLVM_COMPONENT_LIBS) foreach(lib ${ARGN}) if(${lib} IN_LIST llvm_component_libs) message(SEND_ERROR "${name} specifies LINK_LIBS ${lib}, but LINK_LIBS cannot be used for LLVM libraries. Please use LINK_COMPONENTS instead.") endif() endforeach() endfunction() function(add_mlir_example_library name) cmake_parse_arguments(ARG "SHARED;DISABLE_INSTALL" "" "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS" ${ARGN}) _set_mlir_additional_headers_as_srcs(${ARG_ADDITIONAL_HEADERS}) if (ARG_SHARED) set(LIBTYPE SHARED) else() if(BUILD_SHARED_LIBS) set(LIBTYPE SHARED) else() set(LIBTYPE STATIC) endif() endif() # MLIR libraries uniformly depend on LLVMSupport. Just specify it once here. list(APPEND ARG_LINK_COMPONENTS Support) _check_llvm_components_usage(${name} ${ARG_LINK_LIBS}) list(APPEND ARG_DEPENDS mlir-generic-headers) llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs} DEPENDS ${ARG_DEPENDS} LINK_COMPONENTS ${ARG_LINK_COMPONENTS} LINK_LIBS ${ARG_LINK_LIBS}) set_target_properties(${name} PROPERTIES FOLDER "Examples") if (LLVM_BUILD_EXAMPLES AND NOT ${ARG_DISABLE_INSTALL}) add_mlir_library_install(${name}) else() set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL ON) endif() endfunction() # Declare an mlir library which can be compiled in libMLIR.so # In addition to everything that llvm_add_library accepts, this # also has the following option: # EXCLUDE_FROM_LIBMLIR # Don't include this library in libMLIR.so. This option should be used # for test libraries, executable-specific libraries, or rarely used libraries # with large dependencies. # ENABLE_AGGREGATION # Forces generation of an OBJECT library, exports additional metadata, # and installs additional object files needed to include this as part of an # aggregate shared library. # TODO: Make this the default for all MLIR libraries once all libraries # are compatible with building an object library. function(add_mlir_library name) cmake_parse_arguments(ARG "SHARED;INSTALL_WITH_TOOLCHAIN;EXCLUDE_FROM_LIBMLIR;DISABLE_INSTALL;ENABLE_AGGREGATION" "" "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS" ${ARGN}) _set_mlir_additional_headers_as_srcs(${ARG_ADDITIONAL_HEADERS}) # Is an object library needed. set(NEEDS_OBJECT_LIB OFF) if(ARG_ENABLE_AGGREGATION) set(NEEDS_OBJECT_LIB ON) endif() # Determine type of library. if(ARG_SHARED) set(LIBTYPE SHARED) else() # llvm_add_library ignores BUILD_SHARED_LIBS if STATIC is explicitly set, # so we need to handle it here. if(BUILD_SHARED_LIBS) set(LIBTYPE SHARED) else() set(LIBTYPE STATIC) endif() # Test libraries and such shouldn't be include in libMLIR.so if(NOT ARG_EXCLUDE_FROM_LIBMLIR) set(NEEDS_OBJECT_LIB ON) set_property(GLOBAL APPEND PROPERTY MLIR_STATIC_LIBS ${name}) set_property(GLOBAL APPEND PROPERTY MLIR_LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS}) set_property(GLOBAL APPEND PROPERTY MLIR_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS}) endif() endif() if(NEEDS_OBJECT_LIB AND NOT XCODE) # The Xcode generator doesn't handle object libraries correctly. # We special case xcode when building aggregates. list(APPEND LIBTYPE OBJECT) endif() # MLIR libraries uniformly depend on LLVMSupport. Just specify it once here. list(APPEND ARG_LINK_COMPONENTS Support) _check_llvm_components_usage(${name} ${ARG_LINK_LIBS}) list(APPEND ARG_DEPENDS mlir-generic-headers) llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs} DEPENDS ${ARG_DEPENDS} LINK_COMPONENTS ${ARG_LINK_COMPONENTS} LINK_LIBS ${ARG_LINK_LIBS}) if(TARGET ${name}) target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS}) if(NOT ARG_DISABLE_INSTALL) add_mlir_library_install(${name}) endif() else() # Add empty "phony" target add_custom_target(${name}) endif() set_target_properties(${name} PROPERTIES FOLDER "MLIR libraries") # Setup aggregate. if(ARG_ENABLE_AGGREGATION) # Compute and store the properties needed to build aggregates. set(AGGREGATE_OBJECTS) set(AGGREGATE_OBJECT_LIB) set(AGGREGATE_DEPS) if(XCODE) # XCode has limited support for object libraries. Instead, add dep flags # that force the entire library to be embedded. list(APPEND AGGREGATE_DEPS "-force_load" "${name}") else() list(APPEND AGGREGATE_OBJECTS "$") list(APPEND AGGREGATE_OBJECT_LIB "obj.${name}") endif() # For each declared dependency, transform it into a generator expression # which excludes it if the ultimate link target is excluding the library. set(NEW_LINK_LIBRARIES) get_target_property(CURRENT_LINK_LIBRARIES ${name} LINK_LIBRARIES) get_mlir_filtered_link_libraries(NEW_LINK_LIBRARIES ${CURRENT_LINK_LIBRARIES}) set_target_properties(${name} PROPERTIES LINK_LIBRARIES "${NEW_LINK_LIBRARIES}") list(APPEND AGGREGATE_DEPS ${NEW_LINK_LIBRARIES}) set_target_properties(${name} PROPERTIES EXPORT_PROPERTIES "MLIR_AGGREGATE_OBJECT_LIB_IMPORTED;MLIR_AGGREGATE_DEP_LIBS_IMPORTED" MLIR_AGGREGATE_OBJECTS "${AGGREGATE_OBJECTS}" MLIR_AGGREGATE_DEPS "${AGGREGATE_DEPS}" MLIR_AGGREGATE_OBJECT_LIB_IMPORTED "${AGGREGATE_OBJECT_LIB}" MLIR_AGGREGATE_DEP_LIBS_IMPORTED "${CURRENT_LINK_LIBRARIES}" ) # In order for out-of-tree projects to build aggregates of this library, # we need to install the OBJECT library. if(MLIR_INSTALL_AGGREGATE_OBJECTS AND NOT ARG_DISABLE_INSTALL) add_mlir_library_install(obj.${name}) endif() endif() endfunction(add_mlir_library) macro(add_mlir_tool name) llvm_add_tool(MLIR ${ARGV}) endmacro() # Sets a variable with a transformed list of link libraries such individual # libraries will be dynamically excluded when evaluated on a final library # which defines an MLIR_AGGREGATE_EXCLUDE_LIBS which contains any of the # libraries. Each link library can be a generator expression but must not # resolve to an arity > 1 (i.e. it can be optional). function(get_mlir_filtered_link_libraries output) set(_results) foreach(linklib ${ARGN}) # In English, what this expression does: # For each link library, resolve the property MLIR_AGGREGATE_EXCLUDE_LIBS # on the context target (i.e. the executable or shared library being linked) # and, if it is not in that list, emit the library name. Otherwise, empty. list(APPEND _results "$<$>>>:${linklib}>" ) endforeach() set(${output} "${_results}" PARENT_SCOPE) endfunction(get_mlir_filtered_link_libraries) # Declares an aggregate library. Such a library is a combination of arbitrary # regular add_mlir_library() libraries with the special feature that they can # be configured to statically embed some subset of their dependencies, as is # typical when creating a .so/.dylib/.dll or a mondo static library. # # It is always safe to depend on the aggregate directly in order to compile/link # against the superset of embedded entities and transitive deps. # # Arguments: # PUBLIC_LIBS: list of dependent libraries to add to the # INTERFACE_LINK_LIBRARIES property, exporting them to users. This list # will be transitively filtered to exclude any EMBED_LIBS. # EMBED_LIBS: list of dependent libraries that should be embedded directly # into this library. Each of these must be an add_mlir_library() library # without DISABLE_AGGREGATE. # # Note: This is a work in progress and is presently only sufficient for certain # non nested cases involving the C-API. function(add_mlir_aggregate name) cmake_parse_arguments(ARG "SHARED;STATIC" "" "PUBLIC_LIBS;EMBED_LIBS" ${ARGN}) set(_libtype) if(ARG_STATIC) list(APPEND _libtype STATIC) endif() if(ARG_SHARED) list(APPEND _libtype SHARED) endif() set(_debugmsg) set(_embed_libs) set(_objects) set(_deps) foreach(lib ${ARG_EMBED_LIBS}) # We have to handle imported vs in-tree differently: # in-tree: To support arbitrary ordering, the generator expressions get # set on the dependent target when it is constructed and then just # eval'd here. This means we can build an aggregate from targets that # may not yet be defined, which is typical for in-tree. # imported: Exported properties do not support generator expressions, so # we imperatively query and manage the expansion here. This is fine # because imported targets will always be found/configured first and # do not need to support arbitrary ordering. If CMake every supports # exporting generator expressions, then this can be simplified. set(_is_imported OFF) if(TARGET ${lib}) get_target_property(_is_imported ${lib} IMPORTED) endif() if(NOT _is_imported) # Evaluate the in-tree generator expressions directly (this allows target # order independence, since these aren't evaluated until the generate # phase). # What these expressions do: # In the context of this aggregate, resolve the list of OBJECTS and DEPS # that each library advertises and patch it into the whole. set(_local_objects $>) set(_local_deps $>) else() # It is an imported target, which can only have flat strings populated # (no generator expressions). # Rebuild the generator expressions from the imported flat string lists. if(NOT MLIR_INSTALL_AGGREGATE_OBJECTS) message(SEND_ERROR "Cannot build aggregate from imported targets which were not installed via MLIR_INSTALL_AGGREGATE_OBJECTS (for ${lib}).") endif() get_property(_has_object_lib_prop TARGET ${lib} PROPERTY MLIR_AGGREGATE_OBJECT_LIB_IMPORTED SET) get_property(_has_dep_libs_prop TARGET ${lib} PROPERTY MLIR_AGGREGATE_DEP_LIBS_IMPORTED SET) if(NOT _has_object_lib_prop OR NOT _has_dep_libs_prop) message(SEND_ERROR "Cannot create an aggregate out of imported ${lib}: It is missing properties indicating that it was built for aggregation") endif() get_target_property(_imp_local_object_lib ${lib} MLIR_AGGREGATE_OBJECT_LIB_IMPORTED) get_target_property(_imp_dep_libs ${lib} MLIR_AGGREGATE_DEP_LIBS_IMPORTED) set(_local_objects) if(_imp_local_object_lib) set(_local_objects "$") endif() # We should just be able to do this: # get_mlir_filtered_link_libraries(_local_deps ${_imp_dep_libs}) # However, CMake complains about the unqualified use of the one-arg # $ expression. So we do the same thing but use the # two-arg form which takes an explicit target. foreach(_imp_dep_lib ${_imp_dep_libs}) # In English, what this expression does: # For each link library, resolve the property MLIR_AGGREGATE_EXCLUDE_LIBS # on the context target (i.e. the executable or shared library being linked) # and, if it is not in that list, emit the library name. Otherwise, empty. list(APPEND _local_deps "$<$>>>:${_imp_dep_lib}>" ) endforeach() endif() list(APPEND _embed_libs ${lib}) list(APPEND _objects ${_local_objects}) list(APPEND _deps ${_local_deps}) string(APPEND _debugmsg ": EMBED_LIB ${lib}:\n" " OBJECTS = ${_local_objects}\n" " DEPS = ${_local_deps}\n\n") endforeach() add_mlir_library(${name} ${_libtype} ${ARG_UNPARSED_ARGUMENTS} PARTIAL_SOURCES_INTENDED EXCLUDE_FROM_LIBMLIR LINK_LIBS PRIVATE ${_deps} ${ARG_PUBLIC_LIBS} ) target_sources(${name} PRIVATE ${_objects}) # Linux defaults to allowing undefined symbols in shared libraries whereas # many other platforms are more strict. We want these libraries to be # self contained, and we want any undefined symbols to be reported at # library construction time, not at library use, so make Linux strict too. # We make an exception for sanitizer builds, since the AddressSanitizer # run-time doesn't get linked into shared libraries. if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND (NOT LLVM_USE_SANITIZER)) target_link_options(${name} PRIVATE "LINKER:-z,defs" ) endif() # TODO: Should be transitive. set_target_properties(${name} PROPERTIES MLIR_AGGREGATE_EXCLUDE_LIBS "${_embed_libs}") if(MSVC) set_property(TARGET ${name} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() # Debugging generator expressions can be hard. Uncomment the below to emit # files next to the library with a lot of debug information: # string(APPEND _debugmsg # ": MAIN LIBRARY:\n" # " OBJECTS = ${_objects}\n" # " SOURCES = $>\n" # " DEPS = ${_deps}\n" # " LINK_LIBRARIES = $>\n" # " MLIR_AGGREGATE_EXCLUDE_LIBS = $>\n" # ) # file(GENERATE OUTPUT # "${CMAKE_CURRENT_BINARY_DIR}/${name}.aggregate_debug.txt" # CONTENT "${_debugmsg}" # ) endfunction(add_mlir_aggregate) # Adds an MLIR library target for installation. # This is usually done as part of add_mlir_library but is broken out for cases # where non-standard library builds can be installed. function(add_mlir_library_install name) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) get_target_export_arg(${name} MLIR export_to_mlirtargets UMBRELLA mlir-libraries) install(TARGETS ${name} COMPONENT ${name} ${export_to_mlirtargets} LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" # Note that CMake will create a directory like: # objects-${CMAKE_BUILD_TYPE}/obj.LibName # and put object files there. OBJECTS DESTINATION lib${LLVM_LIBDIR_SUFFIX} ) if (NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-${name} DEPENDS ${name} COMPONENT ${name}) endif() set_property(GLOBAL APPEND PROPERTY MLIR_ALL_LIBS ${name}) endif() set_property(GLOBAL APPEND PROPERTY MLIR_EXPORTS ${name}) endfunction() # Declare an mlir library which is part of the public C-API. function(add_mlir_public_c_api_library name) add_mlir_library(${name} ${ARGN} EXCLUDE_FROM_LIBMLIR ENABLE_AGGREGATION ADDITIONAL_HEADER_DIRS ${MLIR_MAIN_INCLUDE_DIR}/mlir-c ) # API libraries compile with hidden visibility and macros that enable # exporting from the DLL. Only apply to the obj lib, which only affects # the exports via a shared library. set_target_properties(obj.${name} PROPERTIES CXX_VISIBILITY_PRESET hidden ) target_compile_definitions(obj.${name} PRIVATE -DMLIR_CAPI_BUILDING_LIBRARY=1 ) endfunction() # Declare the library associated with a dialect. function(add_mlir_dialect_library name) set_property(GLOBAL APPEND PROPERTY MLIR_DIALECT_LIBS ${name}) add_mlir_library(${ARGV} DEPENDS mlir-headers) endfunction(add_mlir_dialect_library) # Declare the library associated with a conversion. function(add_mlir_conversion_library name) set_property(GLOBAL APPEND PROPERTY MLIR_CONVERSION_LIBS ${name}) add_mlir_library(${ARGV} DEPENDS mlir-headers) endfunction(add_mlir_conversion_library) # Declare the library associated with an extension. function(add_mlir_extension_library name) set_property(GLOBAL APPEND PROPERTY MLIR_EXTENSION_LIBS ${name}) add_mlir_library(${ARGV} DEPENDS mlir-headers) endfunction(add_mlir_extension_library) # Declare the library associated with a translation. function(add_mlir_translation_library name) set_property(GLOBAL APPEND PROPERTY MLIR_TRANSLATION_LIBS ${name}) add_mlir_library(${ARGV} DEPENDS mlir-headers) endfunction(add_mlir_translation_library) # Verification tools to aid debugging. function(mlir_check_link_libraries name) if(TARGET ${name}) get_target_property(type ${name} TYPE) if (${type} STREQUAL "INTERFACE_LIBRARY") get_target_property(libs ${name} INTERFACE_LINK_LIBRARIES) else() get_target_property(libs ${name} LINK_LIBRARIES) endif() # message("${name} libs are: ${libs}") set(linking_llvm 0) foreach(lib ${libs}) if(lib) if(${lib} MATCHES "^LLVM$") set(linking_llvm 1) endif() if((${lib} MATCHES "^LLVM.+") AND ${linking_llvm}) # This will almost always cause execution problems, since the # same symbol might be loaded from 2 separate libraries. This # often comes from referring to an LLVM library target # explicitly in target_link_libraries() message("WARNING: ${name} links LLVM and ${lib}!") endif() endif() endforeach() endif() endfunction(mlir_check_link_libraries) function(mlir_check_all_link_libraries name) mlir_check_link_libraries(${name}) if(TARGET ${name}) get_target_property(libs ${name} LINK_LIBRARIES) # message("${name} libs are: ${libs}") foreach(lib ${libs}) mlir_check_link_libraries(${lib}) endforeach() endif() endfunction(mlir_check_all_link_libraries)