Skip to content

Commit 9ef98f8

Browse files
committed
Document dynamic linking
Signed-off-by: Cristian Le <git@lecris.dev>
1 parent beea6ea commit 9ef98f8

File tree

3 files changed

+73
-1
lines changed

3 files changed

+73
-1
lines changed

docs/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090

9191

9292
intersphinx_mapping = {
93+
"cmake": ("https://cmake.org/cmake/help/latest/", None),
9394
"python": ("https://docs.python.org/3", None),
9495
"packaging": ("https://packaging.pypa.io/en/stable", None),
9596
"setuptools": ("https://setuptools.pypa.io/en/latest", None),
@@ -99,7 +100,7 @@
99100
val[0]
100101
for key, val in intersphinx_mapping.items()
101102
# Only works with RTD hosted intersphinx
102-
if key not in ("hatchling", "python")
103+
if key not in ("hatchling", "python", "cmake")
103104
]
104105

105106
nitpick_ignore = [

docs/guide/dynamic_link.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Dynamic linking
2+
3+
If you want to support dynamic linkages between python projects or system
4+
libraries, you will likely encounter some issues in making sure the compiled
5+
libraries/python bindings work after the wheel is created and the python project
6+
is installed on the system. The most common issue are the missing hints pointing
7+
to where the runtime libraries are located, specifically `RPATH` on Linux and
8+
MacOS systems, and `PATH`/`os.add_dll_directory` on Windows systems. Here are
9+
some recommendations on how to address them.
10+
11+
## Link to the static libraries
12+
13+
The easiest solution is to make sure you link to the static libraries
14+
counterparts during the CMake build. How to achieve this depends on the specific
15+
dependency, how it is imported in the CMake project and how the dependency is
16+
packaged in each ecosystem.
17+
18+
For example for [Boost][FindBoost] this is controlled via the variable
19+
`Boost_USE_STATIC_LIBS`.
20+
21+
[FindBoost]: inv:cmake:cmake:module#module:FindBoost
22+
23+
## Wheel repair tools
24+
25+
There are wheel repair tools for each operating system that bundle any dynamic
26+
libraries used and patch the libraries/python bindings to point to prioritize
27+
those libraries. The most common tools for these are [auditwheel] for Linux,
28+
[delocate] for MacOS and [delvewheel] for Windows. [cibuildwheel] incorporates
29+
these tools in its [repair wheel] feature.
30+
31+
One downside of these tools is that all dependencies are duplicated and bundled
32+
in each project.
33+
34+
[auditwheel]: https://pypi.org/project/auditwheel/
35+
[delocate]: https://pypi.org/project/delocate/
36+
[delvewheel]: https://pypi.org/project/delvewheel/
37+
[cibuildwheel]: https://cibuildwheel.pypa.io/en/stable/
38+
[repair wheel]:
39+
https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command
40+
41+
## Manual patching
42+
43+
For maximum control, you can do the equivalent patching inside CMake manually.
44+
This is not recommended because it does not have access to the python
45+
environment metadata.
46+
47+
The `RPATH` patching can be done as
48+
49+
```cmake
50+
if(APPLE)
51+
set(origin_token "@loader_path")
52+
else()
53+
set(origin_token "$ORIGIN")
54+
endif()
55+
set_property(TARGET <target> PROPERTY INSTALL_RPATH
56+
"${origin_token}/install_path/to/dynamic_library"
57+
)
58+
```
59+
60+
For Windows patching, this has to be done at the python files using
61+
`os.add_dll_directory` at the top-most package `__init__.py` file or top-level
62+
python module files.
63+
64+
```python
65+
import os
66+
from pathlib import Path
67+
68+
dependency_dll_path = Path(__file__).parent / "install_path/to/dynamic_library"
69+
os.add_dll_directory(str(dependency_dll_path))
70+
```

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ first Friday of every month at the same time. Our past meeting minutes are
2929
3030
guide/getting_started
3131
guide/cmakelists
32+
guide/dynamic_link
3233
guide/crosscompile
3334
guide/migration_guide
3435
guide/build

0 commit comments

Comments
 (0)