Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python _otio extension module incorrectly links against external Imath library #1662

Open
nrusch opened this issue Sep 12, 2023 · 2 comments
Labels
bug A problem, flaw, or broken functionality. cmake issues with the cmake scripts

Comments

@nrusch
Copy link

nrusch commented Sep 12, 2023

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.

@nrusch nrusch added the bug A problem, flaw, or broken functionality. label Sep 12, 2023
@meshula
Copy link
Collaborator

meshula commented Sep 12, 2023

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.

@nrusch
Copy link
Author

nrusch commented Sep 12, 2023

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})

@reinecke reinecke added the cmake issues with the cmake scripts label Sep 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A problem, flaw, or broken functionality. cmake issues with the cmake scripts
Projects
None yet
Development

No branches or pull requests

3 participants