AcademySoftwareFoundation / Imath

Imath is a C++ and python library of 2D and 3D vector, matrix, and math operations for computer graphics

Home Page:https://imath.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Alembic Windows compilation Python3.9.10 `called with non-existent target "Imath::PyImath_Python3_9".`

OlivierArgentieri opened this issue · comments

Compilation issue on windows

TLDR:

CMake Error at python/PyAlembic/Tests/CMakeLists.txt:49 (GET_TARGET_PROPERTY):
get_target_property() called with non-existent target
"Imath::PyImath_Python3_9".

How to reproduce

Requierements:

  • python 3.9.10
  • Boost source code (tested with 1.85.0 and 1.81.0, same behavior)
  • Imath Source code (3.1.11)
  • Alembic source code (1.8.5)
  • CMake
  • MSVC 14.39.33519

Compile boost with python binding

You can use b2 or cmake, i have tested with both, but in this example i will detail with cmake, more simple to explain.

So in <Boost_SOURCE_ROOT>/:

cmake -S . -B ./build -DBOOST_ENABLE_PYTHON=ON -DPython_ROOT_DIR=C:/python39 -DCMAKE_INSTALL_PREFIX=E:/compile_alembic/boost-1.85.0/install_prefix

cmake --build .\build\ --config Release --target install 

Compile IMath

In <IMath_SOURCE_ROOT>/

cmake -S . -B ./build -DPYTHON=ON -DCMAKE_INSTALL_PREFIX=E:/compile_alembic/Imath-3.1.11/install -DCMAKE_BUILD_TYPE=Release -DBoost_ROOT=E:/compile_alembic/boost-1.85.0/install_prefix -DPython_EXECUTABLE=C:/Python39/python.exe -DPython3_EXECUTABLE=C:/Python39/python.exe -DBoost_NO_BOOST_CMAKE=OFF

cmake --build .\build\ --config Release --target install 

Compile Alembic

cmake -S . -B ./build/ -DImath_ROOT=E:/compile_alembic/Imath-3.1.11/install -DUSE_PYALEMBIC=ON -DCMAKE_INSTALL_PREFIX=E:/compile_alembic/alembic-1.8.5/install -DBoost_INCLUDE_DIR=E:/compile_alembic/boost-1.85.0/install_prefix/includes/boost-1.85.0  -DCMAKE_BUILD_TYPE=Release

And now you should see this error:

CMake Error at python/PyAlembic/Tests/CMakeLists.txt:49 (GET_TARGET_PROPERTY):
  get_target_property() called with non-existent target
  "Imath::PyImath_Python3_9".

Things tried

  • Recompile boost using b2 then recompile imath
  • Recompile boost v1.81.0 using b2 then recompile imath
  • Recompile boost v1.81.0 using b2 and theses arguments release link=shared --python=3.9 --build-type=complete --prefix=.\prefix_install --threading=multi then recompile imath
  • Edit the .cmake file in <PREFIX_IMATH>/lib/cmake/Imath/ImathTargets-release.cmake To check if you have the Imath::PyImath_Python3_9 target, but we don't. , so i have tried to create-it manually, like this
set_property(TARGET Imath::PyImath_Python3_9 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Imath::PyImath_Python3_9 PROPERTIES
  IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/PyImath_Python3_9-3_1.lib"
  IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/PyImath_Python3_9-3_1.dll"
  )

Then i also add this in ImathTargets.cmake

...
add_library(Imath::PyImath_Python3_9 INTERFACE IMPORTED)
set_target_properties(Imath::PyImath_Python3_9 PROPERTIES
  INTERFACE_COMPILE_DEFINITIONS "IMATH_DLL"
  INTERFACE_COMPILE_FEATURES "cxx_std_11"
  INTERFACE_COMPILE_OPTIONS "/EHsc"
  INTERFACE_INCLUDE_DIRECTORIES "E:/compile_alembic/boost-1.85.0/install_prefix/includes/boost-1.85.0"
  INTERFACE_LINK_LIBRARIES "Imath::ImathConfig"
)
...

Everything i tried above, didn't work and when i try to compile without python binding it's works...

I don't know if it's normal or not, but i have searched for this Imath::PyImath_Python3_9 target, and i didn't find it in any of targets .cmake file under <PREFIX_IMATH>/lib/cmake/Imath/, that's why i'm posting this issue here instead of on alembic google group.

Maybe i made something wrong, i'm a beginner with all this compilation pipeline stuff, using Imath and alembic, don't hesistate to share with me some feedbacks or idea.

Thank you

We noticed this problem on Linux as well.

We suspect its related to this:
#360

Making it optional ended up totally removing Imath::PyImath_Python3_9 from ImathTargets-release.cmake.

