OpenTimelineIO
OpenTimelineIO copied to clipboard
Python `_otio` extension module incorrectly links against external `Imath` library
I'm building OTIO against an external Imath
distribution (i.e. OTIO_FIND_IMATH=ON
), and it looks like the _otio
Python extension module is being linked directly against the Imath
lib, leading to the following runtime error:
> python -c 'import opentimelineio'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/luma/dev/ruschn/rez-release/opentimelineio/0.0.cxx17/platform-linux/gcc-9.3.1/python-3.9/python/opentimelineio/__init__.py", line 14, in <module>
from . import (
File "/luma/dev/ruschn/rez-release/opentimelineio/0.0.cxx17/platform-linux/gcc-9.3.1/python-3.9/python/opentimelineio/opentime.py", line 4, in <module>
from . _opentime import ( # noqa
ImportError: libImath-3_1.so.29: cannot open shared object file: No such file or directory
Here is the patchelf
output for the _otio
library:
>>> patchelf --print-needed /luma/dev/ruschn/rez-release/opentimelineio/0.0.cxx17/platform-linux/gcc-9.3.1/python-3.9/python/opentimelineio/_otio.cpython-39-x86_64-linux-gnu.so
libopentimelineio.so
libopentime.so
libImath-3_1.so.29
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6
If I manually remove the direct dependency on libImath-3_1.so.29
, the error is resolved:
> patchelf --remove-needed libImath-3_1.so.29 /luma/dev/ruschn/rez-release/opentimelineio/0.0.cxx17/platform-linux/gcc-9.3.1/python-3.9/python/opentimelineio/_otio.cpython-39-x86_64-linux-gnu.so
Looking at the CMake build configuration, I'm fairly certain this is because Imath
is included in the public link interface for the opentimelineio
target (https://github.com/AcademySoftwareFoundation/OpenTimelineIO/blob/main/src/opentimelineio/CMakeLists.txt#L88-L89), and thus becomes a transitive dependency when the opentimelineio-bindings
target is linked against it.
To Reproduce
Versions
- CentOS 7.9.2009
- GCC 9.3.1 (installed via
devtoolset-9
RPM) - CMake 3.25.1
- Imath 3.1.9
- Python 3.9.13
CMake Arguments
cmake \
-D CMAKE_INSTALL_PREFIX=/path/to/install_prefix \
-D CMAKE_EXE_LINKER_FLAGS=-Wl,--enable-new-dtags \
-D CMAKE_SHARED_LINKER_FLAGS=-Wl,--enable-new-dtags \
-D CMAKE_CXX_STANDARD=17 \
-D CMAKE_CXX_EXTENSIONS=OFF \
-D CMAKE_CXX_FLAGS="-D_GLIBCXX_USE_CXX11_ABI=0" \
-D OTIO_PYTHON_INSTALL=ON \
-D OTIO_DEPENDENCIES_INSTALL=OFF \
-D OTIO_FIND_IMATH=ON \
/path/to/source_dir
Imath is being located via the CMAKE_PREFIX_PATH
environment variable, which includes the directory containing the Imath/ImathConfig.cmake
file.
Additional Note: It looks like the opentime
Python extension module may (unnecessarily?) link against libopentimelineio
. This may warrant a separate issue.
You are right, opentime should't link against opentimelineio. I haven't seen that reported before, I wonder what's up.
The transitive dependence should be specifically that the include path to Imath is public ~ does cmake have a way to do that?
If you have answers to these feel free to create a PR.
You are right, opentime should't link against opentimelineio. I haven't seen that reported before, I wonder what's up.
Yeah, this one is a bit of a mystery, and may be due to the revision I'm building from. I'll keep poking around and open a separate issue if I can prove it. :)
The transitive dependence should be specifically that the include path to Imath is public ~ does cmake have a way to do that?
In an Imath 3.x-only world, you could use Imath::ImathConfig
instead of Imath::Imath
as the public link target, and then Imath::Imath
as a private target, though the redundancy is unfortunate.
Supporting both IlmBase and Imath 3.x will take a bit more footwork. I would point to OpenImageIO as a good example of how to support them in tandem and distill things down to a common set of CMake variables: https://github.com/OpenImageIO/oiio/blob/master/src/cmake/modules/FindOpenEXR.cmake
Currently, the ${IMATH_INCLUDES}
variable is not set when using Imath 3.x, otherwise I think you could do something like this:
target_include_directories(opentimelineio
PUBLIC "${IMATH_INCLUDES}"
PRIVATE "${PROJECT_SOURCE_DIR}/src"
"${PROJECT_SOURCE_DIR}/src/deps"
"${PROJECT_SOURCE_DIR}/src/deps/optional-lite/include"
"${PROJECT_SOURCE_DIR}/src/deps/rapidjson/include")
target_link_libraries(opentimelineio
PUBLIC opentime
PRIVATE ${OTIO_IMATH_TARGETS})