Skip to content

Commit

Permalink
Qt6 Feature - Fix issues with Python 3.11 and PySide6 compilation on …
Browse files Browse the repository at this point in the history
…Windows (#651)

### Qt6 Feature - Fix issues with Python

### Linked issues
#367 

### Describe the reason for the change.

I created two functions to do the install step of Python. One for Python
3.10 (VFX2023) and one for Python 3.11 (VFX2024). I think it will be
easier to maintain and remove later on. The difference was only for
Windows, but both functions contains the code for all platforms.

Since Python 3.11, the `PLATLIBDIR` directory was renamed to `DLLs`
instead of `lib`. You can changed it by modifying the Visual studio
project file, but I found some place in the Python source code that was
hardcoded to `DLLs`. I opted to keep `DLLs` and copy that over to the
OpenRV's stage directory. It does not change anything functionally
because the Python executable is looking for the DLLs library
automatically.

**The changes above also fixes the issue with PySide6 compilation on
Windows.**

### Describe what you have tested and on which operating system.
Windows

### If possible, provide screenshots.
stage directory:

![image](https://github.com/user-attachments/assets/dadbad51-b8a5-4cfe-abd8-55e3ab4dd2fd)

---------

Signed-off-by: Cédrik Fuoco <[email protected]>
Signed-off-by: Cédrik Fuoco <[email protected]>
  • Loading branch information
cedrik-fuoco-adsk authored Dec 10, 2024
1 parent 71e0db4 commit 76e4fc3
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 41 deletions.
36 changes: 18 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -567,24 +567,24 @@ jobs:
msvc-compiler: "14.40.33807"

# VFX2024
# - os: "windows-2022"
# arch-type: "x86_64"
# build-type: "Release"
# qt-version: "6.5.3"
# python-version: "3.10"
# cmake-version: "3.29.8"
# vfx-platform: "CY2024"
# msvc-component: "14.40.17.10.x86.x64"
# msvc-compiler: "14.40.33807"
# - os: "windows-2022"
# arch-type: "x86_64"
# build-type: "Debug"
# qt-version: "6.5.3"
# python-version: "3.10"
# cmake-version: "3.29.8"
# vfx-platform: "CY2024"
# msvc-component: "14.40.17.10.x86.x64"
# msvc-compiler: "14.40.33807"
- os: "windows-2022"
arch-type: "x86_64"
build-type: "Release"
qt-version: "6.5.3"
python-version: "3.11"
cmake-version: "3.29.8"
vfx-platform: "CY2024"
msvc-component: "14.40.17.10.x86.x64"
msvc-compiler: "14.40.33807"
- os: "windows-2022"
arch-type: "x86_64"
build-type: "Debug"
qt-version: "6.5.3"
python-version: "3.11"
cmake-version: "3.29.8"
vfx-platform: "CY2024"
msvc-component: "14.40.17.10.x86.x64"
msvc-compiler: "14.40.33807"

runs-on: ${{ matrix.os }}
steps:
Expand Down
15 changes: 12 additions & 3 deletions cmake/dependencies/python3.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -337,14 +337,23 @@ ELSEIF(RV_VFX_PLATFORM STREQUAL CY2024)
ENDIF()

IF(RV_TARGET_WINDOWS)
ADD_CUSTOM_COMMAND(
COMMENT "Installing ${_python3_target}'s include and libs into ${RV_STAGE_LIB_DIR}"
OUTPUT ${RV_STAGE_BIN_DIR}/${_python3_lib_name}
SET(_copy_commands
COMMAND ${CMAKE_COMMAND} -E copy_directory ${_install_dir}/lib ${RV_STAGE_LIB_DIR}
COMMAND ${CMAKE_COMMAND} -E copy_directory ${_install_dir}/include ${RV_STAGE_INCLUDE_DIR}
COMMAND ${CMAKE_COMMAND} -E copy_directory ${_install_dir}/bin ${RV_STAGE_BIN_DIR}
)

IF(RV_VFX_CY2024)
LIST(APPEND _copy_commands COMMAND ${CMAKE_COMMAND} -E copy_directory ${_install_dir}/DLLs ${RV_STAGE_ROOT_DIR}/DLLs)
ENDIF()

ADD_CUSTOM_COMMAND(
COMMENT "Installing ${_python3_target}'s include and libs into ${RV_STAGE_LIB_DIR}"
OUTPUT ${RV_STAGE_BIN_DIR}/${_python3_lib_name}
${_copy_commands}
DEPENDS ${_python3_target} ${${_python3_target}-requirements-flag} ${_build_flag_depends}
)

ADD_CUSTOM_TARGET(
${_python3_target}-stage-target ALL
DEPENDS ${RV_STAGE_BIN_DIR}/${_python3_lib_name}
Expand Down
6 changes: 6 additions & 0 deletions src/build/make_pyside6.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ def build() -> None:
if OPENSSL_OUTPUT_DIR:
pyside_build_args.append(f"--openssl={os.path.join(OPENSSL_OUTPUT_DIR, 'bin')}")

if platform.system() == "Windows":
# Add the debug switch to match build type but only on Windows
# (on other platforms, PySide6 is built in release)
if VARIANT == "Debug":
pyside_build_args.append("--debug")

print(f"Executing {pyside_build_args}")
subprocess.run(pyside_build_args).check_returncode()

Expand Down
111 changes: 91 additions & 20 deletions src/build/make_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,75 @@ def build() -> None:
).check_returncode()


def install() -> None:
def install_python_vfx2023() -> None:
"""
Run the install step of the build. It puts all the files inside of the output directory and make them ready to be
packaged.
"""

if os.path.exists(OUTPUT_DIR):
shutil.rmtree(OUTPUT_DIR)

if platform.system() == "Windows":
# include
src_dir = os.path.join(SOURCE_DIR, "Include")
dst_dir = os.path.join(OUTPUT_DIR, "include")
shutil.copytree(src_dir, dst_dir)
src_file = os.path.join(SOURCE_DIR, "PC", "pyconfig.h")
dst_file = os.path.join(dst_dir, "pyconfig.h")
shutil.copyfile(src_file, dst_file)

# lib
src_dir = os.path.join(SOURCE_DIR, "Lib")
dst_dir = os.path.join(OUTPUT_DIR, "lib")
shutil.copytree(src_dir, dst_dir)

# libs - required by pyside2
dst_dir = os.path.join(OUTPUT_DIR, "libs")
os.mkdir(dst_dir)
python_libs = glob.glob(
os.path.join(SOURCE_DIR, "PCBuild", "amd64", "python*.lib")
)
if python_libs:
for python_lib in python_libs:
shutil.copy(python_lib, dst_dir)

# bin
src_dir = os.path.join(SOURCE_DIR, "PCBuild", "amd64")
dst_dir = os.path.join(OUTPUT_DIR, "bin")
shutil.copytree(src_dir, dst_dir)
# Create a python3.exe file to mimic Mac+Linux
if VARIANT == "Debug":
src_python_exe = "python_d.exe"
else:
src_python_exe = "python.exe"
src_file = os.path.join(src_dir, src_python_exe)
dst_file = os.path.join(dst_dir, "python3.exe")
shutil.copyfile(src_file, dst_file)

else:
make_args = ["make", "install", f"-j{os.cpu_count() or 1}", "-s"]

print(f"Executing {make_args} from {SOURCE_DIR}")
subprocess_env = {**os.environ}
if OPENSSL_OUTPUT_DIR:
subprocess_env["LC_RPATH"] = os.path.join(OPENSSL_OUTPUT_DIR, "lib")
subprocess.run(
make_args,
cwd=SOURCE_DIR,
env=subprocess_env,
).check_returncode()

# Create the 'python' symlink
if platform.system() != "Windows":
python3_path = os.path.realpath(os.path.join(OUTPUT_DIR, "bin", "python3"))
python_path = os.path.join(os.path.dirname(python3_path), "python")
os.symlink(os.path.basename(python3_path), python_path)

patch_python_distribution(OUTPUT_DIR)
test_python_distribution(OUTPUT_DIR)

def install_python_vfx2024() -> None:
"""
Run the install step of the build. It puts all the files inside of the output directory and make them ready to be
packaged.
Expand Down Expand Up @@ -683,24 +751,28 @@ def install() -> None:
OUTPUT_DIR,
"--temp",
os.path.join(parent, "temp"),
"--preset-default",
"--include-dev",
"--include-symbols",
"--include-tcltk",
"--include-tests",
"--include-venv",
"--flat-dlls",
]

if VARIANT == "Debug":
install_args.append("--debug")

subprocess.run(install_args, cwd=SOURCE_DIR).check_returncode()
print(f"Executing {install_args}")

dst_dir = os.path.join(OUTPUT_DIR, "bin")
libs_dir = os.path.join(OUTPUT_DIR, "libs")
os.makedirs(dst_dir, exist_ok=True)
subprocess.run(
install_args,
cwd=SOURCE_DIR
).check_returncode()

# bin
libs_dir = os.path.join(OUTPUT_DIR, "libs")
dst_dir = os.path.join(OUTPUT_DIR, "bin")

# Create a python3.exe file to mimic Mac+Linux
if VARIANT == "Debug":
src_python_exe = "python_d.exe"
Expand All @@ -710,11 +782,13 @@ def install() -> None:
src_file = os.path.join(OUTPUT_DIR, src_python_exe)
dst_file = os.path.join(dst_dir, "python3.exe")
print(f"Copy {src_file} to {dst_file}")

os.makedirs(dst_dir, exist_ok=True)
shutil.copyfile(src_file, dst_file)

# Move files under root directory into the bin folder.
for filename in os.listdir(os.path.join(OUTPUT_DIR)):
file_path = os.path.join(OUTPUT_DIR, filename)
file_path = os.path.join(OUTPUT_DIR, filename)
if os.path.isfile(file_path):
shutil.move(file_path, os.path.join(dst_dir, filename))

Expand All @@ -726,16 +800,9 @@ def install() -> None:
python3_lib = "python3_d.lib"
python3xx_lib = f"python{PYTHON_VERSION}_d.lib"

shutil.copy(
os.path.join(build_path, python3_lib), os.path.join(dst_dir, python3_lib)
)
shutil.copy(
os.path.join(build_path, python3_lib), os.path.join(libs_dir, python3_lib)
)
shutil.copy(
os.path.join(build_path, python3xx_lib),
os.path.join(dst_dir, python3xx_lib),
)
shutil.copy(os.path.join(build_path, python3_lib), os.path.join(dst_dir, python3_lib))
shutil.copy(os.path.join(build_path, python3_lib), os.path.join(libs_dir, python3_lib))
shutil.copy(os.path.join(build_path, python3xx_lib), os.path.join(dst_dir, python3xx_lib))

# Tcl and Tk DLL are not copied by the main.py script in Debug.
# Assuming that Tcl and Tk are not built in debug.
Expand All @@ -752,7 +819,7 @@ def install() -> None:
print(f"Executing {make_args} from {SOURCE_DIR}")
subprocess_env = {**os.environ}
if OPENSSL_OUTPUT_DIR:
subprocess_env["LC_RPATH"] = os.path.join(OPENSSL_OUTPUT_DIR, LIB_DIR)
subprocess_env["LC_RPATH"] = os.path.join(OPENSSL_OUTPUT_DIR, "lib")
subprocess.run(
make_args,
cwd=SOURCE_DIR,
Expand All @@ -768,7 +835,6 @@ def install() -> None:
patch_python_distribution(OUTPUT_DIR)
test_python_distribution(OUTPUT_DIR)


if __name__ == "__main__":
parser = argparse.ArgumentParser()

Expand Down Expand Up @@ -843,4 +909,9 @@ def install() -> None:
build()

if args.install:
install()
# The install functions has a lot of similiarity but I think it is better to have two differents
# functions because it will be easier to drop the support for a VFX platform.
if VFX_PLATFORM == 2023:
install_python_vfx2023()
elif VFX_PLATFORM == 2024:
install_python_vfx2024()

0 comments on commit 76e4fc3

Please sign in to comment.