Skip to content

Commit ce64696

Browse files
authored
Return to building OTIO from source (#991)
### Fix occasional segault on Windows release startup ### Summarize your change. In commit 93819da to pin the OTIO version, I change the requirements.txt file used to install OTIO to point to a version number instead of a git commit like it was doing before. This introduced an unintended side effect. When you point to a particular git commit the wheel will always be built locally before installing, which makes sense when you think about it because there are no pre-built wheels hosted in git. Conversely, when you use a version number, pip will check pypi for a pre-built wheel before building and install that if it exists. The only pre-built wheel that has a match is Windows release -- there are no debug versions, we don't use the same flavour of Linux as OTIO pre-built wheels nor the same verison of mac OS. This causes a problem because we are building our own version of python and unless the compilers, shared lib versions, etc match exactly there is a potential for ABI in compatibilities and resulting crashes. To fix it, we will simply go back to using a git commit so we always build our own wheels. However, we will use the version to to match the tag in git so we are still pinned which was the point of the previous commit. Lastly, there was a portion of custom code for Windows debug version to build OTIO for the exact problem we're trying to solve here. However, since we started pointing at a git commit this all became useless since once requirements.txt is already doing exactly the same thing. Thus, I removed all the code and we will only have a single code path to build OTIO. ### Describe the reason for the change. Fix an occasional startup crash on Windows (depending on your compiler and shared lib versions). ### Describe what you have tested and on which operating system. Windows 11. Built and launched successfully. Signed-off-by: Roger Nelson <[email protected]>
1 parent 92f4e8a commit ce64696

File tree

3 files changed

+17
-88
lines changed

3 files changed

+17
-88
lines changed

cmake/dependencies/python3.cmake

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ SET(_python3_target
88
"RV_DEPS_PYTHON3"
99
)
1010

11-
SET(_opentimelineio_target
12-
"RV_DEPS_OPENTIMELINEIO"
13-
)
14-
1511
RV_VFX_SET_VARIABLE(_pyside_target CY2023 "RV_DEPS_PYSIDE2" CY2024 "RV_DEPS_PYSIDE6")
1612

1713
SET(PYTHON_VERSION_MAJOR
@@ -33,28 +29,25 @@ SET(RV_DEPS_PYTHON_VERSION_SHORT
3329
"${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}"
3430
)
3531

36-
# This version is used for:
37-
# 1. Building OpenTimelineIO from source for Windows debug builds
38-
# 2. Generating src/build/requirements.txt from requirements.txt.in template
39-
# (used by all other platforms/builds to install from PyPI)
32+
# This version is used for generating src/build/requirements.txt from requirements.txt.in template
33+
# All platforms install OpenTimelineIO from git to ensure consistent source builds.
4034
SET(_opentimelineio_version
4135
"0.18.1"
4236
)
4337

38+
# Construct the full git URL for pip to use in requirements.txt
39+
# Using this avoids @ symbol conflicts in CONFIGURE_FILE
40+
SET(_opentimelineio_pip_url
41+
"git+https://github.com/AcademySoftwareFoundation/OpenTimelineIO@v${_opentimelineio_version}#egg=OpenTimelineIO"
42+
)
43+
4444
RV_VFX_SET_VARIABLE(_pyside_version CY2023 "5.15.10" CY2024 "6.5.3")
4545

4646
SET(_python3_download_url
4747
"https://github.com/python/cpython/archive/refs/tags/v${_python3_version}.zip"
4848
)
4949
RV_VFX_SET_VARIABLE(_python3_download_hash CY2023 "21b32503f31386b37f0c42172dfe5637" CY2024 "392eccd4386936ffcc46ed08057db3e7")
5050

51-
SET(_opentimelineio_download_url
52-
"https://github.com/AcademySoftwareFoundation/OpenTimelineIO"
53-
)
54-
SET(_opentimelineio_git_tag
55-
"v${_opentimelineio_version}"
56-
)
57-
5851
RV_VFX_SET_VARIABLE(
5952
_pyside_archive_url
6053
CY2023
@@ -75,18 +68,8 @@ SET(_build_dir
7568
${RV_DEPS_BASE_DIR}/${_python3_target}/build
7669
)
7770

78-
IF(RV_TARGET_WINDOWS)
79-
80-
FETCHCONTENT_DECLARE(
81-
${_opentimelineio_target}
82-
GIT_REPOSITORY ${_opentimelineio_download_url}
83-
GIT_TAG ${_opentimelineio_git_tag}
84-
SOURCE_SUBDIR "src" # Avoids the top level CMakeLists.txt
85-
)
86-
87-
FETCHCONTENT_MAKEAVAILABLE(${_opentimelineio_target})
88-
89-
ENDIF()
71+
# Note: OpenTimelineIO is now installed via requirements.txt from git URL for all platforms.
72+
# This ensures consistent source builds across Windows, Mac, and Linux.
9073

9174
FETCHCONTENT_DECLARE(
9275
${_pyside_target}
@@ -121,8 +104,6 @@ IF(DEFINED RV_DEPS_OPENSSL_INSTALL_DIR)
121104
LIST(APPEND _python3_make_command ${RV_DEPS_OPENSSL_INSTALL_DIR})
122105
ENDIF()
123106
IF(RV_TARGET_WINDOWS)
124-
LIST(APPEND _python3_make_command "--opentimelineio-source-dir")
125-
LIST(APPEND _python3_make_command ${rv_deps_opentimelineio_SOURCE_DIR})
126107
LIST(APPEND _python3_make_command "--python-version")
127108
LIST(APPEND _python3_make_command "${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}")
128109
ENDIF()

src/build/make_python.py

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
TEMP_DIR = ""
3333
VARIANT = ""
3434
ARCH = ""
35-
OPENTIMELINEIO_SOURCE_DIR = ""
3635

3736
LIB_DIR = ""
3837

@@ -120,8 +119,9 @@ def get_python_interpreter_args(python_home: str, variant: str) -> List[str]:
120119
:return: Path to the python interpreter
121120
"""
122121

123-
build_opentimelineio = platform.system() == "Windows" and variant == "Debug"
124-
python_name_pattern = "python*" if not build_opentimelineio else "python_d*"
122+
# On Windows Debug, use the debug Python interpreter (python_d.exe)
123+
use_debug_python = platform.system() == "Windows" and variant == "Debug"
124+
python_name_pattern = "python*" if not use_debug_python else "python_d*"
125125

126126
python_interpreters = glob.glob(os.path.join(python_home, python_name_pattern), recursive=True)
127127
python_interpreters += glob.glob(os.path.join(python_home, "bin", python_name_pattern))
@@ -279,48 +279,8 @@ def test_python_distribution(python_home: str) -> None:
279279

280280
python_interpreter_args = get_python_interpreter_args(tmp_python_home, VARIANT)
281281

282-
# Note: We need to build opentimelineio from sources in Windows+Debug
283-
# because the official wheel links with the release version of
284-
# python while RV uses the debug version.
285-
build_opentimelineio = platform.system() == "Windows" and VARIANT == "Debug"
286-
if build_opentimelineio:
287-
print("Building opentimelineio")
288-
289-
# Request an opentimelineio debug build
290-
my_env = os.environ.copy()
291-
my_env["OTIO_CXX_DEBUG_BUILD"] = "1"
292-
293-
# Specify the location of the debug python import lib (eg. python39_d.lib)
294-
python_include_dirs = os.path.join(tmp_python_home, "include")
295-
python_lib = os.path.join(tmp_python_home, "libs", f"python{PYTHON_VERSION}_d.lib")
296-
my_env["CMAKE_ARGS"] = f"-DPython_LIBRARY={python_lib} -DCMAKE_INCLUDE_PATH={python_include_dirs}"
297-
298-
opentimelineio_install_arg = python_interpreter_args + [
299-
"-m",
300-
"pip",
301-
"install",
302-
".",
303-
]
304-
305-
subprocess.run(
306-
opentimelineio_install_arg,
307-
env=my_env,
308-
cwd=OPENTIMELINEIO_SOURCE_DIR,
309-
).check_returncode()
310-
311-
# Note : The OpenTimelineIO build will generate the pyd with names that are not loadable by default
312-
# Example: _opentimed_d.cp39-win_amd64.pyd instead of _opentime_d.pyd
313-
# and _otiod_d.cp39-win_amd64.pyd instead of _otio_d.pyd
314-
# We fix those names here
315-
otio_module_dir = os.path.join(tmp_python_home, "lib", "site-packages", "opentimelineio")
316-
for _file in os.listdir(otio_module_dir):
317-
if _file.endswith("pyd"):
318-
otio_lib_name_split = os.path.basename(_file).split(".")
319-
if len(otio_lib_name_split) > 2:
320-
new_otio_lib_name = otio_lib_name_split[0].replace("d_d", "_d") + ".pyd"
321-
src_file = os.path.join(otio_module_dir, _file)
322-
dst_file = os.path.join(otio_module_dir, new_otio_lib_name)
323-
shutil.copyfile(src_file, dst_file)
282+
# Note: OpenTimelineIO is installed via requirements.txt for all platforms and build types.
283+
# The git URL in requirements.txt ensures it builds from source with proper linkage.
324284

325285
wheel_install_arg = python_interpreter_args + [
326286
"-m",
@@ -329,10 +289,7 @@ def test_python_distribution(python_home: str) -> None:
329289
"cryptography",
330290
]
331291

332-
if not build_opentimelineio:
333-
wheel_install_arg.append("opentimelineio")
334-
335-
print(f"Validating the that we can install a wheel with {wheel_install_arg}")
292+
print(f"Validating that we can install a wheel with {wheel_install_arg}")
336293
subprocess.run(wheel_install_arg).check_returncode()
337294

338295
python_validation_args = python_interpreter_args + [
@@ -786,14 +743,6 @@ def install_python_vfx2024() -> None:
786743

787744
parser.add_argument("--vfx_platform", dest="vfx_platform", type=int, required=True)
788745

789-
parser.add_argument(
790-
"--opentimelineio-source-dir",
791-
dest="otio_source_dir",
792-
type=str,
793-
required=False,
794-
default="",
795-
)
796-
797746
if platform.system() == "Windows":
798747
# Major and minor version of Python without dots. E.g. 3.10.3 -> 310
799748
parser.add_argument(
@@ -814,7 +763,6 @@ def install_python_vfx2024() -> None:
814763
OPENSSL_OUTPUT_DIR = args.openssl
815764
VARIANT = args.variant
816765
ARCH = args.arch
817-
OPENTIMELINEIO_SOURCE_DIR = args.otio_source_dir
818766
VFX_PLATFORM = args.vfx_platform
819767

820768
if platform.system() == "Darwin":

src/build/requirements.txt.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
pip # License: MIT License (MIT)
66
setuptools # License: MIT License
7-
OpenTimelineIO==@_opentimelineio_version@ # License: Other/Proprietary License (Modified Apache 2.0 License)
7+
@_opentimelineio_pip_url@ # License: Other/Proprietary License (Modified Apache 2.0 License)
88
PyOpenGL # License: BSD License (BSD)
99

1010
# MacOS only - PyOpenGL_accelerate is built from source in python3.cmake as a workaround until the fix

0 commit comments

Comments
 (0)