@lamiller0 Do you think the problem is that the PyAlembic links against PyImath and therefore the EXPORT is in fact required when you are linking against PyImath? And in fact the fix does not make the python bindings optional but merely makes the linking of the python bindings impossible?

I do notice that alembic is not listed in the list of tested packages on Debian on the original report.

I wonder if the original bug report

CMake Error at /usr/lib/x86_64-linux-gnu/cmake/Imath/ImathTargets.cmake:115 (message):
  The imported target "Imath::PyImath_Python3_11" references the file

     "/usr/lib/x86_64-linux-gnu/libPyImath_Python3_11-3_1.so.29.8.0"
     but this file does not exist.

Indicates a more direct problem, like /usr/lib/x86_64-linux-gnu/libPyImath_Python3_11-3_1.so.29.8.0 actually does not exist, as the error says; perhaps it is not named correctly in ImathTargets.cmake, or perhaps it wasn't copied to the target destination.

I notice that the original bug report does not post the contents of ImathTargets.cmake, so I think we are fishing in the dark here. I assume that if you restore the line, then PyAlembic links again?

I assume that if you restore the line, then PyAlembic links again?

I ran out of time to be able to confirm this, but hope to early next week. I suspect the solution will be to EXPORT it if building PyImath.

Thank you all for your answers.

So I retried to compile alembic using an old version of imath, the built of alembic was a success using Imath v3.1.8 !

I think the idea of the original PR was that you didn't want that export to occur if you were turning off the python bindings. But instead of making it conditional on that, it just removed the export entirely, which breaks other projects that want the exported config to contain the target for the python module.

But admittedly, I'm a little hazy on the whole thing, so I may be misunderstanding.

I guess maybe it's more subtle than that? If I understand the original PR correctly, they were ok building the python bindings, but didn't want to install them, and in that case, having the exported target caused problems downstream. But now removing the exported target entirely causes problems for other downstream projects that need it (such as Alembic). So I stand by my assertion that the right fix should have been to selectively export the target so that somehow it still is present when you do want to both build and install the python bindings. (I'm still a little unclear on what the use case is for wanting to build, but not install, the python bindings.)

You're exactly right, Larry

The motivation to build the python bindings but not install them is this: Whether or not you EXPORT them, they are made available to Python by virtue of being in site-packages or whatever. The usual Python thing. EXPORT makes the library available for linking in a C++ linking area AND ALSO tells anything linking via the c/c++ toolchain that it needs to link to that library.

If you are linking against Imath, that's independent of linking against PyImath. So why do all those projects in debian think they need to link against pyimath in the first place? I think that's the root cause bad news right there, and eliding EXPORT is a red herring. Does our cmake put a dependency on pyimath on everything that links imath? That would be a root cause but I don't see where that would be happening.

The EXPORT is in the MODULE_DEFINE for PyImath, not the library define for Imath. Do how does the python module impinge on the C++ build IN ANY WAY unless the export line itself is bad. That could be it.

EXPORT ${PROJECT_NAME}

PROJECT_NAME is likely Imath and this corrupts things, and probably we should exporting PYMODULE_NAME or whatever mystery sauce cmake has for the purpose.

I just did a few experiments with bringng back the EXPORT line back and diffing what changed when building WITH python:

In ImathTargets.cmake:

foreach(_cmake_expected_target IN ITEMS Imath::ImathConfig Imath::Imath Imath::PyImathConfig Imath::PyImath_Python3_9)

The Imath::PyImath_Python3_9 is added.

Also this block is added:

# Create imported target Imath::PyImath_Python3_9
add_library(Imath::PyImath_Python3_9 SHARED IMPORTED)

set_target_properties(Imath::PyImath_Python3_9 PROPERTIES
  INTERFACE_COMPILE_FEATURES "cxx_std_14"
  INTERFACE_INCLUDE_DIRECTORIES "/spfs/include"
  INTERFACE_LINK_LIBRARIES "Imath::Imath"
)

In ImathTargets-release.cmake this block is added:

# Import target "Imath::PyImath_Python3_9" for configuration "Release"
set_property(TARGET Imath::PyImath_Python3_9 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Imath::PyImath_Python3_9 PROPERTIES
  IMPORTED_LINK_DEPENDENT_LIBRARIES_RELEASE "Python3::Python"
  IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib64/libPyImath_Python3_9-3_1.so.29.10.0"
  IMPORTED_SONAME_RELEASE "libPyImath_Python3_9-3_1.so.29"
  )

list(APPEND _cmake_import_check_targets Imath::PyImath_Python3_9 )
list(APPEND _cmake_import_check_files_for_Imath::PyImath_Python3_9 "${_IMPORT_PREFIX}/lib64/libPyImath_Python3_9-3_1.so.29.10.0" )

Thanks for that. None of that introduces an erroneous new dependency to non-python oriented targets.