The issue I am thinking of solving is to have a way to inject some LD_LIBRARY_PATH or PATH so that it accounts for the path discrepancy of CMake installed files under site_packages and bin/Scripts location. I am considering two distinct cases here
Linking to dependencies
Writing the logic to create the appropriate RPATH for a dependency can be quite tricky, but maybe we can provide some helper functions. The key part is that within scikit-build-core we have better information of if a dependency is coming from the python dependencies, and what the relative paths between the root of the dependency and the final installation path including wheel.install-dir are.
For the user interface, I was thinking of providing a CMake function to handle an imported target and append an appropriate INSTALL_RPATH. Here is a prototype
prototype
function(scikit_build_add_rpath requesting_target imported_target)
# Save the rpath origin symbol
if(APPLE)
set(origin_symbol "@rpath")
else()
set(origin_symbol "$ORIGIN")
endif()
# Check if the imported_target is imported
get_target_property(imported ${imported_target} IMPORTED)
if(NOT imported)
# TODO: What to do with non-imported targets?
return()
endif()
# Check what type of imported_target it is
get_target_property(type ${imported_target} TYPE)
if(NOT type STREQUAL "SHARED_LIBRARY")
# We only add rpaths to shared library
# Technically EXECUTABLE could also be linked against
# TODO: Are there rpaths in static library and do they propagate
# TODO: Is there some handling to do for `INTERFACE_LIBRARY`/`OBJECT_LIBRARY`?
return()
endif()
# Get the library file location
get_target_property(location ${imported_target} LOCATION)
# Take the parent directory
cmake_path(GET location PARENT_PATH location)
# Get the relative path w.r.t.
cmake_path(RELATIVE_PATH location
# scikit-build-core: provide `mocked_wheel_install_dir` pointing to the
# `wheel.install-dir` in the build environment
BASE_DIRECTORY ${mocked_wheel_install_dir}
)
# Invert the path from CMAKE_INSTALL_LIBDIR to `wheel.install-dir`
set(path_to_wheel_install_dir ".")
cmake_path(RELATIVE_PATH path_to_wheel_install_dir
BASE_DIRECTORY ${CMAKE_INSTALL_LIBDIR}
)
# Construct the rpath needed by the
cmake_path(APPEND rpath
"${path_to_wheel_install_dir}"
"${location}"
)
cmake_path(NORMAL_PATH rpath)
# We add `origin_symbol` at the end to not interfere with cmake_path
set(rpath "${origin_symbol}/${rpath}")
set_property(TARGET ${requesting_target} APPEND
PROPERTY INSTALL_RPATH "${rpath}"
)
# TODO: How to handle the windows PATH?
endfunction()
Probably mocked_wheel_install_dir would be passed as a cache variable?
Patching current project being build
For python bindings, constructing the RPATH is not that difficult since it's just $ORIGIN/${CMAKE_INSTALL_LIBDIR}, and I am not sure how to provide a clean interface for this. Maybe having a scikit_build_install_python_module helper? But then how do we get the current build's install path?
The more difficult part would be project.scripts entry points for wrappers or compiled binaries, i.e. something like
import subprocess
def run():
subprocess.call(
["@CMAKE_INSTALL_BINDIR@/@name@"]
)
Handling Window's PATH
WIP: No idea right now
The issue I am thinking of solving is to have a way to inject some
LD_LIBRARY_PATHorPATHso that it accounts for the path discrepancy of CMake installed files undersite_packagesandbin/Scriptslocation. I am considering two distinct cases hereLinking to dependencies
Writing the logic to create the appropriate RPATH for a dependency can be quite tricky, but maybe we can provide some helper functions. The key part is that within
scikit-build-corewe have better information of if a dependency is coming from the python dependencies, and what the relative paths between the root of the dependency and the final installation path includingwheel.install-dirare.For the user interface, I was thinking of providing a CMake function to handle an imported target and append an appropriate
INSTALL_RPATH. Here is a prototypeprototype
Probably
mocked_wheel_install_dirwould be passed as a cache variable?Patching current project being build
For python bindings, constructing the RPATH is not that difficult since it's just
$ORIGIN/${CMAKE_INSTALL_LIBDIR}, and I am not sure how to provide a clean interface for this. Maybe having ascikit_build_install_python_modulehelper? But then how do we get the current build's install path?The more difficult part would be
project.scriptsentry points for wrappers or compiled binaries, i.e. something likeHandling Window's PATH
WIP: No idea right now