@@ -104,29 +104,37 @@ if(DEFINED SKBUILD)
104104 endif ()
105105
106106 # Single module — all sources compiled in, no runtime DLL dependency.
107- pybind11_add_module (docx_comment_parser MODULE
107+ #
108+ # The CMake target is called docx_core, but OUTPUT_NAME makes the built file
109+ # "_core.pyd" / "_core.so" so Python finds PyInit__core, matching
110+ # PYBIND11_MODULE(_core, m) in python_bindings.cpp. It is installed *inside*
111+ # the docx_comment_parser package directory, next to the pure-Python sources
112+ # collected via [tool.scikit-build] wheel.packages.
113+ pybind11_add_module (docx_core MODULE
108114 python/python_bindings.cpp
109115 src/docx_parser.cpp
110116 src/batch_parser.cpp
111117 src/zip_reader.cpp
112118 src/xml_parser.cpp
113119 )
114120
121+ set_target_properties (docx_core PROPERTIES OUTPUT_NAME "_core" )
122+
115123 # DOCX_BUILDING_DLL is correct here: the extension IS building the symbols
116124 # (not importing them from a separate DLL).
117- target_compile_definitions (docx_comment_parser PRIVATE DOCX_BUILDING_DLL )
125+ target_compile_definitions (docx_core PRIVATE DOCX_BUILDING_DLL )
118126
119- target_include_directories (docx_comment_parser PRIVATE
127+ target_include_directories (docx_core PRIVATE
120128 ${CMAKE_CURRENT_SOURCE_DIR } /include
121129 # Vendored zlib.h for MSVC (activated inside zip_reader.cpp)
122130 $<$<CXX_COMPILER_ID :MSVC >:${CMAKE_CURRENT_SOURCE_DIR } /vendor >
123131 )
124132
125- docx_apply_compile_options (docx_comment_parser )
126- docx_link_platform_libs (docx_comment_parser )
133+ docx_apply_compile_options (docx_core )
134+ docx_link_platform_libs (docx_core )
127135
128- install (TARGETS docx_comment_parser
129- DESTINATION "${SKBUILD_PLATLIB_DIR} "
136+ install (TARGETS docx_core
137+ DESTINATION "${SKBUILD_PLATLIB_DIR} /docx_comment_parser "
130138 )
131139
132140 # Nothing else to build in wheel mode — skip the rest of this file.
@@ -202,19 +210,37 @@ if(BUILD_PYTHON_BINDINGS)
202210
203211 if (pybind11_FOUND)
204212 # Distinct CMake target name avoids collision with the SHARED library
205- # target above. OUTPUT_NAME makes the file "docx_comment_parser.pyd"
206- # so Python's import machinery finds PyInit_docx_comment_parser.
207- # (The old name "_docx_comment_parser" caused an ImportError because
208- # Python looked for PyInit__docx_comment_parser — note the double
209- # underscore — which never existed.)
213+ # target above. OUTPUT_NAME makes the file "_core.pyd" / "_core.so" so
214+ # Python's import machinery finds PyInit__core, matching
215+ # PYBIND11_MODULE(_core, m) in python_bindings.cpp.
216+ #
217+ # The extension is a *submodule* of the docx_comment_parser package, so
218+ # it is written straight into src/docx_comment_parser/ — that makes an
219+ # in-place CMake build immediately importable via PYTHONPATH=src, and
220+ # the install rule below drops it beside the installed package.
210221 pybind11_add_module (docx_py_ext MODULE
211222 python/python_bindings.cpp
212223 )
213224
225+ set (_docx_pkg_dir "${CMAKE_CURRENT_SOURCE_DIR } /src/docx_comment_parser" )
226+
214227 set_target_properties (docx_py_ext PROPERTIES
215- OUTPUT_NAME "docx_comment_parser"
228+ OUTPUT_NAME "_core"
229+ LIBRARY_OUTPUT_DIRECTORY "${_docx_pkg_dir} "
230+ RUNTIME_OUTPUT_DIRECTORY "${_docx_pkg_dir} "
216231 )
217232
233+ # Multi-config generators (Visual Studio, Xcode) append a per-config
234+ # subdirectory to *_OUTPUT_DIRECTORY unless the per-config variant is
235+ # set explicitly. Without this the .pyd lands in
236+ # src/docx_comment_parser/Release/ and is not importable in place.
237+ foreach (_cfg IN ITEMS DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
238+ set_target_properties (docx_py_ext PROPERTIES
239+ LIBRARY_OUTPUT_DIRECTORY_${_cfg} "${_docx_pkg_dir} "
240+ RUNTIME_OUTPUT_DIRECTORY_${_cfg} "${_docx_pkg_dir} "
241+ )
242+ endforeach ()
243+
218244 # Do NOT define DOCX_BUILDING_DLL: this extension links against the
219245 # shared library above, so DOCX_API must expand to __declspec(dllimport).
220246 target_include_directories (docx_py_ext PRIVATE
@@ -231,9 +257,18 @@ if(BUILD_PYTHON_BINDINGS)
231257 target_link_libraries (docx_py_ext PRIVATE -lpthread )
232258 endif ()
233259
260+ # Install the extension *and* the pure-Python package that wraps it, so
261+ # a plain `cmake --install` yields a working `import docx_comment_parser`.
234262 install (TARGETS docx_py_ext
235- LIBRARY DESTINATION "${Python3_SITEARCH} "
236- RUNTIME DESTINATION "${Python3_SITEARCH} "
263+ LIBRARY DESTINATION "${Python3_SITEARCH} /docx_comment_parser"
264+ RUNTIME DESTINATION "${Python3_SITEARCH} /docx_comment_parser"
265+ )
266+
267+ install (DIRECTORY "${_docx_pkg_dir} /"
268+ DESTINATION "${Python3_SITEARCH} /docx_comment_parser"
269+ FILES_MATCHING
270+ PATTERN "*.py"
271+ PATTERN "py.typed"
237272 )
238273 else ()
239274 message (WARNING
0 commit comments