Python packaging wrapper for the links_and_nodes C/C++ library and Python bindings
Project description
links_and_nodes
links_and_nodes GPLv3 release. library is released under the terms of LGPLv3.
all tested with debian buster & stretch
how to build
if you are at DLR-RMC, please read README.RMC.md for RMC-specific build instructions.
otherwise first check whether there is a premade build script for your distribution:
ls scripts/build_*
if so, try running it with the option -h first.
it will leave an ln_env.sh script in your INSTALL_PREFIX-folder which you can source in your shell-init
scripts to "activate" that LN-install. as the help-output shows, the INSTALL_PREFIX is given as argument
to the scripts/build_* script.
example:
$ sudo scripts/build_ubuntu22.04.sh /usr/local
then add to your ~/.bashrc:
source /usr/local/ln_env.sh
see the following instructions if you cannot use any of these build scripts.
dependencies
to build the library, daemon and python binding:
-
compiler requirement:
LN requires a C compiler with C99/GNU99 support. The build system compiles the C library as GNU99. On Linux systems with futex support, libln's shm v3 synchronization also relies on GCC/Clang-compatible atomic intrinsics. The distro build scripts install GCC/G++, which satisfies this requirement on all supported Linux platforms.
-
common for debian and ubuntu systems:
$ sudo apt-get update
$ sudo apt-get install scons libtool autoconf libprocps-dev coreutils dash file g++ git gzip libacl1 libncurses5-dev libselinux1 libtomcrypt-dev libtommath-dev locales make patch sed tar wget
- additions for debian stretch, buster
$ sudo apt-get install python-sphinx libboost-python-dev python-numpy iproute2
- additions for debian bullseye
$ sudo apt-get install python3-sphinx python3-dev libboost-python-dev python3-yaml python3-numpy
- additions for ubuntu 18.04
add the "universe" repository to your /etc/apt/sources.list, it might look like this:
deb http://de.archive.ubuntu.com/ubuntu bionic main universe
$ sudo apt-get update
$ sudo apt-get install sphinx-doc sphinx-common python-dev libboost-python-dev
- additions for ubuntu 20.04
add the "universe" repository to your /etc/apt/sources.list, it might look like this:
deb http://de.archive.ubuntu.com/ubuntu focal main universe
$ sudo apt-get update
$ sudo apt-get install sphinx-doc sphinx-common python-dev libboost-python1.67-dev
- arch linux (2020-03-25)
$ sudo pacman -S scons libtool autoconf procps-ng coreutils dash file gcc git gzip acl boost ncurses libtomcrypt libtommath make patch sed tar wget python2-numpy python-sphinx
libstring_util
you can get libstring_util from https://gitlab.com/links_and_nodes/libstring_util or https://rmc-github.robotic.dlr.de/common/libstring_util
$ cd /path/to
$ git clone .../libstring_util.git
$ cd libstring_util
$ autoreconf -if
$ mkdir build; cd build
$ ../configure --prefix=/usr/local
$ make
$ sudo make install
links_and_nodes
$ cd /path/to
$ git clone --recursive .../links_and_nodes.git
$ cd links_and_nodes
$ scons --prefix=/usr/local
$ sudo scons --prefix=/usr/local install
this will build the library, python binding and the daemon and install them
to /usr/local.
you can specify a different target with the option --prefix=/home/user/my_local.
but be careful to always specify an absolute path as prefix!
depending on which install-prefix and python version you chose, you might want to add this to your e.g. ~/.bashrc file:
export LN_PREFIX=/usr/local
export PATH=$LN_PREFIX/bin:$PATH
export LD_LIBRARY_PATH=$LN_PREFIX/lib:$LD_LIBRARY_PATH
# for debian and related:
export PYTHONPATH=$LN_PREFIX/lib/python3/dist-packages:$PYTHONPATH
# for suse, ARCH:
export PYTHONPATH=$LN_PREFIX/lib/python3/site-packages:$PYTHONPATH
# cmake cfg for libln
export CMAKE_PREFIX_PATH=$LN_PREFIX/lib/cmake/:$CMAKE_PREFIX_PATH
(not needed if you install to --prefix=/usr)
optional runtime dependencies
to start the ln_manager gui:
- debian, ubuntu18.04, ubuntu20.04
$ sudo apt-get install openssh-client python-gi gir1.2-gtk-3.0 gir1.2-vte-2.91
- arch
$ sudo pacman -S openssh python2-gobject gtk3 vte3
to start notebooks (pygtksvnb):
- newer debian's
$ sudo apt-get install gir1.2-gtksource-4 python-matplotlib
- debian stretch
$ sudo apt-get install gir1.2-gtksource-3 python-matplotlib
- ubuntu18.04
$ sudo apt-get install gir1.2-gtksource-3.0 python-matplotlib
- ubuntu20.04
$ sudo apt-get install gir1.2-gtksource-4
$ wget https://bootstrap.pypa.io/pip/2.7/get-pip.py -O get-pip.py
$ python get-pip.py --force-reinstall
$ python -m pip install pyparsing matplotlib
- arch
$ sudo pacman -S gtksourceview4 python-matplotlib
TODO: currently no working Gtk3 OpenGL widget found for pyscopes!
how to test your installation
to test the python binding:
$ python -c "import links_and_nodes as ln; print 'ok'"
ok
to test the ln_manager:
$ ln_manager --help
2015-11-05 13:50:29.73 info Manager: $Id: Manager.py 20622 2013-10-01 13:12:52Z schm_fl $
usage: ln_manager [-h] [-i instance_name] [-p PORT] [--log-level LEVEL] -c configuration_file
-h show this usage info and exit
...
to test notebooks:
$ python -m pyutils.pygtksvnb.notebook
further reading
please read the incomplete $LN_documentation/links_and_nodes.md, have a look at those example ln-clients below examples/ and maybe grep for things of interest in my personal test cases libln/tests.
the official API documentation is currently here:
- C-API: libln/include/ln/ln.h
- C++-API: libln/include/ln/cppwrapper.h
- python-API: python/links_and_nodes/_ln.cpp (have a look at the last function BOOST_PYTHON_MODULE() in that file) and python/links_and_nodes/ln_wrappers.py
- ln-config-file options: python/links_and_nodes_manager/SystemConfiguration.py
license issues
all of links and nodes but the ln-library is released with a GPLv3 license. the ln-library is released with a LGPLv3 license - by that you can dynamically link libln.so into your non-GPL compatible binaries (needed header files use a non-copyleft BSD license).
Python packaging
You can install liblinks_and_nodes from PyPI using pip install liblinks-and-nodes.
The package ships a Python wrapper (python_pkg/) that builds the C/C++ library
via SCons during pip install and installs the compiled .so, public headers,
and bundled data into site-packages/liblinks_and_nodes/{lib,include,share}.
Quick start
# Install the package (builds C/C++ library via SCons on-the-fly)
# You can pass -vv to activate verbose mode
uv pip install .
# Or install from PyPI
pip install liblinks-and-nodes
# Locate the installed library, headers and share directory
python -m liblinks_and_nodes lib
python -m liblinks_and_nodes include
python -m liblinks_and_nodes share
# Or programmatically
python -c "import liblinks_and_nodes; print(liblinks_and_nodes.list_library_files())"
Manager extra
Pre-built CI wheels always include the manager and ln_daemon. If you are
installing from PyPI or CI artifacts, the manager is already included —
no extra flags needed.
To also build the ln_daemon binary and the links_and_nodes_manager GUI package
when installing from source:
pip install '.[manager]' -C with-manager=true
# Or with uv:
# Full package, with ln manager, ln daemon and file sync
uv pip install ".[manager]" -vv -C with-manager=true
PyGObject (gi) must be installed via your system package manager:
- Debian/Ubuntu:
apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0 - Fedora:
dnf install python3-gobject gtk3 - Arch:
pacman -S python-gobject gtk3
Testing the packaging locally
All commands below use uv (install via
curl -LsSf https://astral.sh/uv/install.sh | sh).
Full manylinux wheel build (matches CI)
Requires Docker. Reads [tool.cibuildwheel] from pyproject.toml.
The CI pipeline passes with-manager=true through CIBW_CONFIG_SETTINGS,
so the resulting wheels are always "full" (include manager + ln_daemon).
# Build all Python versions (3.10–3.14), full wheels (include manager + daemon)
CIBW_CONFIG_SETTINGS="with-manager=true" \
uvx --python 3.12 cibuildwheel --platform linux
# Or a single version
CIBW_BUILD="cp312-manylinux_x86_64" \
CIBW_CONFIG_SETTINGS="with-manager=true" \
uvx --python 3.12 cibuildwheel --platform linux
Note: you can set CIBW_BUILD_VERBOSITY=3 for debugging
To build base-only wheels (no manager/daemon), omit CIBW_CONFIG_SETTINGS.
Wheels land in wheelhouse/.
Quick smoke test (no Docker)
# Build a platform-specific "full" wheel (matches CI, includes manager + daemon)
uvx --from build pyproject-build --wheel --outdir dist/ \
--config-setting with-manager=true
# Or base-only (no manager/daemon):
# uvx --from build pyproject-build --wheel --outdir dist/
# Install into a fresh uv-managed venv
uv venv /tmp/test_venv
uv pip install --python /tmp/test_venv/bin/python dist/*.whl
# Smoke-check the installed package
/tmp/test_venv/bin/python -m liblinks_and_nodes lib
/tmp/test_venv/bin/python -m liblinks_and_nodes include
/tmp/test_venv/bin/python -c "import links_and_nodes; print('import OK')"
Test sdist round-trip
The sdist is identical regardless of whether the final build includes the manager or not — the flag is only needed at install time.
uvx --from build pyproject-build --sdist --outdir dist/
tar xzf dist/liblinks_and_nodes-*.tar.gz -C /tmp/
# Base install (default):
uv pip install --python /tmp/test_venv/bin/python /tmp/liblinks_and_nodes-*/
# Full install (with manager + daemon):
uv pip install --python /tmp/test_venv/bin/python \
--config-settings with-manager=true /tmp/liblinks_and_nodes-*/
Verify wheel content
unzip -l wheelhouse/*.whl | grep -E '\.so|liblinks_and_nodes|links_and_nodes/'
Upload to PyPI (wheels + sdist)
The following produces all artifacts (manylinux wheels for every Python
version plus a source distribution) in a single dist/ directory, then
uploads them with twine.
1. Build manylinux wheels
Requires Docker. Reads [tool.cibuildwheel] from pyproject.toml.
Wheels are "full" (include manager + daemon) to match CI output.
CIBW_CONFIG_SETTINGS="with-manager=true" \
uvx --python 3.12 cibuildwheel --platform linux --output-dir dist/
2. Build the source distribution
uvx --from build pyproject-build --sdist --outdir dist/
3. Check the artifacts
ls -lh dist/
# Expect: one .whl per Python version (cp310, cp311, cp312, cp313, cp314)
# one .tar.gz (source distribution)
4. Upload to TestPyPI (dry run, uses a separate token)
export TWINE_USERNAME="__token__"
export TWINE_PASSWORD="pypi-<your-testpypi-token>"
uv tool run --from twine twine upload --repository testpypi dist/*
Visit https://test.pypi.org/project/liblinks-and-nodes/ to verify the listing.
5. Upload to production PyPI
export TWINE_USERNAME="__token__"
export TWINE_PASSWORD="pypi-<your-production-token>"
uv tool run --from twine twine upload dist/*
Token setup: Generate API tokens at https://pypi.org/manage/account/token/ (production) and https://test.pypi.org/manage/account/token/ (TestPyPI). Never hardcode tokens — always use environment variables or a
.netrcfile.
CI wheel builds
The GitLab CI pipeline (.gitlab-ci.yml) automatically builds manylinux_2_28
wheels and an sdist when a tag is pushed. Wheel jobs run in parallel
(one per Python version 3.10–3.14) inside Docker-in-Docker using
cibuildwheel. The package stage collects all artifacts into dist/
for download.
To trigger a wheel build locally on the default branch, use:
# Requires Docker
CIBW_CONFIG_SETTINGS="with-manager=true" \
uvx --python 3.12 cibuildwheel --platform linux
The resulting wheels are "full" (include manager + daemon) and "thin":
only libln.so and Python packages are
vendored. External shared-library dependencies (libboost_python*.so from
cmeel-boost, libstring_util.so from libstring_util) are excluded from
the wheel and provided by their own PyPI wheels at install time.
For manylinux wheels with daemon support, auditwheel may bundle system
libraries that are not on the manylinux allowlist, such as libprocps and
its runtime dependency chain. The wheel build copies the corresponding RPM
license/notice files and source-package references into
liblinks_and_nodes/share/third_party_licenses/.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file liblinks_and_nodes-2.8.2a0.tar.gz.
File metadata
- Download URL: liblinks_and_nodes-2.8.2a0.tar.gz
- Upload date:
- Size: 4.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0594172b2817a413bcf822295bf0fa32eca993d6a38c2c6996fa7cdf777223f3
|
|
| MD5 |
5d1dde3df3887ceac44748b39da4d826
|
|
| BLAKE2b-256 |
dd8f66a7d7fa20bf66cdd7e3333789149f50bb5cf1a398b00cccdb92a6dd03ad
|
File details
Details for the file liblinks_and_nodes-2.8.2a0-cp314-cp314-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: liblinks_and_nodes-2.8.2a0-cp314-cp314-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.6 MB
- Tags: CPython 3.14, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
743acff2a4be59d22e9fd8824b297743d3956193f4e4488e3ccdcbffa4aa7253
|
|
| MD5 |
c7326f1003923f591c28540b56b98380
|
|
| BLAKE2b-256 |
b43840045c6da125082ff3567ffa1efdf4896356c5feb14a7887a9493582f6ca
|
File details
Details for the file liblinks_and_nodes-2.8.2a0-cp313-cp313-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: liblinks_and_nodes-2.8.2a0-cp313-cp313-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.6 MB
- Tags: CPython 3.13, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f1572e942f11c4c865f1387ea6891369a896f166bcd560d387776a8107de4ec
|
|
| MD5 |
4a0422091400ca16df93b77b1389132e
|
|
| BLAKE2b-256 |
61b3d412fb7621159a9b373f7188874135e3f2c38b9153ed0164bc648e8f6ca7
|
File details
Details for the file liblinks_and_nodes-2.8.2a0-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: liblinks_and_nodes-2.8.2a0-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.6 MB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e137817f4aca70f1b85a16f6db2419827408de4e0dac4288fd5964824b188895
|
|
| MD5 |
99e41366db93b65ffd356dfc457facdc
|
|
| BLAKE2b-256 |
79c4aba68fe7e227b5439029310899a67dfc276eb8c47194c41fd17aa466e6eb
|
File details
Details for the file liblinks_and_nodes-2.8.2a0-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: liblinks_and_nodes-2.8.2a0-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.6 MB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e057326e394179fee90058b5b8b15701bbc288ea605e2aae1105d0cc3e7579a7
|
|
| MD5 |
341538cb90965d49717b18225207fff5
|
|
| BLAKE2b-256 |
3b504ec568fdf1d1f366fb8233da4dad5e866bcd2d6e39c1750bf0c426de9752
|
File details
Details for the file liblinks_and_nodes-2.8.2a0-cp310-cp310-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: liblinks_and_nodes-2.8.2a0-cp310-cp310-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 13.6 MB
- Tags: CPython 3.10, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6c2ddf32f131011b9e4662a6a47e1847ec1b09cfe55f933fd2b166645d38a8c
|
|
| MD5 |
645a587ec923f4c3a3b8950bbeb48b4b
|
|
| BLAKE2b-256 |
66e0e9bfa1fd7862a7b802277dbe6f2548c2abcec6a3d77accc0f433bb77619a
|