Skip to content

Commit 9d39b88

Browse files
committed
Fix extension module packaging for macOS/Windows multi-config generators
- Add target-level output directory properties to PRTree in CMakeLists.txt to ensure the extension module lands in the correct location for all CMake generators (Xcode, Visual Studio, Ninja, Unix Makefiles) - Add CMAKE_RUNTIME_OUTPUT_DIRECTORY and CMAKE_ARCHIVE_OUTPUT_DIRECTORY to setup.py cmake_args to cover all output types - Ensure extdir exists before CMake build to prevent directory errors - Add robust error handling in setup.py to fail loudly if extension module is not found after build (prevents shipping broken wheels) - Fix Windows Unicode error in _ci_debug_import.py by replacing Unicode checkmark/X characters with ASCII [OK]/[FAIL] This fixes the ModuleNotFoundError on macOS and Windows CI where the compiled PRTree extension was not being included in the wheel package.
1 parent ddf6496 commit 9d39b88

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,13 @@ set_target_properties(PRTree PROPERTIES
4545
C_VISIBILITY_PRESET hidden
4646
CXX_VISIBILITY_PRESET hidden
4747
INTERPROCEDURAL_OPTIMIZATION TRUE
48+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
49+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
50+
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}"
51+
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG}"
52+
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE}"
53+
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}"
54+
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}"
55+
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG}"
56+
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE}"
4857
)

setup.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ def build_extension(self, ext):
5656

5757
cmake_args = [
5858
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=" + extdir,
59+
"-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=" + extdir,
60+
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=" + extdir,
5961
"-DPYTHON_EXECUTABLE=" + sys.executable,
6062
"-DBUILD_SHARED_LIBS=OFF",
6163
]
@@ -106,6 +108,8 @@ def build_extension(self, ext):
106108
)
107109
if not os.path.exists(self.build_temp):
108110
os.makedirs(self.build_temp)
111+
if not os.path.exists(extdir):
112+
os.makedirs(extdir)
109113

110114
subprocess.check_call(
111115
["cmake", ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env
@@ -134,8 +138,17 @@ def build_extension(self, ext):
134138

135139
print(f"Copying extension from {src_file} to {extdir}")
136140
shutil.copy2(src_file, extdir)
141+
142+
if not os.path.exists(expected_file):
143+
raise RuntimeError(
144+
f"Failed to copy extension module to {expected_file}. "
145+
f"Source was {src_file}"
146+
)
137147
else:
138-
print(f"Warning: Could not find {pattern} in build tree")
148+
raise RuntimeError(
149+
f"Could not find compiled extension module {pattern} in build tree. "
150+
f"Build may have failed. Check build logs above."
151+
)
139152

140153

141154
setup(

tests/_ci_debug_import.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
try:
1717
import python_prtree
18-
print(f" python_prtree imported successfully")
18+
print(f"[OK] python_prtree imported successfully")
1919
print(f" Location: {python_prtree.__file__}")
2020

2121
pkg_dir = pathlib.Path(python_prtree.__file__).parent
@@ -28,7 +28,7 @@
2828
print()
2929

3030
from python_prtree import PRTree3D
31-
print(f" PRTree3D imported successfully")
31+
print(f"[OK] PRTree3D imported successfully")
3232
print(f" PRTree3D: {PRTree3D}")
3333
print()
3434

@@ -38,7 +38,7 @@
3838
sys.exit(0)
3939

4040
except Exception as e:
41-
print(f" IMPORT FAILED: {repr(e)}")
41+
print(f"[FAIL] IMPORT FAILED: {repr(e)}")
4242
print()
4343
traceback.print_exc()
4444
print()

0 commit comments

Comments
 (0)