Dynamic linking

If you want to support dynamic linkages between python projects or system libraries, you will likely encounter some issues in making sure the compiled libraries/python bindings work after the wheel is created and the python project is installed on the system. The most common issues are the missing hints pointing to where the runtime libraries are located, specifically RPATH on Linux and MacOS systems, and PATH/os.add_dll_directory on Windows systems. Here are some recommendations on how to address them. If you got here because a vendored dependency’s library landed in site-packages/bin or lib, see that FAQ entry for the specific fix.

Wheel repair tools

The per-platform wheel repair tools (auditwheel, delocate, delvewheel; see repairing wheels) bundle any dynamic libraries used and patch the libraries/python bindings to prioritize them. They rename each bundled library with a unique hash to avoid collisions if another package bundles the same library, and they do not allow cross-wheel library dependencies.

Manual patching

You can manually make a relative RPath. This has the benefit of working when not running scikit-build-core, as well.

The RPATH patching can be done as

if(APPLE)
  set(origin_token "@loader_path")
else()
  set(origin_token "$ORIGIN")
endif()
set_property(TARGET <target> PROPERTY INSTALL_RPATH
  "${origin_token}/install_path/to/dynamic_library"
)

For Windows patching, this has to be done at the python files using os.add_dll_directory at the top-most package __init__.py file or top-level python module files.

import os
from pathlib import Path

dependency_dll_path = Path(__file__).parent / "install_path/to/dynamic_library"
os.add_dll_directory(str(dependency_dll_path))