19f3f6d7bSStella Laurenzo################################################################################ 2310c9496SStella Laurenzo# Python modules 3310c9496SStella Laurenzo# MLIR's Python modules are both directly used by the core project and are 4310c9496SStella Laurenzo# available for use and embedding into external projects (in their own 5310c9496SStella Laurenzo# namespace and with their own deps). In order to facilitate this, python 6310c9496SStella Laurenzo# artifacts are split between declarations, which make a subset of 7310c9496SStella Laurenzo# things available to be built and "add", which in line with the normal LLVM 8310c9496SStella Laurenzo# nomenclature, adds libraries. 9310c9496SStella Laurenzo################################################################################ 10310c9496SStella Laurenzo 11310c9496SStella Laurenzo# Function: declare_mlir_python_sources 12310c9496SStella Laurenzo# Declares pure python sources as part of a named grouping that can be built 13310c9496SStella Laurenzo# later. 14310c9496SStella Laurenzo# Arguments: 15310c9496SStella Laurenzo# ROOT_DIR: Directory where the python namespace begins (defaults to 16310c9496SStella Laurenzo# CMAKE_CURRENT_SOURCE_DIR). For non-relocatable sources, this will 17310c9496SStella Laurenzo# typically just be the root of the python source tree (current directory). 18310c9496SStella Laurenzo# For relocatable sources, this will point deeper into the directory that 19310c9496SStella Laurenzo# can be relocated. For generated sources, can be relative to 20310c9496SStella Laurenzo# CMAKE_CURRENT_BINARY_DIR. Generated and non generated sources cannot be 21310c9496SStella Laurenzo# mixed. 22310c9496SStella Laurenzo# ADD_TO_PARENT: Adds this source grouping to a previously declared source 23310c9496SStella Laurenzo# grouping. Source groupings form a DAG. 24310c9496SStella Laurenzo# SOURCES: List of specific source files relative to ROOT_DIR to include. 25310c9496SStella Laurenzo# SOURCES_GLOB: List of glob patterns relative to ROOT_DIR to include. 26310c9496SStella Laurenzofunction(declare_mlir_python_sources name) 27310c9496SStella Laurenzo cmake_parse_arguments(ARG 28310c9496SStella Laurenzo "" 29ac521d9eSStella Stamenova "ROOT_DIR;ADD_TO_PARENT" 30310c9496SStella Laurenzo "SOURCES;SOURCES_GLOB" 31310c9496SStella Laurenzo ${ARGN}) 32310c9496SStella Laurenzo 33310c9496SStella Laurenzo if(NOT ARG_ROOT_DIR) 34310c9496SStella Laurenzo set(ARG_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 35310c9496SStella Laurenzo endif() 36132bc6e2SStella Laurenzo set(_install_destination "src/python/${name}") 37310c9496SStella Laurenzo 38310c9496SStella Laurenzo # Process the glob. 39310c9496SStella Laurenzo set(_glob_sources) 40310c9496SStella Laurenzo if(ARG_SOURCES_GLOB) 41310c9496SStella Laurenzo set(_glob_spec ${ARG_SOURCES_GLOB}) 42310c9496SStella Laurenzo list(TRANSFORM _glob_spec PREPEND "${ARG_ROOT_DIR}/") 43310c9496SStella Laurenzo file(GLOB_RECURSE _glob_sources 44310c9496SStella Laurenzo RELATIVE "${ARG_ROOT_DIR}" 45310c9496SStella Laurenzo ${_glob_spec} 46310c9496SStella Laurenzo ) 47310c9496SStella Laurenzo list(APPEND ARG_SOURCES ${_glob_sources}) 48310c9496SStella Laurenzo endif() 49310c9496SStella Laurenzo 50310c9496SStella Laurenzo # We create a custom target to carry properties and dependencies for 51310c9496SStella Laurenzo # generated sources. 52132bc6e2SStella Laurenzo add_library(${name} INTERFACE) 53310c9496SStella Laurenzo set_target_properties(${name} PROPERTIES 54132bc6e2SStella Laurenzo # Yes: Leading-lowercase property names are load bearing and the recommended 55132bc6e2SStella Laurenzo # way to do this: https://gitlab.kitware.com/cmake/cmake/-/issues/19261 56ac521d9eSStella Stamenova EXPORT_PROPERTIES "mlir_python_SOURCES_TYPE;mlir_python_DEPENDS" 57132bc6e2SStella Laurenzo mlir_python_SOURCES_TYPE pure 58132bc6e2SStella Laurenzo mlir_python_DEPENDS "" 59132bc6e2SStella Laurenzo ) 60ac521d9eSStella Stamenova 61ac521d9eSStella Stamenova # Use the interface include directories and sources on the target to carry the 62ac521d9eSStella Stamenova # properties we would like to export. These support generator expressions and 63ac521d9eSStella Stamenova # allow us to properly specify paths in both the local build and install scenarios. 64ac521d9eSStella Stamenova # The one caveat here is that because we don't directly build against the interface 65ac521d9eSStella Stamenova # library, we need to specify the INCLUDE_DIRECTORIES and SOURCES properties as well 66ac521d9eSStella Stamenova # via private properties because the evaluation would happen at configuration time 67ac521d9eSStella Stamenova # instead of build time. 68ac521d9eSStella Stamenova # Eventually this could be done using a FILE_SET simplifying the logic below. 69ac521d9eSStella Stamenova # FILE_SET is available in cmake 3.23+, so it is not an option at the moment. 70132bc6e2SStella Laurenzo target_include_directories(${name} INTERFACE 71132bc6e2SStella Laurenzo "$<BUILD_INTERFACE:${ARG_ROOT_DIR}>" 72132bc6e2SStella Laurenzo "$<INSTALL_INTERFACE:${_install_destination}>" 73310c9496SStella Laurenzo ) 74ac521d9eSStella Stamenova set_property(TARGET ${name} PROPERTY INCLUDE_DIRECTORIES ${ARG_ROOT_DIR}) 75ac521d9eSStella Stamenova 76ac521d9eSStella Stamenova if(ARG_SOURCES) 77ac521d9eSStella Stamenova list(TRANSFORM ARG_SOURCES PREPEND "${ARG_ROOT_DIR}/" OUTPUT_VARIABLE _build_sources) 78ac521d9eSStella Stamenova list(TRANSFORM ARG_SOURCES PREPEND "${_install_destination}/" OUTPUT_VARIABLE _install_sources) 79ac521d9eSStella Stamenova target_sources(${name} 80ac521d9eSStella Stamenova INTERFACE 81ac521d9eSStella Stamenova "$<INSTALL_INTERFACE:${_install_sources}>" 82ac521d9eSStella Stamenova "$<BUILD_INTERFACE:${_build_sources}>" 83ac521d9eSStella Stamenova PRIVATE ${_build_sources} 84ac521d9eSStella Stamenova ) 85ac521d9eSStella Stamenova endif() 86310c9496SStella Laurenzo 87310c9496SStella Laurenzo # Add to parent. 88310c9496SStella Laurenzo if(ARG_ADD_TO_PARENT) 89132bc6e2SStella Laurenzo set_property(TARGET ${ARG_ADD_TO_PARENT} APPEND PROPERTY mlir_python_DEPENDS ${name}) 90132bc6e2SStella Laurenzo endif() 91132bc6e2SStella Laurenzo 92132bc6e2SStella Laurenzo # Install. 93132bc6e2SStella Laurenzo set_property(GLOBAL APPEND PROPERTY MLIR_EXPORTS ${name}) 94132bc6e2SStella Laurenzo if(NOT LLVM_INSTALL_TOOLCHAIN_ONLY) 95132bc6e2SStella Laurenzo _mlir_python_install_sources( 96132bc6e2SStella Laurenzo ${name} "${ARG_ROOT_DIR}" "${_install_destination}" 97132bc6e2SStella Laurenzo ${ARG_SOURCES} 98132bc6e2SStella Laurenzo ) 99310c9496SStella Laurenzo endif() 100310c9496SStella Laurenzoendfunction() 101310c9496SStella Laurenzo 102310c9496SStella Laurenzo# Function: declare_mlir_python_extension 103310c9496SStella Laurenzo# Declares a buildable python extension from C++ source files. The built 104310c9496SStella Laurenzo# module is considered a python source file and included as everything else. 105310c9496SStella Laurenzo# Arguments: 106132bc6e2SStella Laurenzo# ROOT_DIR: Root directory where sources are interpreted relative to. 107132bc6e2SStella Laurenzo# Defaults to CMAKE_CURRENT_SOURCE_DIR. 108310c9496SStella Laurenzo# MODULE_NAME: Local import name of the module (i.e. "_mlir"). 109310c9496SStella Laurenzo# ADD_TO_PARENT: Same as for declare_mlir_python_sources. 110310c9496SStella Laurenzo# SOURCES: C++ sources making up the module. 111310c9496SStella Laurenzo# PRIVATE_LINK_LIBS: List of libraries to link in privately to the module 112310c9496SStella Laurenzo# regardless of how it is included in the project (generally should be 113310c9496SStella Laurenzo# static libraries that can be included with hidden visibility). 114310c9496SStella Laurenzo# EMBED_CAPI_LINK_LIBS: Dependent CAPI libraries that this extension depends 115310c9496SStella Laurenzo# on. These will be collected for all extensions and put into an 116310c9496SStella Laurenzo# aggregate dylib that is linked against. 117392622d0SMaksim Levental# PYTHON_BINDINGS_LIBRARY: Either pybind11 or nanobind. 118310c9496SStella Laurenzofunction(declare_mlir_python_extension name) 119310c9496SStella Laurenzo cmake_parse_arguments(ARG 120310c9496SStella Laurenzo "" 121392622d0SMaksim Levental "ROOT_DIR;MODULE_NAME;ADD_TO_PARENT;PYTHON_BINDINGS_LIBRARY" 122310c9496SStella Laurenzo "SOURCES;PRIVATE_LINK_LIBS;EMBED_CAPI_LINK_LIBS" 123310c9496SStella Laurenzo ${ARGN}) 124310c9496SStella Laurenzo 125132bc6e2SStella Laurenzo if(NOT ARG_ROOT_DIR) 126132bc6e2SStella Laurenzo set(ARG_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 127132bc6e2SStella Laurenzo endif() 128132bc6e2SStella Laurenzo set(_install_destination "src/python/${name}") 129132bc6e2SStella Laurenzo 130392622d0SMaksim Levental if(NOT ARG_PYTHON_BINDINGS_LIBRARY) 131392622d0SMaksim Levental set(ARG_PYTHON_BINDINGS_LIBRARY "pybind11") 132392622d0SMaksim Levental endif() 133392622d0SMaksim Levental 134132bc6e2SStella Laurenzo add_library(${name} INTERFACE) 135310c9496SStella Laurenzo set_target_properties(${name} PROPERTIES 136132bc6e2SStella Laurenzo # Yes: Leading-lowercase property names are load bearing and the recommended 137132bc6e2SStella Laurenzo # way to do this: https://gitlab.kitware.com/cmake/cmake/-/issues/19261 138392622d0SMaksim Levental EXPORT_PROPERTIES "mlir_python_SOURCES_TYPE;mlir_python_EXTENSION_MODULE_NAME;mlir_python_EMBED_CAPI_LINK_LIBS;mlir_python_DEPENDS;mlir_python_BINDINGS_LIBRARY" 139132bc6e2SStella Laurenzo mlir_python_SOURCES_TYPE extension 140132bc6e2SStella Laurenzo mlir_python_EXTENSION_MODULE_NAME "${ARG_MODULE_NAME}" 141132bc6e2SStella Laurenzo mlir_python_EMBED_CAPI_LINK_LIBS "${ARG_EMBED_CAPI_LINK_LIBS}" 142132bc6e2SStella Laurenzo mlir_python_DEPENDS "" 143392622d0SMaksim Levental mlir_python_BINDINGS_LIBRARY "${ARG_PYTHON_BINDINGS_LIBRARY}" 144132bc6e2SStella Laurenzo ) 145ac521d9eSStella Stamenova 146ac521d9eSStella Stamenova # Set the interface source and link_libs properties of the target 147ac521d9eSStella Stamenova # These properties support generator expressions and are automatically exported 148ac521d9eSStella Stamenova list(TRANSFORM ARG_SOURCES PREPEND "${ARG_ROOT_DIR}/" OUTPUT_VARIABLE _build_sources) 149ac521d9eSStella Stamenova list(TRANSFORM ARG_SOURCES PREPEND "${_install_destination}/" OUTPUT_VARIABLE _install_sources) 150ac521d9eSStella Stamenova target_sources(${name} INTERFACE 151ac521d9eSStella Stamenova "$<BUILD_INTERFACE:${_build_sources}>" 152ac521d9eSStella Stamenova "$<INSTALL_INTERFACE:${_install_sources}>" 153ac521d9eSStella Stamenova ) 154ac521d9eSStella Stamenova target_link_libraries(${name} INTERFACE 155ac521d9eSStella Stamenova ${ARG_PRIVATE_LINK_LIBS} 156310c9496SStella Laurenzo ) 157310c9496SStella Laurenzo 158310c9496SStella Laurenzo # Add to parent. 159310c9496SStella Laurenzo if(ARG_ADD_TO_PARENT) 160132bc6e2SStella Laurenzo set_property(TARGET ${ARG_ADD_TO_PARENT} APPEND PROPERTY mlir_python_DEPENDS ${name}) 161310c9496SStella Laurenzo endif() 162132bc6e2SStella Laurenzo 163132bc6e2SStella Laurenzo # Install. 164132bc6e2SStella Laurenzo set_property(GLOBAL APPEND PROPERTY MLIR_EXPORTS ${name}) 165132bc6e2SStella Laurenzo if(NOT LLVM_INSTALL_TOOLCHAIN_ONLY) 166132bc6e2SStella Laurenzo _mlir_python_install_sources( 167ac521d9eSStella Stamenova ${name} "${ARG_ROOT_DIR}" "${_install_destination}" 168132bc6e2SStella Laurenzo ${ARG_SOURCES} 169132bc6e2SStella Laurenzo ) 170132bc6e2SStella Laurenzo endif() 171132bc6e2SStella Laurenzoendfunction() 172132bc6e2SStella Laurenzo 173132bc6e2SStella Laurenzofunction(_mlir_python_install_sources name source_root_dir destination) 174132bc6e2SStella Laurenzo foreach(source_relative_path ${ARGN}) 175132bc6e2SStella Laurenzo # Transform "a/b/c.py" -> "${install_prefix}/a/b" for installation. 176132bc6e2SStella Laurenzo get_filename_component( 177ac521d9eSStella Stamenova dest_relative_dir "${source_relative_path}" DIRECTORY 178132bc6e2SStella Laurenzo BASE_DIR "${source_root_dir}" 179132bc6e2SStella Laurenzo ) 180132bc6e2SStella Laurenzo install( 181132bc6e2SStella Laurenzo FILES "${source_root_dir}/${source_relative_path}" 182ac521d9eSStella Stamenova DESTINATION "${destination}/${dest_relative_dir}" 1839494bd84SJack Wolfard COMPONENT mlir-python-sources 184132bc6e2SStella Laurenzo ) 185132bc6e2SStella Laurenzo endforeach() 1869494bd84SJack Wolfard get_target_export_arg(${name} MLIR export_to_mlirtargets 1879494bd84SJack Wolfard UMBRELLA mlir-python-sources) 188132bc6e2SStella Laurenzo install(TARGETS ${name} 1899494bd84SJack Wolfard COMPONENT mlir-python-sources 190132bc6e2SStella Laurenzo ${export_to_mlirtargets} 191132bc6e2SStella Laurenzo ) 192310c9496SStella Laurenzoendfunction() 193310c9496SStella Laurenzo 194310c9496SStella Laurenzo# Function: add_mlir_python_modules 195310c9496SStella Laurenzo# Adds python modules to a project, building them from a list of declared 196310c9496SStella Laurenzo# source groupings (see declare_mlir_python_sources and 197310c9496SStella Laurenzo# declare_mlir_python_extension). One of these must be called for each 198310c9496SStella Laurenzo# packaging root in use. 199310c9496SStella Laurenzo# Arguments: 200310c9496SStella Laurenzo# ROOT_PREFIX: The directory in the build tree to emit sources. This will 201310c9496SStella Laurenzo# typically be something like ${MY_BINARY_DIR}/python_packages/foobar 202310c9496SStella Laurenzo# for non-relocatable modules or a deeper directory tree for relocatable. 203310c9496SStella Laurenzo# INSTALL_PREFIX: Prefix into the install tree for installing the package. 204310c9496SStella Laurenzo# Typically mirrors the path above but without an absolute path. 205310c9496SStella Laurenzo# DECLARED_SOURCES: List of declared source groups to include. The entire 206310c9496SStella Laurenzo# DAG of source modules is included. 207310c9496SStella Laurenzo# COMMON_CAPI_LINK_LIBS: List of dylibs (typically one) to make every 208310c9496SStella Laurenzo# extension depend on (see mlir_python_add_common_capi_library). 209310c9496SStella Laurenzofunction(add_mlir_python_modules name) 210310c9496SStella Laurenzo cmake_parse_arguments(ARG 211310c9496SStella Laurenzo "" 21299c43e3cSBimo "ROOT_PREFIX;INSTALL_PREFIX" 21399c43e3cSBimo "COMMON_CAPI_LINK_LIBS;DECLARED_SOURCES" 214310c9496SStella Laurenzo ${ARGN}) 215310c9496SStella Laurenzo # Helper to process an individual target. 216310c9496SStella Laurenzo function(_process_target modules_target sources_target) 217132bc6e2SStella Laurenzo get_target_property(_source_type ${sources_target} mlir_python_SOURCES_TYPE) 218132bc6e2SStella Laurenzo 219310c9496SStella Laurenzo if(_source_type STREQUAL "pure") 220310c9496SStella Laurenzo # Pure python sources to link into the tree. 221aa78c529SStella Laurenzo set(_pure_sources_target "${modules_target}.sources.${sources_target}") 222ac521d9eSStella Stamenova add_mlir_python_sources_target(${_pure_sources_target} 223ac521d9eSStella Stamenova INSTALL_COMPONENT ${modules_target} 224ac521d9eSStella Stamenova INSTALL_DIR ${ARG_INSTALL_PREFIX} 225ac521d9eSStella Stamenova OUTPUT_DIRECTORY ${ARG_ROOT_PREFIX} 226ac521d9eSStella Stamenova SOURCES_TARGETS ${sources_target} 227310c9496SStella Laurenzo ) 228ac521d9eSStella Stamenova add_dependencies(${modules_target} ${_pure_sources_target}) 229310c9496SStella Laurenzo elseif(_source_type STREQUAL "extension") 230310c9496SStella Laurenzo # Native CPP extension. 231132bc6e2SStella Laurenzo get_target_property(_module_name ${sources_target} mlir_python_EXTENSION_MODULE_NAME) 232392622d0SMaksim Levental get_target_property(_bindings_library ${sources_target} mlir_python_BINDINGS_LIBRARY) 233132bc6e2SStella Laurenzo # Transform relative source to based on root dir. 234ac521d9eSStella Stamenova set(_extension_target "${modules_target}.extension.${_module_name}.dso") 235310c9496SStella Laurenzo add_mlir_python_extension(${_extension_target} "${_module_name}" 236310c9496SStella Laurenzo INSTALL_COMPONENT ${modules_target} 237310c9496SStella Laurenzo INSTALL_DIR "${ARG_INSTALL_PREFIX}/_mlir_libs" 238310c9496SStella Laurenzo OUTPUT_DIRECTORY "${ARG_ROOT_PREFIX}/_mlir_libs" 239392622d0SMaksim Levental PYTHON_BINDINGS_LIBRARY ${_bindings_library} 240310c9496SStella Laurenzo LINK_LIBS PRIVATE 241ac521d9eSStella Stamenova ${sources_target} 242310c9496SStella Laurenzo ${ARG_COMMON_CAPI_LINK_LIBS} 243310c9496SStella Laurenzo ) 244ac521d9eSStella Stamenova add_dependencies(${modules_target} ${_extension_target}) 245310c9496SStella Laurenzo mlir_python_setup_extension_rpath(${_extension_target}) 246310c9496SStella Laurenzo else() 247310c9496SStella Laurenzo message(SEND_ERROR "Unrecognized source type '${_source_type}' for python source target ${sources_target}") 248310c9496SStella Laurenzo return() 249310c9496SStella Laurenzo endif() 250310c9496SStella Laurenzo endfunction() 251310c9496SStella Laurenzo 252310c9496SStella Laurenzo # Build the modules target. 253ac521d9eSStella Stamenova add_custom_target(${name} ALL) 254ac521d9eSStella Stamenova _flatten_mlir_python_targets(_flat_targets ${ARG_DECLARED_SOURCES}) 255310c9496SStella Laurenzo foreach(sources_target ${_flat_targets}) 256310c9496SStella Laurenzo _process_target(${name} ${sources_target}) 257310c9496SStella Laurenzo endforeach() 258310c9496SStella Laurenzo 259310c9496SStella Laurenzo # Create an install target. 260310c9496SStella Laurenzo if(NOT LLVM_ENABLE_IDE) 261310c9496SStella Laurenzo add_llvm_install_targets( 262310c9496SStella Laurenzo install-${name} 263310c9496SStella Laurenzo DEPENDS ${name} 264310c9496SStella Laurenzo COMPONENT ${name}) 265310c9496SStella Laurenzo endif() 266310c9496SStella Laurenzoendfunction() 267310c9496SStella Laurenzo 268310c9496SStella Laurenzo# Function: declare_mlir_dialect_python_bindings 269310c9496SStella Laurenzo# Helper to generate source groups for dialects, including both static source 270310c9496SStella Laurenzo# files and a TD_FILE to generate wrappers. 271310c9496SStella Laurenzo# 272310c9496SStella Laurenzo# This will generate a source group named ${ADD_TO_PARENT}.${DIALECT_NAME}. 273310c9496SStella Laurenzo# 274310c9496SStella Laurenzo# Arguments: 275310c9496SStella Laurenzo# ROOT_DIR: Same as for declare_mlir_python_sources(). 276310c9496SStella Laurenzo# ADD_TO_PARENT: Same as for declare_mlir_python_sources(). Unique names 277310c9496SStella Laurenzo# for the subordinate source groups are derived from this. 278310c9496SStella Laurenzo# TD_FILE: Tablegen file to generate source for (relative to ROOT_DIR). 279310c9496SStella Laurenzo# DIALECT_NAME: Python name of the dialect. 280310c9496SStella Laurenzo# SOURCES: Same as declare_mlir_python_sources(). 281310c9496SStella Laurenzo# SOURCES_GLOB: Same as declare_mlir_python_sources(). 282310c9496SStella Laurenzo# DEPENDS: Additional dependency targets. 28392233062Smax# GEN_ENUM_BINDINGS: Generate enum bindings. 28492233062Smax# GEN_ENUM_BINDINGS_TD_FILE: Optional Tablegen file to generate enums for (relative to ROOT_DIR). 28592233062Smax# This file is where the *EnumAttrs are defined, not where the *Enums are defined. 28692233062Smax# **WARNING**: This arg will shortly be removed when the just-below TODO is satisfied. Use at your 28792233062Smax# risk. 28867a910bbSRahul Kayaith# 28967a910bbSRahul Kayaith# TODO: Right now `TD_FILE` can't be the actual dialect tablegen file, since we 29067a910bbSRahul Kayaith# use its path to determine where to place the generated python file. If 29167a910bbSRahul Kayaith# we made the output path an additional argument here we could remove the 29267a910bbSRahul Kayaith# need for the separate "wrapper" .td files 293310c9496SStella Laurenzofunction(declare_mlir_dialect_python_bindings) 294310c9496SStella Laurenzo cmake_parse_arguments(ARG 29592233062Smax "GEN_ENUM_BINDINGS" 296310c9496SStella Laurenzo "ROOT_DIR;ADD_TO_PARENT;TD_FILE;DIALECT_NAME" 29792233062Smax "SOURCES;SOURCES_GLOB;DEPENDS;GEN_ENUM_BINDINGS_TD_FILE" 298310c9496SStella Laurenzo ${ARGN}) 299310c9496SStella Laurenzo # Sources. 300310c9496SStella Laurenzo set(_dialect_target "${ARG_ADD_TO_PARENT}.${ARG_DIALECT_NAME}") 301310c9496SStella Laurenzo declare_mlir_python_sources(${_dialect_target} 302310c9496SStella Laurenzo ROOT_DIR "${ARG_ROOT_DIR}" 303310c9496SStella Laurenzo ADD_TO_PARENT "${ARG_ADD_TO_PARENT}" 304310c9496SStella Laurenzo SOURCES "${ARG_SOURCES}" 305310c9496SStella Laurenzo SOURCES_GLOB "${ARG_SOURCES_GLOB}" 306310c9496SStella Laurenzo ) 307310c9496SStella Laurenzo 308310c9496SStella Laurenzo # Tablegen 309310c9496SStella Laurenzo if(ARG_TD_FILE) 310ac521d9eSStella Stamenova set(tblgen_target "${_dialect_target}.tablegen") 311310c9496SStella Laurenzo set(td_file "${ARG_ROOT_DIR}/${ARG_TD_FILE}") 312310c9496SStella Laurenzo get_filename_component(relative_td_directory "${ARG_TD_FILE}" DIRECTORY) 313132bc6e2SStella Laurenzo file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${relative_td_directory}") 314310c9496SStella Laurenzo set(dialect_filename "${relative_td_directory}/_${ARG_DIALECT_NAME}_ops_gen.py") 315310c9496SStella Laurenzo set(LLVM_TARGET_DEFINITIONS ${td_file}) 316ac521d9eSStella Stamenova mlir_tablegen("${dialect_filename}" 317ac521d9eSStella Stamenova -gen-python-op-bindings -bind-dialect=${ARG_DIALECT_NAME} 318ac521d9eSStella Stamenova DEPENDS ${ARG_DEPENDS} 319ac521d9eSStella Stamenova ) 320310c9496SStella Laurenzo add_public_tablegen_target(${tblgen_target}) 321310c9496SStella Laurenzo 32292233062Smax set(_sources ${dialect_filename}) 32392233062Smax if(ARG_GEN_ENUM_BINDINGS OR ARG_GEN_ENUM_BINDINGS_TD_FILE) 32492233062Smax if(ARG_GEN_ENUM_BINDINGS_TD_FILE) 32592233062Smax set(td_file "${ARG_ROOT_DIR}/${ARG_GEN_ENUM_BINDINGS_TD_FILE}") 32692233062Smax set(LLVM_TARGET_DEFINITIONS ${td_file}) 32792233062Smax endif() 32892233062Smax set(enum_filename "${relative_td_directory}/_${ARG_DIALECT_NAME}_enum_gen.py") 32992233062Smax mlir_tablegen(${enum_filename} -gen-python-enum-bindings) 33092233062Smax list(APPEND _sources ${enum_filename}) 33192233062Smax endif() 33292233062Smax 333310c9496SStella Laurenzo # Generated. 334ac521d9eSStella Stamenova declare_mlir_python_sources("${_dialect_target}.ops_gen" 335310c9496SStella Laurenzo ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}" 336310c9496SStella Laurenzo ADD_TO_PARENT "${_dialect_target}" 33792233062Smax SOURCES ${_sources} 338310c9496SStella Laurenzo ) 339310c9496SStella Laurenzo endif() 340310c9496SStella Laurenzoendfunction() 341310c9496SStella Laurenzo 3423f71765aSAlex Zinenko# Function: declare_mlir_dialect_extension_python_bindings 3433f71765aSAlex Zinenko# Helper to generate source groups for dialect extensions, including both 3443f71765aSAlex Zinenko# static source files and a TD_FILE to generate wrappers. 3453f71765aSAlex Zinenko# 3463f71765aSAlex Zinenko# This will generate a source group named ${ADD_TO_PARENT}.${EXTENSION_NAME}. 3473f71765aSAlex Zinenko# 3483f71765aSAlex Zinenko# Arguments: 3493f71765aSAlex Zinenko# ROOT_DIR: Same as for declare_mlir_python_sources(). 3503f71765aSAlex Zinenko# ADD_TO_PARENT: Same as for declare_mlir_python_sources(). Unique names 3513f71765aSAlex Zinenko# for the subordinate source groups are derived from this. 3523f71765aSAlex Zinenko# TD_FILE: Tablegen file to generate source for (relative to ROOT_DIR). 3533f71765aSAlex Zinenko# DIALECT_NAME: Python name of the dialect. 3543f71765aSAlex Zinenko# EXTENSION_NAME: Python name of the dialect extension. 3553f71765aSAlex Zinenko# SOURCES: Same as declare_mlir_python_sources(). 3563f71765aSAlex Zinenko# SOURCES_GLOB: Same as declare_mlir_python_sources(). 3573f71765aSAlex Zinenko# DEPENDS: Additional dependency targets. 35892233062Smax# GEN_ENUM_BINDINGS: Generate enum bindings. 35992233062Smax# GEN_ENUM_BINDINGS_TD_FILE: Optional Tablegen file to generate enums for (relative to ROOT_DIR). 36092233062Smax# This file is where the *Attrs are defined, not where the *Enums are defined. 36192233062Smax# **WARNING**: This arg will shortly be removed when the TODO for 36292233062Smax# declare_mlir_dialect_python_bindings is satisfied. Use at your risk. 3633f71765aSAlex Zinenkofunction(declare_mlir_dialect_extension_python_bindings) 3643f71765aSAlex Zinenko cmake_parse_arguments(ARG 36592233062Smax "GEN_ENUM_BINDINGS" 3663f71765aSAlex Zinenko "ROOT_DIR;ADD_TO_PARENT;TD_FILE;DIALECT_NAME;EXTENSION_NAME" 36792233062Smax "SOURCES;SOURCES_GLOB;DEPENDS;GEN_ENUM_BINDINGS_TD_FILE" 3683f71765aSAlex Zinenko ${ARGN}) 3693f71765aSAlex Zinenko # Source files. 3703f71765aSAlex Zinenko set(_extension_target "${ARG_ADD_TO_PARENT}.${ARG_EXTENSION_NAME}") 3713f71765aSAlex Zinenko declare_mlir_python_sources(${_extension_target} 3723f71765aSAlex Zinenko ROOT_DIR "${ARG_ROOT_DIR}" 3733f71765aSAlex Zinenko ADD_TO_PARENT "${ARG_ADD_TO_PARENT}" 3743f71765aSAlex Zinenko SOURCES "${ARG_SOURCES}" 3753f71765aSAlex Zinenko SOURCES_GLOB "${ARG_SOURCES_GLOB}" 3763f71765aSAlex Zinenko ) 3773f71765aSAlex Zinenko 3783f71765aSAlex Zinenko # Tablegen 3793f71765aSAlex Zinenko if(ARG_TD_FILE) 3803f71765aSAlex Zinenko set(tblgen_target "${ARG_ADD_TO_PARENT}.${ARG_EXTENSION_NAME}.tablegen") 3813f71765aSAlex Zinenko set(td_file "${ARG_ROOT_DIR}/${ARG_TD_FILE}") 3823f71765aSAlex Zinenko get_filename_component(relative_td_directory "${ARG_TD_FILE}" DIRECTORY) 3833f71765aSAlex Zinenko file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${relative_td_directory}") 3843f71765aSAlex Zinenko set(output_filename "${relative_td_directory}/_${ARG_EXTENSION_NAME}_ops_gen.py") 3853f71765aSAlex Zinenko set(LLVM_TARGET_DEFINITIONS ${td_file}) 3863f71765aSAlex Zinenko mlir_tablegen("${output_filename}" -gen-python-op-bindings 3873f71765aSAlex Zinenko -bind-dialect=${ARG_DIALECT_NAME} 3883f71765aSAlex Zinenko -dialect-extension=${ARG_EXTENSION_NAME}) 3893f71765aSAlex Zinenko add_public_tablegen_target(${tblgen_target}) 3903f71765aSAlex Zinenko if(ARG_DEPENDS) 3913f71765aSAlex Zinenko add_dependencies(${tblgen_target} ${ARG_DEPENDS}) 3923f71765aSAlex Zinenko endif() 3933f71765aSAlex Zinenko 39492233062Smax set(_sources ${output_filename}) 39592233062Smax if(ARG_GEN_ENUM_BINDINGS OR ARG_GEN_ENUM_BINDINGS_TD_FILE) 39692233062Smax if(ARG_GEN_ENUM_BINDINGS_TD_FILE) 39792233062Smax set(td_file "${ARG_ROOT_DIR}/${ARG_GEN_ENUM_BINDINGS_TD_FILE}") 39892233062Smax set(LLVM_TARGET_DEFINITIONS ${td_file}) 39992233062Smax endif() 40092233062Smax set(enum_filename "${relative_td_directory}/_${ARG_EXTENSION_NAME}_enum_gen.py") 40192233062Smax mlir_tablegen(${enum_filename} -gen-python-enum-bindings) 40292233062Smax list(APPEND _sources ${enum_filename}) 40392233062Smax endif() 40492233062Smax 4053f71765aSAlex Zinenko declare_mlir_python_sources("${_extension_target}.ops_gen" 4063f71765aSAlex Zinenko ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}" 4073f71765aSAlex Zinenko ADD_TO_PARENT "${_extension_target}" 40892233062Smax SOURCES ${_sources} 4093f71765aSAlex Zinenko ) 4103f71765aSAlex Zinenko endif() 4113f71765aSAlex Zinenkoendfunction() 4123f71765aSAlex Zinenko 413310c9496SStella Laurenzo# Function: mlir_python_setup_extension_rpath 414310c9496SStella Laurenzo# Sets RPATH properties on a target, assuming that it is being output to 415310c9496SStella Laurenzo# an _mlir_libs directory with all other libraries. For static linkage, 416310c9496SStella Laurenzo# the RPATH will just be the origin. If linking dynamically, then the LLVM 417310c9496SStella Laurenzo# library directory will be added. 418310c9496SStella Laurenzo# Arguments: 419310c9496SStella Laurenzo# RELATIVE_INSTALL_ROOT: If building dynamically, an RPATH entry will be 420310c9496SStella Laurenzo# added to the install tree lib/ directory by first traversing this 421310c9496SStella Laurenzo# path relative to the installation location. Typically a number of ".." 422310c9496SStella Laurenzo# entries, one for each level of the install path. 423310c9496SStella Laurenzofunction(mlir_python_setup_extension_rpath target) 424310c9496SStella Laurenzo cmake_parse_arguments(ARG 425310c9496SStella Laurenzo "" 426310c9496SStella Laurenzo "RELATIVE_INSTALL_ROOT" 427310c9496SStella Laurenzo "" 428310c9496SStella Laurenzo ${ARGN}) 429310c9496SStella Laurenzo 430310c9496SStella Laurenzo # RPATH handling. 431310c9496SStella Laurenzo # For the build tree, include the LLVM lib directory and the current 432310c9496SStella Laurenzo # directory for RPATH searching. For install, just the current directory 433310c9496SStella Laurenzo # (assumes that needed dependencies have been installed). 434310c9496SStella Laurenzo if(NOT APPLE AND NOT UNIX) 435310c9496SStella Laurenzo return() 436310c9496SStella Laurenzo endif() 437310c9496SStella Laurenzo 438310c9496SStella Laurenzo set(_origin_prefix "\$ORIGIN") 439310c9496SStella Laurenzo if(APPLE) 440310c9496SStella Laurenzo set(_origin_prefix "@loader_path") 441310c9496SStella Laurenzo endif() 442310c9496SStella Laurenzo set_target_properties(${target} PROPERTIES 443310c9496SStella Laurenzo BUILD_WITH_INSTALL_RPATH OFF 444310c9496SStella Laurenzo BUILD_RPATH "${_origin_prefix}" 445310c9496SStella Laurenzo INSTALL_RPATH "${_origin_prefix}" 446310c9496SStella Laurenzo ) 447310c9496SStella Laurenzo 448310c9496SStella Laurenzo # For static builds, that is all that is needed: all dependencies will be in 449310c9496SStella Laurenzo # the one directory. For shared builds, then we also need to add the global 450310c9496SStella Laurenzo # lib directory. This will be absolute for the build tree and relative for 451310c9496SStella Laurenzo # install. 452310c9496SStella Laurenzo # When we have access to CMake >= 3.20, there is a helper to calculate this. 453310c9496SStella Laurenzo if(BUILD_SHARED_LIBS AND ARG_RELATIVE_INSTALL_ROOT) 454310c9496SStella Laurenzo get_filename_component(_real_lib_dir "${LLVM_LIBRARY_OUTPUT_INTDIR}" REALPATH) 455310c9496SStella Laurenzo set_property(TARGET ${target} APPEND PROPERTY 456310c9496SStella Laurenzo BUILD_RPATH "${_real_lib_dir}") 457e941b031SJohn Ericson set_property(TARGET ${target} APPEND PROPERTY 458e941b031SJohn Ericson INSTALL_RPATH "${_origin_prefix}/${ARG_RELATIVE_INSTALL_ROOT}/lib${LLVM_LIBDIR_SUFFIX}") 459310c9496SStella Laurenzo endif() 460310c9496SStella Laurenzoendfunction() 461310c9496SStella Laurenzo 462310c9496SStella Laurenzo# Function: add_mlir_python_common_capi_library 463310c9496SStella Laurenzo# Adds a shared library which embeds dependent CAPI libraries needed to link 464310c9496SStella Laurenzo# all extensions. 465310c9496SStella Laurenzo# Arguments: 466310c9496SStella Laurenzo# INSTALL_COMPONENT: Name of the install component. Typically same as the 467310c9496SStella Laurenzo# target name passed to add_mlir_python_modules(). 468310c9496SStella Laurenzo# INSTALL_DESTINATION: Prefix into the install tree in which to install the 469310c9496SStella Laurenzo# library. 470310c9496SStella Laurenzo# OUTPUT_DIRECTORY: Full path in the build tree in which to create the 471310c9496SStella Laurenzo# library. Typically, this will be the common _mlir_libs directory where 472310c9496SStella Laurenzo# all extensions are emitted. 473310c9496SStella Laurenzo# RELATIVE_INSTALL_ROOT: See mlir_python_setup_extension_rpath(). 474ac521d9eSStella Stamenova# DECLARED_HEADERS: Source groups from which to discover headers that belong 475ac521d9eSStella Stamenova# to the library and should be installed with it. 476310c9496SStella Laurenzo# DECLARED_SOURCES: Source groups from which to discover dependent 477310c9496SStella Laurenzo# EMBED_CAPI_LINK_LIBS. 478310c9496SStella Laurenzo# EMBED_LIBS: Additional libraries to embed (must be built with OBJECTS and 479310c9496SStella Laurenzo# have an "obj.${name}" object library associated). 480310c9496SStella Laurenzofunction(add_mlir_python_common_capi_library name) 481310c9496SStella Laurenzo cmake_parse_arguments(ARG 482310c9496SStella Laurenzo "" 483310c9496SStella Laurenzo "INSTALL_COMPONENT;INSTALL_DESTINATION;OUTPUT_DIRECTORY;RELATIVE_INSTALL_ROOT" 484ac521d9eSStella Stamenova "DECLARED_HEADERS;DECLARED_SOURCES;EMBED_LIBS" 485310c9496SStella Laurenzo ${ARGN}) 486310c9496SStella Laurenzo # Collect all explicit and transitive embed libs. 487310c9496SStella Laurenzo set(_embed_libs ${ARG_EMBED_LIBS}) 488310c9496SStella Laurenzo _flatten_mlir_python_targets(_all_source_targets ${ARG_DECLARED_SOURCES}) 489310c9496SStella Laurenzo foreach(t ${_all_source_targets}) 490132bc6e2SStella Laurenzo get_target_property(_local_embed_libs ${t} mlir_python_EMBED_CAPI_LINK_LIBS) 491310c9496SStella Laurenzo if(_local_embed_libs) 492310c9496SStella Laurenzo list(APPEND _embed_libs ${_local_embed_libs}) 493310c9496SStella Laurenzo endif() 494310c9496SStella Laurenzo endforeach() 495310c9496SStella Laurenzo list(REMOVE_DUPLICATES _embed_libs) 496310c9496SStella Laurenzo 497fe6d9937SStella Laurenzo # Generate the aggregate .so that everything depends on. 498fe6d9937SStella Laurenzo add_mlir_aggregate(${name} 499310c9496SStella Laurenzo SHARED 500310c9496SStella Laurenzo DISABLE_INSTALL 501fe6d9937SStella Laurenzo EMBED_LIBS ${_embed_libs} 502310c9496SStella Laurenzo ) 503fe6d9937SStella Laurenzo 504ac521d9eSStella Stamenova # Process any headers associated with the library 505ac521d9eSStella Stamenova _flatten_mlir_python_targets(_flat_header_targets ${ARG_DECLARED_HEADERS}) 506ac521d9eSStella Stamenova set(_header_sources_target "${name}.sources") 507ac521d9eSStella Stamenova add_mlir_python_sources_target(${_header_sources_target} 508ac521d9eSStella Stamenova INSTALL_COMPONENT ${ARG_INSTALL_COMPONENT} 509ac521d9eSStella Stamenova INSTALL_DIR "${ARG_INSTALL_DESTINATION}/include" 510ac521d9eSStella Stamenova OUTPUT_DIRECTORY "${ARG_OUTPUT_DIRECTORY}/include" 511ac521d9eSStella Stamenova SOURCES_TARGETS ${_flat_header_targets} 512ac521d9eSStella Stamenova ) 513ac521d9eSStella Stamenova add_dependencies(${name} ${_header_sources_target}) 514ac521d9eSStella Stamenova 5156a7687c4SMaksim Levental if(WIN32) 516310c9496SStella Laurenzo set_property(TARGET ${name} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON) 517310c9496SStella Laurenzo endif() 518310c9496SStella Laurenzo set_target_properties(${name} PROPERTIES 519310c9496SStella Laurenzo LIBRARY_OUTPUT_DIRECTORY "${ARG_OUTPUT_DIRECTORY}" 520310c9496SStella Laurenzo BINARY_OUTPUT_DIRECTORY "${ARG_OUTPUT_DIRECTORY}" 521cb7b0381SStella Laurenzo # Needed for windows (and don't hurt others). 522cb7b0381SStella Laurenzo RUNTIME_OUTPUT_DIRECTORY "${ARG_OUTPUT_DIRECTORY}" 523cb7b0381SStella Laurenzo ARCHIVE_OUTPUT_DIRECTORY "${ARG_OUTPUT_DIRECTORY}" 524310c9496SStella Laurenzo ) 525310c9496SStella Laurenzo mlir_python_setup_extension_rpath(${name} 526310c9496SStella Laurenzo RELATIVE_INSTALL_ROOT "${ARG_RELATIVE_INSTALL_ROOT}" 527310c9496SStella Laurenzo ) 528310c9496SStella Laurenzo install(TARGETS ${name} 529310c9496SStella Laurenzo COMPONENT ${ARG_INSTALL_COMPONENT} 530310c9496SStella Laurenzo LIBRARY DESTINATION "${ARG_INSTALL_DESTINATION}" 531310c9496SStella Laurenzo RUNTIME DESTINATION "${ARG_INSTALL_DESTINATION}" 532310c9496SStella Laurenzo ) 533310c9496SStella Laurenzoendfunction() 534310c9496SStella Laurenzo 535310c9496SStella Laurenzofunction(_flatten_mlir_python_targets output_var) 536310c9496SStella Laurenzo set(_flattened) 537310c9496SStella Laurenzo foreach(t ${ARGN}) 538132bc6e2SStella Laurenzo get_target_property(_source_type ${t} mlir_python_SOURCES_TYPE) 539132bc6e2SStella Laurenzo get_target_property(_depends ${t} mlir_python_DEPENDS) 540310c9496SStella Laurenzo if(_source_type) 541310c9496SStella Laurenzo list(APPEND _flattened "${t}") 542310c9496SStella Laurenzo if(_depends) 543310c9496SStella Laurenzo _flatten_mlir_python_targets(_local_flattened ${_depends}) 544310c9496SStella Laurenzo list(APPEND _flattened ${_local_flattened}) 545310c9496SStella Laurenzo endif() 546310c9496SStella Laurenzo endif() 547310c9496SStella Laurenzo endforeach() 548310c9496SStella Laurenzo list(REMOVE_DUPLICATES _flattened) 549310c9496SStella Laurenzo set(${output_var} "${_flattened}" PARENT_SCOPE) 550310c9496SStella Laurenzoendfunction() 551310c9496SStella Laurenzo 552ac521d9eSStella Stamenova# Function: add_mlir_python_sources_target 553ac521d9eSStella Stamenova# Adds a target corresponding to an interface target that carries source 554ac521d9eSStella Stamenova# information. This target is responsible for "building" the sources by 555ac521d9eSStella Stamenova# placing them in the correct locations in the build and install trees. 556ac521d9eSStella Stamenova# Arguments: 557ac521d9eSStella Stamenova# INSTALL_COMPONENT: Name of the install component. Typically same as the 558ac521d9eSStella Stamenova# target name passed to add_mlir_python_modules(). 559ac521d9eSStella Stamenova# INSTALL_DESTINATION: Prefix into the install tree in which to install the 560ac521d9eSStella Stamenova# library. 561ac521d9eSStella Stamenova# OUTPUT_DIRECTORY: Full path in the build tree in which to create the 562ac521d9eSStella Stamenova# library. Typically, this will be the common _mlir_libs directory where 563ac521d9eSStella Stamenova# all extensions are emitted. 564ac521d9eSStella Stamenova# SOURCES_TARGETS: List of interface libraries that carry source information. 565ac521d9eSStella Stamenovafunction(add_mlir_python_sources_target name) 566ac521d9eSStella Stamenova cmake_parse_arguments(ARG 567ac521d9eSStella Stamenova "" 568ac521d9eSStella Stamenova "INSTALL_COMPONENT;INSTALL_DIR;OUTPUT_DIRECTORY" 569ac521d9eSStella Stamenova "SOURCES_TARGETS" 570ac521d9eSStella Stamenova ${ARGN}) 571ac521d9eSStella Stamenova 572ac521d9eSStella Stamenova if(ARG_UNPARSED_ARGUMENTS) 573ac521d9eSStella Stamenova message(FATAL_ERROR "Unhandled arguments to add_mlir_python_sources_target(${name}, ... : ${ARG_UNPARSED_ARGUMENTS}") 574ac521d9eSStella Stamenova endif() 575ac521d9eSStella Stamenova 576ac521d9eSStella Stamenova # On Windows create_symlink requires special permissions. Use copy_if_different instead. 577ac521d9eSStella Stamenova if(CMAKE_HOST_WIN32) 578ac521d9eSStella Stamenova set(_link_or_copy copy_if_different) 579ac521d9eSStella Stamenova else() 580ac521d9eSStella Stamenova set(_link_or_copy create_symlink) 581ac521d9eSStella Stamenova endif() 582ac521d9eSStella Stamenova 583ac521d9eSStella Stamenova foreach(_sources_target ${ARG_SOURCES_TARGETS}) 584ac521d9eSStella Stamenova get_target_property(_src_paths ${_sources_target} SOURCES) 585ac521d9eSStella Stamenova if(NOT _src_paths) 586ac521d9eSStella Stamenova get_target_property(_src_paths ${_sources_target} INTERFACE_SOURCES) 587ac521d9eSStella Stamenova if(NOT _src_paths) 588ac521d9eSStella Stamenova break() 589ac521d9eSStella Stamenova endif() 590ac521d9eSStella Stamenova endif() 591ac521d9eSStella Stamenova 592ac521d9eSStella Stamenova get_target_property(_root_dir ${_sources_target} INCLUDE_DIRECTORIES) 593ac521d9eSStella Stamenova if(NOT _root_dir) 594ac521d9eSStella Stamenova get_target_property(_root_dir ${_sources_target} INTERFACE_INCLUDE_DIRECTORIES) 595ac521d9eSStella Stamenova endif() 596ac521d9eSStella Stamenova 5971846523bSBrendan Duke # Initialize an empty list of all Python source destination paths. 5981846523bSBrendan Duke set(all_dest_paths "") 599ac521d9eSStella Stamenova foreach(_src_path ${_src_paths}) 600ac521d9eSStella Stamenova file(RELATIVE_PATH _source_relative_path "${_root_dir}" "${_src_path}") 601ac521d9eSStella Stamenova set(_dest_path "${ARG_OUTPUT_DIRECTORY}/${_source_relative_path}") 602ac521d9eSStella Stamenova 603ac521d9eSStella Stamenova get_filename_component(_dest_dir "${_dest_path}" DIRECTORY) 604ac521d9eSStella Stamenova file(MAKE_DIRECTORY "${_dest_dir}") 605ac521d9eSStella Stamenova 606ac521d9eSStella Stamenova add_custom_command( 6071846523bSBrendan Duke OUTPUT "${_dest_path}" 608ac521d9eSStella Stamenova COMMENT "Copying python source ${_src_path} -> ${_dest_path}" 609ac521d9eSStella Stamenova DEPENDS "${_src_path}" 610ac521d9eSStella Stamenova COMMAND "${CMAKE_COMMAND}" -E ${_link_or_copy} 611ac521d9eSStella Stamenova "${_src_path}" "${_dest_path}" 612ac521d9eSStella Stamenova ) 6131846523bSBrendan Duke 6141846523bSBrendan Duke # Track the symlink or copy command output. 6151846523bSBrendan Duke list(APPEND all_dest_paths "${_dest_path}") 6161846523bSBrendan Duke 617ac521d9eSStella Stamenova if(ARG_INSTALL_DIR) 6182aa6d56dSStella Laurenzo # We have to install each file individually because we need to preserve 6192aa6d56dSStella Laurenzo # the relative directory structure in the install destination. 6202aa6d56dSStella Laurenzo # As an example, ${_source_relative_path} may be dialects/math.py 6212aa6d56dSStella Laurenzo # which would be transformed to ${ARG_INSTALL_DIR}/dialects 6222aa6d56dSStella Laurenzo # here. This could be moved outside of the loop and cleaned up 6232aa6d56dSStella Laurenzo # if we used FILE_SETS (introduced in CMake 3.23). 6242aa6d56dSStella Laurenzo get_filename_component(_install_destination "${ARG_INSTALL_DIR}/${_source_relative_path}" DIRECTORY) 625ac521d9eSStella Stamenova install( 6262aa6d56dSStella Laurenzo FILES ${_src_path} 6272aa6d56dSStella Laurenzo DESTINATION "${_install_destination}" 628ac521d9eSStella Stamenova COMPONENT ${ARG_INSTALL_COMPONENT} 629ac521d9eSStella Stamenova ) 630ac521d9eSStella Stamenova endif() 631ac521d9eSStella Stamenova endforeach() 6322aa6d56dSStella Laurenzo endforeach() 6331846523bSBrendan Duke 6341846523bSBrendan Duke # Create a new custom target that depends on all symlinked or copied sources. 6351846523bSBrendan Duke add_custom_target("${name}" DEPENDS ${all_dest_paths}) 636ac521d9eSStella Stamenovaendfunction() 637ac521d9eSStella Stamenova 638310c9496SStella Laurenzo################################################################################ 6399f3f6d7bSStella Laurenzo# Build python extension 6409f3f6d7bSStella Laurenzo################################################################################ 6419f3f6d7bSStella Laurenzofunction(add_mlir_python_extension libname extname) 6429f3f6d7bSStella Laurenzo cmake_parse_arguments(ARG 6439f3f6d7bSStella Laurenzo "" 644392622d0SMaksim Levental "INSTALL_COMPONENT;INSTALL_DIR;OUTPUT_DIRECTORY;PYTHON_BINDINGS_LIBRARY" 6459f3f6d7bSStella Laurenzo "SOURCES;LINK_LIBS" 6469f3f6d7bSStella Laurenzo ${ARGN}) 6479f3f6d7bSStella Laurenzo if(ARG_UNPARSED_ARGUMENTS) 6489f3f6d7bSStella Laurenzo message(FATAL_ERROR "Unhandled arguments to add_mlir_python_extension(${libname}, ... : ${ARG_UNPARSED_ARGUMENTS}") 6499f3f6d7bSStella Laurenzo endif() 6509f3f6d7bSStella Laurenzo 6516a7687c4SMaksim Levental # The extension itself must be compiled with RTTI and exceptions enabled. 6526a7687c4SMaksim Levental # Also, some warning classes triggered by pybind11 are disabled. 6536a7687c4SMaksim Levental set(eh_rtti_enable) 6546a7687c4SMaksim Levental if (MSVC) 6556a7687c4SMaksim Levental set(eh_rtti_enable /EHsc /GR) 6566a7687c4SMaksim Levental elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL) 6576a7687c4SMaksim Levental set(eh_rtti_enable -frtti -fexceptions) 6586a7687c4SMaksim Levental endif () 6596a7687c4SMaksim Levental 6609f3f6d7bSStella Laurenzo # The actual extension library produces a shared-object or DLL and has 6619f3f6d7bSStella Laurenzo # sources that must be compiled in accordance with pybind11 needs (RTTI and 6629f3f6d7bSStella Laurenzo # exceptions). 663392622d0SMaksim Levental if(NOT DEFINED ARG_PYTHON_BINDINGS_LIBRARY OR ARG_PYTHON_BINDINGS_LIBRARY STREQUAL "pybind11") 66455e76c70SMike Urbach pybind11_add_module(${libname} 6659f3f6d7bSStella Laurenzo ${ARG_SOURCES} 6669f3f6d7bSStella Laurenzo ) 667392622d0SMaksim Levental elseif(ARG_PYTHON_BINDINGS_LIBRARY STREQUAL "nanobind") 668392622d0SMaksim Levental nanobind_add_module(${libname} 6699e863cd4Serwei-xilinx NB_DOMAIN ${MLIR_BINDINGS_PYTHON_NB_DOMAIN} 670f136c800Svfdev FREE_THREADED 671392622d0SMaksim Levental ${ARG_SOURCES} 672392622d0SMaksim Levental ) 6735cd42747SPeter Hawkins 674*1a8f49fdSScott Todd if (NOT MLIR_DISABLE_CONFIGURE_PYTHON_DEV_PACKAGES 675*1a8f49fdSScott Todd AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL)) 676*1a8f49fdSScott Todd # Avoid some warnings from upstream nanobind. 677*1a8f49fdSScott Todd # If a superproject set MLIR_DISABLE_CONFIGURE_PYTHON_DEV_PACKAGES, let 678*1a8f49fdSScott Todd # the super project handle compile options as it wishes. 679f136c800Svfdev set(nanobind_target "nanobind-static") 680f136c800Svfdev if (NOT TARGET ${nanobind_target}) 681f136c800Svfdev # Get correct nanobind target name: nanobind-static-ft or something else 682f136c800Svfdev # It is set by nanobind_add_module function according to the passed options 683f136c800Svfdev get_property(all_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY BUILDSYSTEM_TARGETS) 684f136c800Svfdev 685f136c800Svfdev # Iterate over the list of targets 686f136c800Svfdev foreach(target ${all_targets}) 687f136c800Svfdev # Check if the target name matches the given string 688f136c800Svfdev if("${target}" MATCHES "nanobind-") 689f136c800Svfdev set(nanobind_target "${target}") 690f136c800Svfdev endif() 691f136c800Svfdev endforeach() 692f136c800Svfdev 693f136c800Svfdev if (NOT TARGET ${nanobind_target}) 694f136c800Svfdev message(FATAL_ERROR "Could not find nanobind target to set compile options to") 695f136c800Svfdev endif() 696f136c800Svfdev endif() 697f136c800Svfdev target_compile_options(${nanobind_target} 6985cd42747SPeter Hawkins PRIVATE 6995cd42747SPeter Hawkins -Wno-cast-qual 7005cd42747SPeter Hawkins -Wno-zero-length-array 7015cd42747SPeter Hawkins -Wno-nested-anon-types 7025cd42747SPeter Hawkins -Wno-c++98-compat-extra-semi 7035cd42747SPeter Hawkins -Wno-covered-switch-default 7046a7687c4SMaksim Levental ${eh_rtti_enable} 7055cd42747SPeter Hawkins ) 7065cd42747SPeter Hawkins endif() 70778f04477SMaksim Levental 70878f04477SMaksim Levental if(APPLE) 70978f04477SMaksim Levental # NanobindAdaptors.h uses PyClassMethod_New to build `pure_subclass`es but nanobind 71078f04477SMaksim Levental # doesn't declare this API as undefined in its linker flags. So we need to declare it as such 71178f04477SMaksim Levental # for downstream users that do not do something like `-undefined dynamic_lookup`. 71278f04477SMaksim Levental set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-U -Wl,_PyClassMethod_New") 71378f04477SMaksim Levental endif() 714392622d0SMaksim Levental endif() 7159f3f6d7bSStella Laurenzo 7163adb0ac1SMarkus Böck target_compile_options(${libname} PRIVATE ${eh_rtti_enable}) 7179f3f6d7bSStella Laurenzo 7189f3f6d7bSStella Laurenzo # Configure the output to match python expectations. 7199f3f6d7bSStella Laurenzo set_target_properties( 7209f3f6d7bSStella Laurenzo ${libname} PROPERTIES 721310c9496SStella Laurenzo LIBRARY_OUTPUT_DIRECTORY ${ARG_OUTPUT_DIRECTORY} 7229f3f6d7bSStella Laurenzo OUTPUT_NAME "${extname}" 7231de7a17fSStella Laurenzo NO_SONAME ON 7249f3f6d7bSStella Laurenzo ) 7259f3f6d7bSStella Laurenzo 7269f3f6d7bSStella Laurenzo if(WIN32) 7279f3f6d7bSStella Laurenzo # Need to also set the RUNTIME_OUTPUT_DIRECTORY on Windows in order to 7289f3f6d7bSStella Laurenzo # control where the .dll gets written. 7299f3f6d7bSStella Laurenzo set_target_properties( 7309f3f6d7bSStella Laurenzo ${libname} PROPERTIES 731310c9496SStella Laurenzo RUNTIME_OUTPUT_DIRECTORY ${ARG_OUTPUT_DIRECTORY} 7325821047aSJohn Demme ARCHIVE_OUTPUT_DIRECTORY ${ARG_OUTPUT_DIRECTORY} 7339f3f6d7bSStella Laurenzo ) 7349f3f6d7bSStella Laurenzo endif() 7359f3f6d7bSStella Laurenzo 7369f3f6d7bSStella Laurenzo target_link_libraries(${libname} 7379f3f6d7bSStella Laurenzo PRIVATE 7389f3f6d7bSStella Laurenzo ${ARG_LINK_LIBS} 7399f3f6d7bSStella Laurenzo ) 7409f3f6d7bSStella Laurenzo 7419f3f6d7bSStella Laurenzo target_link_options(${libname} 7429f3f6d7bSStella Laurenzo PRIVATE 7439f3f6d7bSStella Laurenzo # On Linux, disable re-export of any static linked libraries that 7449f3f6d7bSStella Laurenzo # came through. 7459f3f6d7bSStella Laurenzo $<$<PLATFORM_ID:Linux>:LINKER:--exclude-libs,ALL> 7469f3f6d7bSStella Laurenzo ) 7479f3f6d7bSStella Laurenzo 748784a5bccSStella Stamenova if(WIN32) 749784a5bccSStella Stamenova # On Windows, pyconfig.h (and by extension python.h) hardcode the version of the 750784a5bccSStella Stamenova # python library which will be used for linkage depending on the flavor of the build. 751784a5bccSStella Stamenova # pybind11 has a workaround which depends on the definition of Py_DEBUG (if Py_DEBUG 752784a5bccSStella Stamenova # is not passed in as a compile definition, pybind11 undefs _DEBUG when including 753784a5bccSStella Stamenova # python.h, so that the release python library would be used). 754784a5bccSStella Stamenova # Since mlir uses pybind11, we can leverage their workaround by never directly 755784a5bccSStella Stamenova # pyconfig.h or python.h and instead relying on the pybind11 headers to include the 756784a5bccSStella Stamenova # necessary python headers. This results in mlir always linking against the 757784a5bccSStella Stamenova # release python library via the (undocumented) cmake property Python3_LIBRARY_RELEASE. 758784a5bccSStella Stamenova target_link_libraries(${libname} PRIVATE ${Python3_LIBRARY_RELEASE}) 759784a5bccSStella Stamenova endif() 760784a5bccSStella Stamenova 7619f3f6d7bSStella Laurenzo ################################################################################ 7629f3f6d7bSStella Laurenzo # Install 7639f3f6d7bSStella Laurenzo ################################################################################ 7649f3f6d7bSStella Laurenzo if(ARG_INSTALL_DIR) 7659f3f6d7bSStella Laurenzo install(TARGETS ${libname} 766310c9496SStella Laurenzo COMPONENT ${ARG_INSTALL_COMPONENT} 7679f3f6d7bSStella Laurenzo LIBRARY DESTINATION ${ARG_INSTALL_DIR} 7689f3f6d7bSStella Laurenzo ARCHIVE DESTINATION ${ARG_INSTALL_DIR} 7699f3f6d7bSStella Laurenzo # NOTE: Even on DLL-platforms, extensions go in the lib directory tree. 7709f3f6d7bSStella Laurenzo RUNTIME DESTINATION ${ARG_INSTALL_DIR} 7719f3f6d7bSStella Laurenzo ) 7729f3f6d7bSStella Laurenzo endif() 7739f3f6d7bSStella Laurenzoendfunction() 774