From 8be06bb3e4bc749f41103eb40c5cddb00797fc2f Mon Sep 17 00:00:00 2001 From: Olaf Razzoli Date: Thu, 28 May 2026 19:18:48 +0100 Subject: [PATCH] Align Python in the Windows dev tree with the install layout Mirrors the install-time Python layout in the build tree on Windows so embedded Python initializes and the xstudio Python package is importable when running build/run_xstudio.bat from a fresh dev build (no cmake --install required). - src/embedded_python/src/CMakeLists.txt: stage vcpkg's tools/python3 into build/bin/python3/ at build time via cmake -E copy_directory_if_different (incremental; ~150 MB on first build, near-zero on subsequent builds). Add configure-time guard for missing vcpkg python tree. - python/CMakeLists.txt: on Windows, replace pip install . with cmake -E copy_directory_if_different of python/src/xstudio/ into build/bin/python3/Lib/site-packages/xstudio/. Update python_module target's DEPENDS for the new output path. Add an explicit Windows install(DIRECTORY ...) rule for the xstudio package (previously absent. Linux/macOS branches untouched. - src/python_module/src/CMakeLists.txt: on Windows, route the __pybind_xstudio.pyd LIBRARY_OUTPUT_DIRECTORY to build/bin/python3/Lib/site-packages/xstudio/core/ built directly at the final location, .pdb co-located for debugger. macOS and Linux unchanged. Install destination contents unchanged. Signed-off-by: Olaf Razzoli --- python/CMakeLists.txt | 40 ++++++++++++++++++++------ src/embedded_python/src/CMakeLists.txt | 27 +++++++++++++++-- src/python_module/src/CMakeLists.txt | 7 +++++ 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 1322e7622..f5dc84b7c 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -38,22 +38,35 @@ else() configure_file(${VERSION_PY_IN} ${VERSION_PY} @ONLY) if (WIN32) - # This will install the xstudio python module to the VCPKG python distribution - # Later at install time, the whole python dist is added to the xstudio package - # and hence we get the xstudio python module where we need it. - add_custom_command(OUTPUT ${OUTPUT}/lib/${PYTHONVP}/site-packages/xstudio/api - COMMAND ${Python_EXECUTABLE} - ARGS -m pip install . - DEPENDS __pybind_xstudio ${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in) + # Stage the xstudio Python package directly into the dev-tree mirror of + # the install layout. Runtime PYTHONHOME is build/bin/python3 in dev + # (set up by src/embedded_python/src/CMakeLists.txt) and + # /bin/python3 at install, Python's standard site-discovery + # resolves `import xstudio` from there. + # + # Replaces a previous `python -m pip install .` invocation that + # implicitly mutated vcpkg's tools/python3/Lib/site-packages, then + # relied on `install(DIRECTORY tools/python3 ...)` to propagate xstudio + # into the installer. Now the build-tree stage is explicit and the + # install rule below is explicit. + # cmake -E copy_directory_if_different is incremental — only changed + # .py files are copied on rebuilds. + set(WIN_PYTHON_SITE "${CMAKE_BINARY_DIR}/bin/python3/Lib/site-packages/xstudio") + add_custom_command(OUTPUT ${WIN_PYTHON_SITE}/__init__.py + COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/src/xstudio + ${WIN_PYTHON_SITE} + DEPENDS ${DEPS} ${VERSION_PY} + COMMENT "Staging xstudio Python package to ${WIN_PYTHON_SITE}") + add_custom_target(python_module ALL DEPENDS __pybind_xstudio ${WIN_PYTHON_SITE}/__init__.py) else() add_custom_command(OUTPUT ${OUTPUT}/lib/${PYTHONVP}/site-packages/xstudio/api COMMAND ${Python_EXECUTABLE} ARGS setup.py install --old-and-unmanageable --prefix=${OUTPUT} DEPENDS __pybind_xstudio ${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in) + add_custom_target(python_module ALL DEPENDS __pybind_xstudio ${OUTPUT}/lib/${PYTHONVP}/site-packages/xstudio/api) endif() - add_custom_target(python_module ALL DEPENDS __pybind_xstudio ${OUTPUT}/lib/${PYTHONVP}/site-packages/xstudio/api) - endif() @@ -63,6 +76,15 @@ if(NOT APPLE) if (NOT WIN32) install(DIRECTORY ${OUTPUT}/lib/${PYTHONVP}/site-packages/xstudio DESTINATION lib/python/) + else() + # Install the staged xstudio Python package to its final install + # location. WIN_PYTHON_SITE is set above to + # ${CMAKE_BINARY_DIR}/bin/python3/Lib/site-packages/xstudio. + # Previously no explicit Windows install rule existed for the + # xstudio .py files — they reached the installer only as a + # side-effect of `pip install .` mutating vcpkg's tree. + install(DIRECTORY ${WIN_PYTHON_SITE} + DESTINATION bin/python3/Lib/site-packages) endif() if(WIN32) diff --git a/src/embedded_python/src/CMakeLists.txt b/src/embedded_python/src/CMakeLists.txt index d2ef95304..04bdac036 100644 --- a/src/embedded_python/src/CMakeLists.txt +++ b/src/embedded_python/src/CMakeLists.txt @@ -40,6 +40,29 @@ set_python_to_proper_build_type() set_target_properties(${PROJECT_NAME} PROPERTIES LINK_DEPENDS_NO_SHARED true) if(WIN32) -# Install the entire python install from vcpkg to the bin/python3 folder -install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../../../vcpkg_installed/x64-windows/tools/python3 DESTINATION bin) + set(_xstudio_vcpkg_python "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/tools/python3") + + if(NOT EXISTS "${_xstudio_vcpkg_python}") + message(FATAL_ERROR + "vcpkg Python tree not found at ${_xstudio_vcpkg_python}. " + "Re-run vcpkg install or check VCPKG_TARGET_TRIPLET.") + endif() + + # Build-time mirror of vcpkg's tools/python3 into the build tree. Embedded + # Python computes PYTHONHOME as /../../bin/python3 (see + # embedded_python.cpp Windows branch), so a populated build/bin/python3 is + # required to launch xstudio directly from the build tree with no + # cmake --install. copy_directory_if_different is incremental: first build + # ~150 MB, subsequent builds copy only changed files. The staged contents + # (CPython interpreter, stdlib, vcpkg-bundled site-packages) are not + # debugging targets for xstudio devs, so a copy has no debugger-ergonomic + # downside. + add_custom_target(stage_python_runtime ALL + COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different + "${_xstudio_vcpkg_python}" + "${CMAKE_BINARY_DIR}/bin/python3" + COMMENT "Staging vcpkg Python runtime to ${CMAKE_BINARY_DIR}/bin/python3") + + # Install the entire python install from vcpkg to the bin/python3 folder + install(DIRECTORY ${_xstudio_vcpkg_python} DESTINATION bin) endif() \ No newline at end of file diff --git a/src/python_module/src/CMakeLists.txt b/src/python_module/src/CMakeLists.txt index 8ee52b856..ac272b9c8 100644 --- a/src/python_module/src/CMakeLists.txt +++ b/src/python_module/src/CMakeLists.txt @@ -39,6 +39,13 @@ if (APPLE) # Our install commands will copy the entire python3.X folder into the app bundle # when making the re-locatable .app structure set(OUTPUT_DIR "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/${PYTHONVP}/site-packages/xstudio/core") +elseif (WIN32) + # Build the .pyd directly into the dev-tree mirror of its install location + # (build/bin/python3/Lib/site-packages/xstudio/core/). The matching + # install(TARGETS) rule below, which is target-based, picks the .pyd up + # from wherever LIBRARY_OUTPUT_DIRECTORY put it. No POST_BUILD copy, + # .pdb co-located with the binary so the debugger resolves symbols cleanly. + set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/bin/python3/Lib/site-packages/xstudio/core") else() set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/bin/python/lib/${PYTHONVP}/site-packages/xstudio/core") endif()