Skip to main content

Wrap ldd *nix utility to determine shared libraries required by a program.

Project description

pylddwrap

Build Status Coverage MIT License PyPI - version PyPI - Python Version Documentation Status

Pylddwrap wraps ldd *nix utility to determine shared libraries required by a program.

We need to dynamically package subset of our system at deployment time. Consequently, we have to determine the dependencies on shared libraries of our binaries programmatically.

The output of ldd Linux command, while informative, is not structured enough to be easily integrated into a program. At the time of this writing, we only found two alternative ldd wrappers on Internet python-ldd and ldd.py, but their output was either too basic for our use case or the project was still incipient.

Pylddwrap, in contrast, returns a well-structured list of the dependencies. The command-line tool outputs the dependencies either as a table (for visual inspection) or as a JSON-formatted string (for use with other tools). The included Python module lddwrap returns a Python object with type annotations so that it can be used readily by the deployment scripts and other modules.

For more information on the ldd tool, please see ldd manual.

Usage

Command-Line Tool pylddwrap

  • Assume we need the dependencies of the /bin/ls. The following command gives them as a table:

pylddwrap /bin/ls
  • The output of the command looks like this:

soname          | path                                  | found | mem_address          | unused
----------------+---------------------------------------+-------+----------------------+-------
linux-vdso.so.1 | None                                  | True  | (0x00007ffd8750f000) | False
libselinux.so.1 | /lib/x86_64-linux-gnu/libselinux.so.1 | True  | (0x00007f4e73dc3000) | True
libc.so.6       | /lib/x86_64-linux-gnu/libc.so.6       | True  | (0x00007f4e739f9000) | False
libpcre.so.3    | /lib/x86_64-linux-gnu/libpcre.so.3    | True  | (0x00007f4e73789000) | False
libdl.so.2      | /lib/x86_64-linux-gnu/libdl.so.2      | True  | (0x00007f4e73585000) | False
None            | /lib64/ld-linux-x86-64.so.2           | True  | (0x00007f4e73fe5000) | False
libpthread.so.0 | /lib/x86_64-linux-gnu/libpthread.so.0 | True  | (0x00007f4e73368000) | False
  • To obtain the dependencies as JSON, invoke:

pylddwrap --format json /bin/ls
  • The JSON output is structured like this:

[
  {
    "soname": "linux-vdso.so.1",
    "path": "None",
    "found": true,
    "mem_address": "(0x00007ffed857f000)",
    "unused": false
  },
  ...
]

ldwrap Python Module

We provide lddwrap Python module which you can integrate into your deployment scripts and other modules.

  • The following example shows how to list the dependencies of /bin/ls:

import pathlib
import lddwrap

path = pathlib.Path("/bin/ls")
deps = lddwrap.list_dependencies(path=path)
for dep in deps:
    print(dep)

"""
soname: linux-vdso.so.1, path: None, found: True, mem_address: (0x00007ffe8e2fb000), unused: None
soname: libselinux.so.1, path: /lib/x86_64-linux-gnu/libselinux.so.1, found: True, mem_address: (0x00007f7759ccc000), unused: None
soname: libc.so.6, path: /lib/x86_64-linux-gnu/libc.so.6, found: True, mem_address: (0x00007f7759902000), unused: None
...
"""
  • List all dependencies of the /bin/ls utility and check if the direct dependencies are used. If unused for list_dependencies is set to False then the unused variable of the dependencies will not be determined and are therefore unknown and set to None. Otherwise information about direct usage will be retrieved and added to the dependencies.

import pathlib
import lddwrap

path = pathlib.Path("/bin/ls")
deps = lddwrap.list_dependencies(path=path, unused=True)
print(deps[1])
# soname: libselinux.so.1,
# path: /lib/x86_64-linux-gnu/libselinux.so.1,
# found: True,
# mem_address: (0x00007f5a6064a000),
# unused: True
  • Lddwrap operates normally with the environment variables of the caller. In cases where your dependencies are determined differently than the current environment, you pass a separate environment (in form of a dictionary) as an argument:

import os
import pathlib
import lddwrap

env = os.environ.copy()
env['LD_LIBRARY_PATH'] = "some/important/path"
path = pathlib.Path("/bin/ls")
deps = lddwrap.list_dependencies(path=path, env=env)

Installation

  • Install pylddwrap with pip:

pip3 install pylddwrap

Development

  • Check out the repository.

  • In the repository root, create the virtual environment:

python3 -m venv venv3
  • Activate the virtual environment:

source venv3/bin/activate
  • Install the development dependencies:

pip3 install -e .[dev]

We use tox for testing and packaging the distribution. Assuming that the virtual environment has been activated and the development dependencies have been installed, run:

tox

Pre-commit Checks

We provide a set of pre-commit checks that lint and check code for formatting.

Namely, we use:

  • yapf to check the formatting.

  • The style of the docstrings is checked with pydocstyle.

  • Static type analysis is performed with mypy.

  • Various linter checks are done with pylint.

Run the pre-commit checks locally from an activated virtual environment with development dependencies:

./precommit.py
  • The pre-commit script can also automatically format the code:

./precommit.py  --overwrite

Versioning

We follow Semantic Versioning. The version X.Y.Z indicates:

  • X is the major version (backward-incompatible),

  • Y is the minor version (backward-compatible), and

  • Z is the patch version (backward-compatible bug fix).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pylddwrap-1.0.1.tar.gz (10.0 kB view details)

Uploaded Source

File details

Details for the file pylddwrap-1.0.1.tar.gz.

File metadata

  • Download URL: pylddwrap-1.0.1.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.0 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.5.2+

File hashes

Hashes for pylddwrap-1.0.1.tar.gz
Algorithm Hash digest
SHA256 171a39fc7feb33e607706c57c08373ceb2f6fd4362af9241ccc65e80c948ccdf
MD5 e86461f9d3bffc7b82687052303ce84a
BLAKE2b-256 e7e15ff0cbb7f06a7b1bdde316d0437c9c34600db64e07e46db5e70fec1a2f6a

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page