@@ -99,6 +99,57 @@ function(declare_mlir_python_sources name)
9999 endif ()
100100endfunction ()
101101
102+ # Function: generate_type_stubs
103+ # Turns on automatic type stub generation (via nanobind's stubgen) for extension modules.
104+ # Arguments:
105+ # MODULE_NAME: The name of the extension module as specified in declare_mlir_python_extension.
106+ # DEPENDS_TARGET: The dso target corresponding to the extension module
107+ # (e.g., something like StandalonePythonModules.extension._standaloneDialectsNanobind.dso)
108+ # MLIR_DEPENDS_TARGET: The dso target corresponding to the main/core extension module
109+ # (e.g., something like StandalonePythonModules.extension._mlir.dso)
110+ # OUTPUT_DIR: The root output directory to emit the type stubs into.
111+ # Outputs:
112+ # NB_STUBGEN_CUSTOM_TARGET: The target corresponding to generation which other targets can depend on.
113+ function (generate_type_stubs MODULE_NAME DEPENDS_TARGET MLIR_DEPENDS_TARGET OUTPUT_DIR)
114+ if (EXISTS ${nanobind_DIR} /../src/stubgen.py)
115+ set (NB_STUBGEN "${nanobind_DIR} /../src/stubgen.py" )
116+ elseif (EXISTS ${nanobind_DIR} /../stubgen.py)
117+ set (NB_STUBGEN "${nanobind_DIR} /../stubgen.py" )
118+ else ()
119+ message (FATAL_ERROR "generate_type_stubs(): could not locate 'stubgen.py'!" )
120+ endif ()
121+ file (REAL_PATH "${NB_STUBGEN} " NB_STUBGEN)
122+
123+ set (_module "${MLIR_PYTHON_PACKAGE_PREFIX} ._mlir_libs.${MODULE_NAME} " )
124+ file (REAL_PATH "${MLIR_BINARY_DIR} /${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX} /.." _import_path)
125+
126+ set (NB_STUBGEN_CMD
127+ "${Python_EXECUTABLE} "
128+ "${NB_STUBGEN} "
129+ --module
130+ "${_module} "
131+ -i
132+ "${_import_path} "
133+ --recursive
134+ --include -private
135+ --output -dir
136+ "${OUTPUT_DIR} " )
137+
138+ set (NB_STUBGEN_OUTPUT "${OUTPUT_DIR} /${MODULE_NAME} .pyi" )
139+ add_custom_command (
140+ OUTPUT ${NB_STUBGEN_OUTPUT}
141+ COMMAND ${NB_STUBGEN_CMD}
142+ WORKING_DIRECTORY "${CMAKE_CURRENT_FUNCTION_LIST_DIR} "
143+ DEPENDS
144+ "${MLIR_DEPENDS_TARGET} .extension._mlir.dso"
145+ "${MLIR_DEPENDS_TARGET} .sources.MLIRPythonSources.Core.Python"
146+ "${DEPENDS_TARGET} "
147+ )
148+ set (_name "MLIRPythonModuleStubs_${_module} " )
149+ add_custom_target ("${_name} " ALL DEPENDS ${NB_STUBGEN_OUTPUT} )
150+ set (NB_STUBGEN_CUSTOM_TARGET "${_name} " PARENT_SCOPE)
151+ endfunction ()
152+
102153# Function: declare_mlir_python_extension
103154# Declares a buildable python extension from C++ source files. The built
104155# module is considered a python source file and included as everything else.
@@ -115,9 +166,10 @@ endfunction()
115166# on. These will be collected for all extensions and put into an
116167# aggregate dylib that is linked against.
117168# PYTHON_BINDINGS_LIBRARY: Either pybind11 or nanobind.
169+ # GENERATE_TYPE_STUBS: Enable type stub generation.
118170function (declare_mlir_python_extension name )
119171 cmake_parse_arguments (ARG
120- ""
172+ "GENERATE_TYPE_STUBS "
121173 "ROOT_DIR;MODULE_NAME;ADD_TO_PARENT;PYTHON_BINDINGS_LIBRARY"
122174 "SOURCES;PRIVATE_LINK_LIBS;EMBED_CAPI_LINK_LIBS"
123175 ${ARGN} )
@@ -135,12 +187,13 @@ function(declare_mlir_python_extension name)
135187 set_target_properties (${name} PROPERTIES
136188 # Yes: Leading-lowercase property names are load bearing and the recommended
137189 # way to do this: https://gitlab.kitware.com/cmake/cmake/-/issues/19261
138- EXPORT_PROPERTIES "mlir_python_SOURCES_TYPE;mlir_python_EXTENSION_MODULE_NAME;mlir_python_EMBED_CAPI_LINK_LIBS;mlir_python_DEPENDS;mlir_python_BINDINGS_LIBRARY"
190+ EXPORT_PROPERTIES "mlir_python_SOURCES_TYPE;mlir_python_EXTENSION_MODULE_NAME;mlir_python_EMBED_CAPI_LINK_LIBS;mlir_python_DEPENDS;mlir_python_BINDINGS_LIBRARY;mlir_python_GENERATE_TYPE_STUBS "
139191 mlir_python_SOURCES_TYPE extension
140192 mlir_python_EXTENSION_MODULE_NAME "${ARG_MODULE_NAME} "
141193 mlir_python_EMBED_CAPI_LINK_LIBS "${ARG_EMBED_CAPI_LINK_LIBS} "
142194 mlir_python_DEPENDS ""
143195 mlir_python_BINDINGS_LIBRARY "${ARG_PYTHON_BINDINGS_LIBRARY} "
196+ mlir_python_GENERATE_TYPE_STUBS "${ARG_GENERATE_TYPE_STUBS} "
144197 )
145198
146199 # Set the interface source and link_libs properties of the target
@@ -243,6 +296,22 @@ function(add_mlir_python_modules name)
243296 )
244297 add_dependencies (${modules_target} ${_extension_target} )
245298 mlir_python_setup_extension_rpath(${_extension_target} )
299+ get_target_property (_generate_type_stubs ${sources_target} mlir_python_GENERATE_TYPE_STUBS)
300+ if (_generate_type_stubs)
301+ generate_type_stubs(
302+ ${_module_name}
303+ ${_extension_target}
304+ ${name}
305+ "${CMAKE_CURRENT_SOURCE_DIR} /mlir/_mlir_libs/_mlir"
306+ )
307+ declare_mlir_python_sources(
308+ "${MLIR_PYTHON_PACKAGE_PREFIX} .${_module_name} _type_stub_gen"
309+ ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR} /mlir"
310+ ADD_TO_PARENT "${sources_target} "
311+ SOURCES_GLOB "_mlir_libs/${_module_name} /**/*.pyi"
312+ )
313+ add_dependencies ("${modules_target} " "${NB_STUBGEN_CUSTOM_TARGET} " )
314+ endif ()
246315 else ()
247316 message (SEND_ERROR "Unrecognized source type '${_source_type} ' for python source target ${sources_target} " )
248317 return ()
@@ -678,26 +747,28 @@ function(add_mlir_python_extension libname extname)
678747 # the super project handle compile options as it wishes.
679748 get_property (NB_LIBRARY_TARGET_NAME TARGET ${libname} PROPERTY LINK_LIBRARIES )
680749 target_compile_options (${NB_LIBRARY_TARGET_NAME}
681- PRIVATE
682- -Wall -Wextra -Wpedantic
683- -Wno-c++98-compat-extra-semi
684- -Wno-cast-qual
685- -Wno-covered-switch-default
686- -Wno-nested-anon-types
687- -Wno-unused-parameter
688- -Wno-zero-length -array
689- ${eh_rtti_enable} )
750+ PRIVATE
751+ -Wall -Wextra -Wpedantic
752+ -Wno-c++98-compat-extra-semi
753+ -Wno-cast-qual
754+ -Wno-covered-switch-default
755+ -Wno-deprecated-literal-operator
756+ -Wno-nested-anon-types
757+ -Wno-unused-parameter
758+ -Wno-zero-length -array
759+ ${eh_rtti_enable} )
690760
691761 target_compile_options (${libname}
692- PRIVATE
693- -Wall -Wextra -Wpedantic
694- -Wno-c++98-compat-extra-semi
695- -Wno-cast-qual
696- -Wno-covered-switch-default
697- -Wno-nested-anon-types
698- -Wno-unused-parameter
699- -Wno-zero-length -array
700- ${eh_rtti_enable} )
762+ PRIVATE
763+ -Wall -Wextra -Wpedantic
764+ -Wno-c++98-compat-extra-semi
765+ -Wno-cast-qual
766+ -Wno-covered-switch-default
767+ -Wno-deprecated-literal-operator
768+ -Wno-nested-anon-types
769+ -Wno-unused-parameter
770+ -Wno-zero-length -array
771+ ${eh_rtti_enable} )
701772 endif ()
702773
703774 if (APPLE )
0 commit comments