Home / Alt manpages / dpkg-shlibdeps(1)

  • dpkg-shlibdeps(1)
  • User command
  • linux

Generate Debian Library Dependencies with dpkg-shlibdeps

You will finish with a Debian package build step that inspects an ELF executable, finds the shared libraries it needs, and writes a dependency such as libc6 (>= 2.34) into a substvars file. The examples match dpkg 1.22.6 from dpkg-dev 1.22.6ubuntu6.6, installed on this machine.

Allow about fifteen minutes. You need a Debian source tree with debian/control, an already-built executable, and the dpkg-dev package. These commands normally run as your build user. They do not need sudo and should not be run as root merely to make dependency discovery work.

1. Check the installed tool

Run the version check from an ordinary shell:

$ dpkg-shlibdeps --version
Debian dpkg-shlibdeps version 1.22.6.

The command takes one or more executable paths. It reads the ELF binaries, maps their shared libraries to Debian packages, and uses package-provided symbols or shlibs data to choose the dependency. It expects to be run in a package source tree, because the default output file is debian/substvars and it reads package metadata from debian/control.

Checkpoint

From the root of your source tree, confirm that the package metadata and binary exist:

$ test -f debian/control && echo 'control file: present'
$ test -x debian/example/usr/bin/example && echo 'binary: present'

Replace example and the executable path with the binary package and path used by your build. A successful test command prints the two confirmation lines; a missing line is a packaging-order problem to fix before calling dpkg-shlibdeps.

2. Preview the dependency without changing substvars

Use -O while checking a new build. It prints the generated substitution variables instead of updating debian/substvars:

$ dpkg-shlibdeps -O debian/example/usr/bin/example
shlibs:Depends=libc6 (>= 2.34)

Your output will depend on the binary and the installed package database. The useful shape is shlibs:Depends=..., not a fixed list of libraries. In the local probe, /bin/true produced the libc6 (>= 2.34) line after being run from a source tree with debian/control.

-O is a useful review checkpoint because shell redirection or a normal invocation is not needed. If you use -O with a filename, attach the filename to the option, for example -Odebian/dependency-preview; without a filename, standard output is used.

3. Write the result to the intended substvars file

Once the preview is correct, write to an explicit file so the destination is visible in the build recipe:

$ dpkg-shlibdeps -Tdebian/substvars debian/example/usr/bin/example
$ grep '^shlibs:' debian/substvars
shlibs:Depends=libc6 (>= 2.34)

The -T form takes the substvars path directly after the option. The default destination is debian/substvars, so omitting -T normally selects that same file. The command removes existing variables using the selected prefix before writing the newly calculated values. That is useful in a clean build, but it can surprise you in a hand-maintained file.

Do not overwrite a file containing unrelated local substitutions without checking it first. If you need to preserve a hand-edited file, preview with -O, or choose a separate generated path and make the packaging step consume that path deliberately. If you wrote an unwanted generated file, restore it from version control or remove only that file after checking that no later build step needs it. Do not delete the whole debian directory.

4. Supply dependencies to the right control field

The default dependency field is Depends. Use -d before an executable when another field is genuinely required, and remember that the setting applies to following executables until another -d option:

$ dpkg-shlibdeps -O \
    -dPre-Depends debian/example/usr/sbin/example
shlibs:Pre-Depends=libc6 (>= 2.34)

Do not choose Pre-Depends just to make a dependency look stronger. It changes unpacking order and should reflect a real package requirement. If the same dependency appears in several recognised fields, dpkg-shlibdeps removes weaker duplicates and keeps it in the more important field.

For a package that builds several binaries, pass them together or repeat -e. This keeps one generated dependency set for the analysed package:

$ dpkg-shlibdeps -O \
    debian/example/usr/bin/example \
    debian/example/usr/lib/example/plugin.so

Only include files that are part of the package being built. Analysing an arbitrary host executable can produce a plausible dependency while saying nothing useful about your package.

5. Add private library paths with -l

If the binary links to a private library in your build tree, add its directory with -l:

$ dpkg-shlibdeps -O \
    -l"$PWD/debian/example/usr/lib/example" \
    debian/example/usr/bin/example

The option prepends the directory to dpkg-shlibdeps' private-library search list. Use it instead of setting LD_LIBRARY_PATH for this build-time lookup. LD_LIBRARY_PATH also changes the run-time linker's behaviour and can hide cross-compilation or packaging mistakes.

If the library is built into another binary package, make sure that package's DEBIAN/shlibs or DEBIAN/symbols data exists before analysing the consumer. Use -S to search a particular package build directory first when several packages contain similarly named library variants. Use -xpackage to exclude a package when a binary or plugin would otherwise create a self-dependency.

6. Understand a shlibs file when dependency lookup fails

Symbols files give finer-grained minimum versions. A shlibs file is the simpler fallback or override: it maps a library name and SONAME version to a package dependency. Its entries contain one line per library:

# comment lines are allowed
libcrunch 1 libcrunch1 (>= 1.2-1)

Blank lines are not allowed. The first two fields are whitespace-delimited, and the dependency field continues to the end of the line. For libcrunch.so.1, the library field is libcrunch and the SONAME version is 1. The dependency should name the package version that supplied the newest symbols needed by the consumers.

For package-local overrides, dpkg-shlibdeps looks first at debian/shlibs.local, unless -L names another file. It also considers generated package-tree data, installed package data, and the system default file. A local override can conceal a bad library package, so use it as an intentional packaging decision and keep the reason in your source tree.

7. Diagnose errors before weakening the check

A missing library produces a message such as couldn't find library ... needed by .... Check the binary's RPATH, the private directory passed with -l, the package build order, and whether the library has the expected SONAME. Run with -v to see directories and dependency files being considered:

$ dpkg-shlibdeps -v -O debian/example/usr/bin/example
$ printf 'exit status: %s\n' "$?"
exit status: 0

A no dependency information found error means the library was located but no usable symbols or shlibs record was found. Fix the library package or build order. --ignore-missing-info exists, but the manual discourages it: suppressing the error can publish a package that installs successfully and fails later when a required library is absent.

Warnings about an unused linked library are a separate quality signal. Remove an unnecessary linker flag when practical. Do not silence warnings by changing dependency fields; that changes package metadata without fixing the binary.

Done means

  • dpkg-shlibdeps --version matches the dpkg-dev version you are targeting.
  • The command runs from a source tree with a valid debian/control and a built package binary.
  • You previewed the generated shlibs:Depends value with -O.
  • You wrote to the intended substvars file only after reviewing the preview.
  • Private libraries use -l, not a build-time workaround with LD_LIBRARY_PATH.
  • Missing symbols or shlibs data is fixed or understood, rather than hidden with --ignore-missing-info.