diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake --- a/mlir/cmake/modules/AddMLIR.cmake +++ b/mlir/cmake/modules/AddMLIR.cmake @@ -54,7 +54,7 @@ # with large dependencies. function(add_mlir_library name) cmake_parse_arguments(ARG - "SHARED;INSTALL_WITH_TOOLCHAIN;EXCLUDE_FROM_LIBMLIR" + "SHARED;INSTALL_WITH_TOOLCHAIN;EXCLUDE_FROM_LIBMLIR;DISABLE_AGGREGATE" "" "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS" ${ARGN}) @@ -100,18 +100,19 @@ else() set(LIBTYPE STATIC) endif() - if(NOT XCODE) - # The Xcode generator doesn't handle object libraries correctly. - list(APPEND LIBTYPE OBJECT) - endif() # Test libraries and such shouldn't be include in libMLIR.so - if(NOT ARG_EXCLUDE_FROM_LIBMLIR) + if(NOT ARG_EXCLUDE_FROM_LIBMLIR AND NOT ARG_DISABLE_AGGREGATE) 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(NOT XCODE AND NOT ARG_DISABLE_AGGREGATE) + # The Xcode generator doesn't handle object libraries correctly. + list(APPEND LIBTYPE OBJECT) + endif() + # MLIR libraries uniformly depend on LLVMSupport. Just specify it once here. list(APPEND ARG_LINK_COMPONENTS Support) @@ -137,8 +138,139 @@ add_custom_target(${name}) endif() set_target_properties(${name} PROPERTIES FOLDER "MLIR libraries") + + # Setup aggregate. + if(NOT ARG_DISABLE_AGGREGATE) + # Compute and store the properties needed to build aggregates. + set(AGGREGATE_OBJECTS) + 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 "$") + 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 + MLIR_AGGREGATE_OBJECTS "${AGGREGATE_OBJECTS}" + ) + set_target_properties(${name} PROPERTIES + MLIR_AGGREGATE_DEPS "${AGGREGATE_DEPS}" + ) + endif() endfunction(add_mlir_library) +# 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}) + # 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 $>) + + 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 + DISABLE_AGGREGATE + "${LLVM_MAIN_SRC_DIR}/cmake/dummy.cpp" + LINK_LIBS PRIVATE + ${_deps} + ${ARG_PUBLIC_LIBS} + ) + target_sources(${name} PRIVATE ${_objects}) + # 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() + 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. diff --git a/mlir/cmake/modules/AddMLIRPython.cmake b/mlir/cmake/modules/AddMLIRPython.cmake --- a/mlir/cmake/modules/AddMLIRPython.cmake +++ b/mlir/cmake/modules/AddMLIRPython.cmake @@ -78,6 +78,7 @@ OUTPUT_NAME "${extname}" PREFIX "${PYTHON_MODULE_PREFIX}" SUFFIX "${PYTHON_MODULE_SUFFIX}${PYTHON_MODULE_EXTENSION}" + NO_SONAME ON ) if(WIN32) @@ -96,8 +97,6 @@ # to take place. set_target_properties(${libname} PROPERTIES CXX_VISIBILITY_PRESET "hidden") - # Python extensions depends *only* on the public API and LLVMSupport unless - # if further dependencies are added explicitly. target_link_libraries(${libname} PRIVATE ${ARG_LINK_LIBS} diff --git a/mlir/lib/Bindings/Python/CMakeLists.txt b/mlir/lib/Bindings/Python/CMakeLists.txt --- a/mlir/lib/Bindings/Python/CMakeLists.txt +++ b/mlir/lib/Bindings/Python/CMakeLists.txt @@ -10,49 +10,27 @@ # use needs to be made more flexible. ################################################################################ -set(public_api_libs - MLIRCAPIConversion - MLIRCAPIDebug - MLIRCEXECUTIONENGINE - MLIRCAPIIR - MLIRCAPIRegistration - MLIRCAPITransforms - - # Dialects - MLIRCAPIAsync - MLIRCAPIGPU - MLIRCAPILinalg - MLIRCAPILLVM - MLIRCAPIShape - MLIRCAPISparseTensor - MLIRCAPIStandard - MLIRCAPISCF - MLIRCAPITensor -) - -foreach(lib ${public_api_libs}) - if(XCODE) - # Xcode doesn't support object libraries, so we have to trick it into - # linking the static libraries instead. - list(APPEND _DEPS "-force_load" ${lib}) - else() - list(APPEND _OBJECTS $) - endif() - # Accumulate transitive deps of each exported lib into _DEPS. - list(APPEND _DEPS $) -endforeach() - -add_mlir_library(MLIRPythonCAPI - PARTIAL_SOURCES_INTENDED +add_mlir_aggregate(MLIRPythonCAPI SHARED - ${_OBJECTS} - EXCLUDE_FROM_LIBMLIR - LINK_LIBS - ${_DEPS} + EMBED_LIBS + MLIRCAPIConversion + MLIRCAPIDebug + MLIRCEXECUTIONENGINE + MLIRCAPIIR + MLIRCAPIRegistration + MLIRCAPITransforms + + # Dialects + MLIRCAPIAsync + MLIRCAPIGPU + MLIRCAPILinalg + MLIRCAPILLVM + MLIRCAPIShape + MLIRCAPISparseTensor + MLIRCAPIStandard + MLIRCAPISCF + MLIRCAPITensor ) -if(MSVC) - set_property(TARGET MLIRPythonCAPI PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON) -endif() ################################################################################ # Build core python extension diff --git a/mlir/lib/ExecutionEngine/CMakeLists.txt b/mlir/lib/ExecutionEngine/CMakeLists.txt --- a/mlir/lib/ExecutionEngine/CMakeLists.txt +++ b/mlir/lib/ExecutionEngine/CMakeLists.txt @@ -17,7 +17,7 @@ ExecutionEngine.cpp OptUtils.cpp - EXCLUDE_FROM_LIBMLIR + DISABLE_AGGREGATE ADDITIONAL_HEADER_DIRS ${MLIR_MAIN_INCLUDE_DIR}/mlir/ExecutionEngine @@ -53,7 +53,7 @@ add_mlir_library(MLIRJitRunner JitRunner.cpp - EXCLUDE_FROM_LIBMLIR + DISABLE_AGGREGATE DEPENDS intrinsics_gen @@ -77,29 +77,23 @@ ) add_mlir_library(mlir_c_runner_utils - SHARED + SHARED DISABLE_AGGREGATE CRunnerUtils.cpp SparseUtils.cpp - - EXCLUDE_FROM_LIBMLIR ) set_property(TARGET mlir_c_runner_utils PROPERTY CXX_STANDARD 11) target_compile_definitions(mlir_c_runner_utils PRIVATE mlir_c_runner_utils_EXPORTS) add_mlir_library(mlir_runner_utils - SHARED + SHARED DISABLE_AGGREGATE RunnerUtils.cpp - - EXCLUDE_FROM_LIBMLIR ) target_compile_definitions(mlir_runner_utils PRIVATE mlir_runner_utils_EXPORTS) add_mlir_library(mlir_async_runtime - SHARED + SHARED DISABLE_AGGREGATE AsyncRuntime.cpp - EXCLUDE_FROM_LIBMLIR - LINK_LIBS PUBLIC ${LLVM_PTHREAD_LIB} ) @@ -122,10 +116,8 @@ find_library(CUDA_RUNTIME_LIBRARY cuda) add_mlir_library(mlir_cuda_runtime - SHARED + SHARED DISABLE_AGGREGATE CudaRuntimeWrappers.cpp - - EXCLUDE_FROM_LIBMLIR ) set_property(TARGET mlir_cuda_runtime PROPERTY CXX_STANDARD 14) target_include_directories(mlir_cuda_runtime @@ -166,10 +158,8 @@ endif() add_mlir_library(mlir_rocm_runtime - SHARED + SHARED DISABLE_AGGREGATE RocmRuntimeWrappers.cpp - - EXCLUDE_FROM_LIBMLIR ) target_compile_definitions(mlir_rocm_runtime PRIVATE