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 @@ -23,11 +23,12 @@ # grouping. Source groupings form a DAG. # SOURCES: List of specific source files relative to ROOT_DIR to include. # SOURCES_GLOB: List of glob patterns relative to ROOT_DIR to include. +# DEPENDS: Additional dependency targets. function(declare_mlir_python_sources name) cmake_parse_arguments(ARG "" "ROOT_DIR;ADD_TO_PARENT" - "SOURCES;SOURCES_GLOB" + "SOURCES;SOURCES_GLOB;DEPENDS" ${ARGN}) if(NOT ARG_ROOT_DIR) @@ -50,6 +51,10 @@ # We create a custom target to carry properties and dependencies for # generated sources. add_library(${name} INTERFACE) + if(ARG_DEPENDS) + add_dependencies(${name} ${ARG_DEPENDS}) + endif() + set_target_properties(${name} PROPERTIES # Yes: Leading-lowercase property names are load bearing and the recommended # way to do this: https://gitlab.kitware.com/cmake/cmake/-/issues/19261 @@ -62,26 +67,22 @@ # properties we would like to export. These support generator expressions and # allow us to properly specify paths in both the local build and install scenarios. # The one caveat here is that because we don't directly build against the interface - # library, we need to specify the INCLUDE_DIRECTORIES and SOURCES properties as well - # via private properties because the evaluation would happen at configuration time - # instead of build time. - # Eventually this could be done using a FILE_SET simplifying the logic below. + # library, we will need to manually evaluate the expressions at configuration time. + # Eventually this could be done using a FILE_SET to simplify the evaluation logic. # FILE_SET is available in cmake 3.23+, so it is not an option at the moment. target_include_directories(${name} INTERFACE "$" "$" ) - set_property(TARGET ${name} PROPERTY INCLUDE_DIRECTORIES ${ARG_ROOT_DIR}) if(ARG_SOURCES) - list(TRANSFORM ARG_SOURCES PREPEND "${ARG_ROOT_DIR}/" OUTPUT_VARIABLE _build_sources) - list(TRANSFORM ARG_SOURCES PREPEND "${_install_destination}/" OUTPUT_VARIABLE _install_sources) - target_sources(${name} - INTERFACE - "$" - "$" - PRIVATE ${_build_sources} - ) + foreach(_src ${ARG_SOURCES}) + target_sources(${name} + INTERFACE + "$" + "$" + ) + endforeach() endif() # Add to parent. @@ -284,6 +285,7 @@ ADD_TO_PARENT "${ARG_ADD_TO_PARENT}" SOURCES "${ARG_SOURCES}" SOURCES_GLOB "${ARG_SOURCES_GLOB}" + DEPENDS ${ARG_DEPENDS} ) # Tablegen @@ -296,15 +298,18 @@ set(LLVM_TARGET_DEFINITIONS ${td_file}) mlir_tablegen("${dialect_filename}" -gen-python-op-bindings -bind-dialect=${ARG_DIALECT_NAME} - DEPENDS ${ARG_DEPENDS} ) add_public_tablegen_target(${tblgen_target}) + if(ARG_DEPENDS) + add_dependencies(${tblgen_target} ${ARG_DEPENDS}) + endif() # Generated. declare_mlir_python_sources("${_dialect_target}.ops_gen" ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}" ADD_TO_PARENT "${_dialect_target}" SOURCES "${dialect_filename}" + DEPENDS ${tblgen_target} ) endif() endfunction() @@ -338,6 +343,7 @@ ADD_TO_PARENT "${ARG_ADD_TO_PARENT}" SOURCES "${ARG_SOURCES}" SOURCES_GLOB "${ARG_SOURCES_GLOB}" + DEPENDS ${ARG_DEPENDS} ) # Tablegen @@ -348,9 +354,10 @@ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${relative_td_directory}") set(output_filename "${relative_td_directory}/_${ARG_EXTENSION_NAME}_ops_gen.py") set(LLVM_TARGET_DEFINITIONS ${td_file}) - mlir_tablegen("${output_filename}" -gen-python-op-bindings - -bind-dialect=${ARG_DIALECT_NAME} - -dialect-extension=${ARG_EXTENSION_NAME}) + mlir_tablegen("${output_filename}" + -gen-python-op-bindings -bind-dialect=${ARG_DIALECT_NAME} + -dialect-extension=${ARG_EXTENSION_NAME} + ) add_public_tablegen_target(${tblgen_target}) if(ARG_DEPENDS) add_dependencies(${tblgen_target} ${ARG_DEPENDS}) @@ -360,6 +367,7 @@ ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}" ADD_TO_PARENT "${_extension_target}" SOURCES "${output_filename}" + DEPENDS ${tblgen_target} ) endif() endfunction() @@ -539,17 +547,43 @@ foreach(_sources_target ${ARG_SOURCES_TARGETS}) add_dependencies(${name} ${_sources_target}) - get_target_property(_src_paths ${_sources_target} SOURCES) + # We use interface libraries to carry information about the sources via the + # INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_SOURCES properties. These support + # generator expressions and allows us to specify the paths for both the local and install + # scenarios. However, because the setup below happens at *configuration* time instead of + # build time, the generator expressions have not yet been evaluated in the local build + # case. To work around this, we do our own "evaluation" of the BUILD_INTERFACE expression. + # Eventually this could be done using a FILE_SET simplifying the logic below. + # FILE_SET is available in cmake 3.23+, so it is not an option at the moment. + set(_build_regex "^\\$\$") + set(_install_regex "^\\$\$") + + set(_src_paths) + get_target_property(_interface_src_paths ${_sources_target} INTERFACE_SOURCES) + if(_interface_src_paths) + foreach(_interface_src_path ${_interface_src_paths}) + if(NOT _interface_src_path MATCHES ${_build_regex} AND NOT _interface_src_path MATCHES ${_install_regex}) + list(APPEND _src_paths ${_interface_src_path}) + elseif(_interface_src_path MATCHES ${_build_regex}) + string(REGEX REPLACE ${_build_regex} "\\1" _build_src_path ${_interface_src_path}) + list(APPEND _src_paths ${_build_src_path}) + endif() + endforeach() + endif() if(NOT _src_paths) - get_target_property(_src_paths ${_sources_target} INTERFACE_SOURCES) - if(NOT _src_paths) - break() - endif() + break() endif() - get_target_property(_root_dir ${_sources_target} INCLUDE_DIRECTORIES) - if(NOT _root_dir) - get_target_property(_root_dir ${_sources_target} INTERFACE_INCLUDE_DIRECTORIES) + set(_root_dir) + get_target_property(_interface_root_dirs ${_sources_target} INTERFACE_INCLUDE_DIRECTORIES) + if(_interface_root_dirs) + foreach(_interface_root_dir ${_interface_root_dirs}) + if(NOT _interface_root_dir MATCHES ${_build_regex} AND NOT _interface_root_dir MATCHES ${_install_regex}) + set(_root_dir ${_interface_root_dir}) + elseif(_interface_root_dir MATCHES ${_build_regex}) + string(REGEX REPLACE ${_build_regex} "\\1" _root_dir ${_interface_root_dir}) + endif() + endforeach() endif() foreach(_src_path ${_src_paths}) diff --git a/mlir/python/CMakeLists.txt b/mlir/python/CMakeLists.txt --- a/mlir/python/CMakeLists.txt +++ b/mlir/python/CMakeLists.txt @@ -469,7 +469,8 @@ MLIRPythonTestSources.Dialects.PythonTest.ops_gen ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}" ADD_TO_PARENT MLIRPythonTestSources.Dialects.PythonTest - SOURCES "dialects/_python_test_ops_gen.py") + SOURCES "dialects/_python_test_ops_gen.py" + DEPENDS PythonTestDialectPyIncGen) declare_mlir_python_extension(MLIRPythonTestSources.PythonTestExtension MODULE_NAME _mlirPythonTest