Skip to content

Latest commit

 

History

History
270 lines (196 loc) · 9.33 KB

File metadata and controls

270 lines (196 loc) · 9.33 KB

Installing libpathrs

At the moment, libpathrs is not packaged for most distributions:

Library Packaging Status Rust Crate Packaging Status
Library Packaging Status Rust Crate Packaging Status

and so it is often necessary to build and install it from source.

Downloading a Release

Official release tarballs are available from our releases page. Each release contains:

  • A source tarball (libpathrs-$version.tar.xz) with a detached GPG signature (.asc).
  • A vendored copy of the Rust dependencies (libpathrs.vendor.tar.zst) with a detached GPG signature (.asc).
  • A (legacy) inline clear-signed checksums file (libpathrs.sha256sum).

Verifying the Release Signature

All official releases are signed with a key present in libpathrs.keyring in the source tree. If this is your first time verifying a release, you can get the keyring from the source repository or from a previously verified release tarball.

$ # Import the libpathrs release keyring into a temporary keyring.
$ tmp_gpgdir="$(mktemp -d)"
$ gpg --homedir="$tmp_gpgdir" --no-default-keyring \
      --keyring=libpathrs.keyring --import libpathrs.keyring

$ # Verify individual artefact signatures.
$ gpg --homedir="$tmp_gpgdir" --no-default-keyring \
      --keyring=libpathrs.keyring \
      --verify libpathrs-$version.tar.xz.asc libpathrs-$version.tar.xz

Build Dependencies

libpathrs is written in Rust and requires a working Rust toolchain. The minimum supported Rust version (MSRV) is 1.63, though we recommend using the latest stable release.

Rust Toolchain

Most Linux distributions ship cargo and rustc packages:

Distribution Command
Debian / Ubuntu apt install cargo rustc
Fedora dnf install cargo rust
openSUSE zypper install cargo rust
Arch Linux pacman -S rust

Distribution-packaged Rust versions may be quite old -- make sure yours ships at least Rust 1.63. If it doesn't, use rustup instead:

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

After installing, make sure ~/.cargo/bin is in your $PATH.

Other Build Dependencies

You will also need GNU make, clang, and lld.

Distribution Command
Debian / Ubuntu apt install build-essential clang lld
Fedora dnf install make clang lld
openSUSE zypper install make clang lld
Arch Linux pacman -S base-devel clang lld

Building

$ tar xf libpathrs-$version.tar.xz
$ cd libpathrs-$version
$ make release

This produces both libpathrs.so and libpathrs.a under target/release/.

On some architectures, rustc will include additional linker flags that are not supported by lld. In order to work around this issue, you may need to explicitly specify clang as the linker driver:

$ make release EXTRA_RUSTC_FLAGS="-C linker=clang"

Vendored / Offline Builds

If you have the vendored dependencies tarball (for offline builds), extract it and point Cargo at it:

$ tar xvf libpathrs.vendor.tar.zst
$ mkdir -p .cargo
$ cat >.cargo/config.toml <<EOF
[source.crates-io]
replace-with = "vendored-sources"

[source.vendored-sources]
directory = "vendor"
EOF
$ make release

Installing

install.sh is a fairly minimal installation script that accepts a subset of autoconf-style arguments and generates a corresponding pkg-config manifest that is also installed. This should be sufficient for most users, but very specialised installation environments may need to come up with their own installation methods.

$ ./install.sh --prefix=/usr --libdir=/usr/lib64

For distribution packaging with a staging root:

$ ./install.sh DESTDIR=$BUILDROOT \
      --prefix=/usr --libdir=/usr/lib64

make install is just shorthand for ./install.sh --prefix=/usr/local and we recommend you use install.sh directly.

If installing onto your host system, you should run sudo ldconfig after installation so the link loader will pick up the new library.

lib vs lib64

install.sh tries to autodetect whether to install into lib or lib64 under the exec-prefix by checking whether a lib64 directory exists on the host system. This heuristic doesn't always get it right -- some systems have a dummy lib64 that is not included in the paths handled by ldconfig, and the check for lib64 ignores DESTDIR so cross-distribution install.sh invocations are likely to break. You should always pass --libdir explicitly if there's any doubt about the correct path for your distribution:

  • Fedora, openSUSE, RHEL (64-bit): /usr/lib64
  • Debian, Ubuntu, Arch Linux: /usr/lib (or /usr/lib/x86_64-linux-gnu on multiarch Debian/Ubuntu)

install.sh Options

Flag Default Description
--prefix /usr/local Installation prefix
--exec-prefix $PREFIX Executable prefix
--includedir $PREFIX/include Header file directory
--libdir $EPREFIX/lib or lib64 Library directory (autodetected)
--pkgconfigdir $LIBDIR/pkgconfig pkg-config .pc file directory
--rust-target native Rust target triple (for cross-compilation)
--rust-buildmode release Rust build profile to install from
DESTDIR / Staging root (for distribution packaging)

Python Bindings

The Python bindings for libpathrs are available on PyPI:

pip install pathrs

If you need to build the bindings from source (for distribution packaging or development), read on.

Building from Source

The bindings live in contrib/bindings/python/ and use CFFI in API mode to link against libpathrs.so. You'll need Python >= 3.9, cffi, setuptools, and the build frontend:

Distribution Command
Debian / Ubuntu apt install python3-dev python3-cffi python3-build python3-wheel
Fedora dnf install python3-devel python3-cffi python3-build python3-wheel
openSUSE zypper install python3-devel python3-cffi python3-build python3-wheel
Arch Linux pacman -S python python-cffi python-build python-wheel

If libpathrs.so and pathrs.h are already installed on the system, building is straightforward:

$ cd contrib/bindings/python
$ python3 -m build

PATHRS_SRC_ROOT

When packaging for a distribution, it may be more natural to build the Python bindings in the same build script as the main libpathrs.so library, meaning that pathrs*.whl will be built without libpathrs.so having been installed on the host. As a workaround for this, you can set PATHRS_SRC_ROOT to point at the libpathrs source tree (which must have been already compiled):

$ # Build libpathrs.so first.
$ make release

$ # Then build the Python bindings against the source tree.
$ cd contrib/bindings/python
$ PATHRS_SRC_ROOT=/path/to/libpathrs python3 -m build

This tells the CFFI build script to find pathrs.h in $PATHRS_SRC_ROOT/include/ and libpathrs.so in $PATHRS_SRC_ROOT/target/{debug,release}/ (it prefers whichever was built more recently). Without PATHRS_SRC_ROOT, the build assumes a system-wide install and will fail if the header or library isn't found.

Installing

$ pip3 install contrib/bindings/python/dist/pathrs*.whl

make -B contrib/bindings/python install is shorthand for the above command.

At runtime, libpathrs.so must be in the dynamic linker search path (installed system-wide via ldconfig, or reachable via LD_LIBRARY_PATH).

Using libpathrs

C

Use pkg-config to get the right compiler and linker flags:

gcc -o myprogram myprogram.c $(pkg-config --cflags --libs pathrs)

Or in a Makefile:

CFLAGS  += $(shell pkg-config --cflags pathrs)
LDFLAGS += $(shell pkg-config --libs pathrs)

Python

import pathrs

with pathrs.Root("/path/to/rootfs") as root:
    with root.resolve("/etc/passwd") as handle:
        with handle.reopen("r") as f:
            for line in f:
                print(line.rstrip("\n"))