-
Notifications
You must be signed in to change notification settings - Fork 49
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
CMake design: How to make vanilla CMake installs play nice with python packaging #856
Comments
CMake strips RPaths that are outside the install tree. You probably need: set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) That will leave the proper |
For windows it points to |
In our project (https://github.com/mqt-core) we use the following snippet if(APPLE)
set(BASEPOINT @loader_path)
else()
set(BASEPOINT $ORIGIN)
endif()
set(CMAKE_INSTALL_RPATH ${BASEPOINT} ${BASEPOINT}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) The As for the windows problems: you can emulate something similar to what delvewheel is doing and patch your import sys
# under Windows, make sure to add the appropriate DLL directory to the PATH
if sys.platform == "win32":
def _dll_patch() -> None:
"""Add the DLL directory to the PATH."""
import os
import sysconfig
from pathlib import Path
bin_dir = Path(sysconfig.get_paths()["purelib"]) / "mqt" / "core" / "bin"
os.add_dll_directory(str(bin_dir))
_dll_patch()
del _dll_patch At least that's our current way of trying to make it work in cda-tum/mqt-core#662 |
Awesome, thanks for sharing that. Let me try them out and I'll share my version as well for reference |
Ok, here's my version which addresses various quirks. Some parts are due to having the C library be the main CMake recipe, but all sub-projects are independently buildable. # Try to find system installed library, otherwise use the bundled version
if (NOT TARGET Spglib::symspg)
find_package(Spglib CONFIG)
if (NOT Spglib_FOUND)
message(STATUS "Using bundled spglib sources")
add_subdirectory(${PROJECT_SOURCE_DIR}/.. _deps/spglib-build)
endif ()
endif ()
# Set appropriate RPATH. If it's using the system one, it should point to empty folders and not have any effect
set_target_properties(Spglib_python PROPERTIES
INSTALL_RPATH "$<IF:$<BOOL:${APPLE}>,@loader_path,$ORIGIN>/${CMAKE_INSTALL_LIBDIR}"
)
# Make the python package runnable within the build tree
file(COPY spglib
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/
)
add_custom_command(TARGET Spglib_python POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink
$<TARGET_FILE:Spglib_python>
${CMAKE_CURRENT_BINARY_DIR}/spglib/$<TARGET_FILE_NAME:Spglib_python>
COMMAND ${CMAKE_COMMAND} -E copy -t ${CMAKE_CURRENT_BINARY_DIR}/spglib/ $<TARGET_RUNTIME_DLLS:Spglib_python>
COMMAND_EXPAND_LISTS
)
# Installation stuff using `wheel.install-dir="spglib"` for the `.` destination
if (NOT SKBUILD AND SPGLIB_INSTALL)
message(WARNING "Installing the python bindings outside of scikit-build-core environment is not supported.")
elseif (SPGLIB_INSTALL)
if (TARGET Spglib_symspg)
# For windows systems we need to also install a copy of the dll files, this has no effect otherwise
install(TARGETS Spglib_symspg
RUNTIME DESTINATION . COMPONENT Spglib_Runtime
)
endif ()
install(TARGETS Spglib_python
LIBRARY DESTINATION . COMPONENT Spglib_Runtime
)
endif () The last part I'm not fond of because it creates a copy of the |
I have started to work on spglib/spglib#520, where I redesign the build process to be more compatible with
audit-wheel
and make things simpler overall. The problems that I am trying to tackle there:pip install
environment (too fragile to allow standalonecmake --install
without populating.dist-info
metadata)INSTALL_RPATH
on the python bindings file pointing to$ORIGIN/${CMAKE_INSTALL_LIBDIR}
GNUInstallDirs
(except for the python bindings which point to.
), with the install prefix pointing to the python packageThat design works relatively well but I am hitting 2 issues:
INSTALL_RPATH
equivalent, and usually it relies on all the.dll
files being in the same folder, but this conflicts withGNUInstallDirs
where it would put them inbin
, but on the other hand, we need the python bindings to be under the path dictated byimport ...
.Is there a way to reconcile these? I was thinking maybe putting the python bindings under the
GNUInstallDirs
structure as well, but that is not predictable since it would be${CMAKE_INSTALL_LIBDIR}
on unix, but${CMAKE_INSTALL_BINDIR}
on windowsrepair-wheel
commands are failing with rather cryptic issue:The text was updated successfully, but these errors were encountered: