System designTroubleshooting

dpkg -S no path found: fix shared library package deps

Fix 'no path found matching pattern' from dpkg -S when packaging a vision SDK: query the shared library by soname, add the runtime deps, or skip the step.

LumaSpec Vision10 min read Share on LinkedIn

On this page 10 sections
  1. 01What the error string actually tells you
  2. 02The two-command test
  3. 03Cause 1 — the helper asks for the wrong string
  4. 04Cause 2 — the library never came from a package
  5. 05Worked example: the camera deb's seven dependencies
  6. 06Skip it on purpose: the single-machine case
  7. 07When a fleet makes repackage worth fixing
  8. 08Prove it before rollout
  9. 09The decision
  10. 10Questions

Your machine-vision SDK builds cleanly, make package produces the component debs, and make repackage dies with dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libstdc++.so.6. Nothing is wrong with the library and nothing is missing from the system. A helper script resolved each shared-object dependency to a full path and asked dpkg for that exact string, and dpkg's database does not record it.

This guide is for engineers packaging Linux vision software — SDKs for frame grabbers and 3D cameras, GigE tools — for deployment on vision controllers and industrial PCs. You will separate the causes behind that error, fix the query so repackage completes, add the runtime packages that genuinely are absent, and decide when skipping the step is the correct call.

What the error string actually tells you

no path found matching pattern is dpkg-query's exact answer when the argument matches no recorded path in its database. It is not 'file missing' and it is not 'library broken'.

The build log shows the sequence. The script listed the deb's dependencies before resolution — libglog.so.0, libstdc++.so.6, libxmlrpc++.so.8, ld-linux-x86-64.so.2, libgcc_s.so.1, libxmlrpc_client++.so.8, libc.so.6 — then resolved each one to a full path such as /lib/x86_64-linux-gnu/libstdc++.so.6 and queried that string with dpkg -S.

Two behaviors collide. An argument containing a slash is matched against the database as an exact path, and symlinked directories are recorded nowhere. On a system where /lib is a symlink into /usr/lib, one physical file answers to both prefixes, but the owning package's file list holds only one of them. Query the other prefix and dpkg answers 'no path found' — with the library sitting right there.

The two-command test

Run these two lines before changing anything:

  1. dpkg-query -S '/lib/x86_64-linux-gnu/libstdc++.so.6' — the leading slash means exact-path matching, so this reproduces the failure whenever the database records the other prefix.
  2. dpkg-query -S 'libstdc++.so.6' — no slash means substring matching, so every recorded path containing the soname comes back, for example libstdc++6:amd64: /usr/lib/x86_64-linux-gnu/libstdc++.so.6.

The split is the diagnosis. Command 2 names an owner: the query is wrong, and cause 1 is yours. Command 2 also comes back empty: the file never came from a package, and cause 2 is yours. Quote the argument; the ++ needs no escaping once quoted.

Cause 1 — the helper asks for the wrong string

Ubuntu 19.04, the first release shipped with /usr merged by default, is where this bites hardest: /lib is a symlink into /usr/lib, and package file lists were mid-migration between the two prefixes. Exact-string queries then fail for whichever prefix a given package does not use. That also explains the dead end of reordering LD_LIBRARY_PATH: resolution follows the loader, the database follows the package, and no loader order changes either.

The fix is one line in the helper — strip the directory, keep the soname:

so="/lib/x86_64-linux-gnu/libstdc++.so.6"
dpkg-query -S "${so##*/}"
# libstdc++6:amd64: /usr/lib/x86_64-linux-gnu/libstdc++.so.6

For the Depends field, filter the hits: keep the runtime package (libstdc++6), drop its -dev sibling that owns the unversioned libstdc++.so symlink, and drop any -dbg variants. Add a version constraint only when you rely on the newer ABI: libstdc++6 (>= 11) installs nowhere that still runs GCC 10-era libraries, so an over-tight constraint turns a working build into a refused install on the target.

Cause 2 — the library never came from a package

libglog.so.0 and the libxmlrpc++ sonames are the usual suspects here: build either from source once, and make install drops it into /usr/local/lib, where dpkg never looks. The bare-soname query then returns nothing for a file that exists and loads fine.

Confirm it with two facts: the bare-soname query returns no owner, and dpkg -l | grep glog shows no installed package. Then install the distribution's runtime package. On the Ubuntu 18.04 and 19.04 generation that is libglog0v5 for libglog.so.0, and libxmlrpc-c++8v5 for both libxmlrpc++.so.8 and libxmlrpc_client++.so.8. The 0v5 and 8v5 suffixes belong to those releases and move on newer ones, so run the query first and install what the query names instead of copying package names between machines. Rerun the queries afterwards: every soname must return an owner before repackage will complete.

Worked example: the camera deb's seven dependencies

The build log for the camera component deb gives a complete input set: the deb ships one SDK library and depends on seven shared objects — libglog.so.0, libstdc++.so.6, libxmlrpc++.so.8, ld-linux-x86-64.so.2, libgcc_s.so.1, libxmlrpc_client++.so.8, libc.so.6. The rule in words: the Depends field must name the runtime package owning every non-loader soname, and it must never name libc, because libc6 is an Essential package present on every dpkg-based system.

depends = owners(sonames) - {libc.so.6, ld-linux-x86-64.so.2}

The arithmetic: 7 sonames − 2 loader and libc entries = 5 queries. The five bare-soname queries return these owners:

  • libstdc++.so.6 → libstdc++6
  • libgcc_s.so.1 → libgcc1
  • libglog.so.0 → libglog0v5
  • libxmlrpc++.so.8 → libxmlrpc-c++8v5
  • libxmlrpc_client++.so.8 → libxmlrpc-c++8v5, the same package, so 5 sonames collapse to 4 packages

Decision rule, with its threshold: if all five queries return an owner, the original error was the query string, and fixing the helper to search basenames completes repackage. If any query returns nothing, that library came from a source install — install the distribution runtime package, or vendor your own build into a deb of its own, then repackage. Either way, seven log entries reduce to a four-package line you could have written by hand.

Skip it on purpose: the single-machine case

Repackaging is bookkeeping, not building. The target unwraps each generated deb, lists its shared-object dependencies, writes a Depends field into the control file and repacks. The log already told you the stakes: it printed CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies once per component — four times — before repackage ever ran, so the plain debs declare nothing anyway. On one machine that is a detail, not a defect. Skip the target and install the runtime packages by name:

sudo apt-get install libstdc++6 libgcc1 libglog0v5 libxmlrpc-c++8v5
sudo apt install ./*.deb

If the install succeeds but the SDK still cannot grab frames, you have moved to a different layer: Linux vision shared library errors: diagnose missing dependencies hunts loader errors at run time, and frame grabber initialization failure: fix firmware and runtime covers the device-opening stage after that.

When a fleet makes repackage worth fixing

Unattended installs, offline media and mixed releases lean on correct Depends metadata, so there the step earns its keep. Two paths beat debugging the script:

  • Hand-write the Depends fields per component with the four-package line from the worked example. Ten minutes, fully controlled.
  • Let CPack do it: the Debian generator exposes CPACK_DEBIAN_PACKAGE_SHLIBDEPS, which runs dpkg-shlibdeps over the built binaries and writes the Depends fields itself. That retires the hand-rolled helper and the exact-string problem together.

Build on the release you deploy. The failure above began as a release mismatch — an SDK supported only on long-term-support releases, built on a short-lived desktop release — and a build container pinned to the deploy release removes the mismatch permanently. Camera SDK header not found in a containerized build sets up that container, and Docker build SDK version mismatch: pin one library version everywhere handles the version pinning. A library upgrade on the build machine causes the same class of failure months later; fixing camera SDK build errors after a library upgrade walks that case.

If the target is an embedded Yocto image rather than Ubuntu, dpkg is not the packaging layer at all; shared-library development on a Yocto SDK explains how that SDK carries its libraries.

Prove it before rollout

  1. dpkg -I on each deb prints the control file. After a fixed repackage, the Depends line lists the four runtime packages; after a deliberate skip, it is empty, and the deploy script must carry the explicit apt install.
  2. Rehearse in a clean container of the deploy release: fresh image, install the debs, run the grab sample. Anything missing announces itself on the first run instead of in the field.
  3. Then go to hardware: the SDK must open the device and stream. When one tool grabs and another fails on the same host, the fault is in SDK and driver support, not packaging — frame grabber SDK support: why one viewer works and another fails maps that layer.

The decision

Case Test Fix
Bare-soname query names an owner dpkg-query -S 'libstdc++.so.6' returns libstdc++6:amd64 Fix the helper: query the basename, keep runtime packages
Bare-soname query returns nothing dpkg -l shows no owning package Install libglog0v5 or libxmlrpc-c++8v5, or vendor your own deb
One machine, no fleet No Depends needed Skip make repackage, install with apt
Fleet or offline media Depends must be exact CPACK_DEBIAN_PACKAGE_SHLIBDEPS, or hand-written Depends

For a single development machine, the shortest correct path is skip-and-install: the four runtime packages by name, then the debs through apt. For a fleet, fix the query or hand the job to CPACK_DEBIAN_PACKAGE_SHLIBDEPS. For a soname nobody owns, install the distribution package or wrap your build in its own deb.

If you would rather not maintain a packaging pipeline at all, deploy onto vision controllers that arrive with their runtime installed and licensed; the vision controller category lists the range. The MV-VC3301H-128G66 pairs an Intel Core i3-8100 with 8 GB of memory and a 128 GB SSD, and includes the VM6200Pro runtime licence.

Vision controllersHikrobot MV-VC3301H-128G66 I3-8100, 8GB+128G SSD, No PoE, PCIe expansion supported, Incl. VM6200Pro licenseMV-VC3301H-128G66
LAN ports
5+ LAN ports
USB 3 ports
3-4 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$2,419.00View partBuild a system with it

Where the cameras hang off dedicated hardware instead of the host NIC, frame grabbers take the stream directly; the frame grabber finder filters them by interface and port count, and the system configurator pairs the host with the cards and the light channels it drives.

Stuck on a specific SDK or release? Contact us with the SDK name, the Ubuntu release and the failing component, and we will tell you which cause you are in. More Linux-side fixes sit in the Learn hub, and the systems topic page collects this class of build and integration errors.

Questions

Does skipping make repackage break anything?

Repackaging only rewrites the Depends fields of debs your build already produced. Skip it and the debs still install and run on one machine, provided you install the runtime libraries yourself or let apt pull them. What you lose is metadata: on a managed fleet or an offline install, an undeclared dependency set is how version skew hides until the first failed deployment.

Why does dpkg -S return several packages for one library?

Without a leading slash, dpkg-query runs a substring search, so libstdc++.so.6 also matches the -dev package's unversioned symlink and any debug variants. For a Depends line keep the runtime package only: the name without -dev, -dbg or a compiler-version suffix. On Ubuntu that makes libstdc++6:amd64 the owner recorded for libstdc++.so.6.

How do I find the owning package of any shared library?

For an installed file, run dpkg-query -S with the bare name, for example dpkg-query -S 'libglog.so.0'. For a library you have not installed yet, apt-file search answers the same question across the whole Ubuntu archive; install apt-file and run apt-file update once before the first search. Either way the output names the runtime package to put on the Depends line.

Should I install the debs with dpkg -i or apt?

Use apt whenever the debs declare dependencies: sudo apt install ./*.deb resolves the Depends lines from the archive in one pass. dpkg -i resolves nothing, so an unsatisfied dependency stops the install halfway and leaves packages half-configured; sudo apt --fix-broken install cleans that state up. For dependency-free debs on a prepared machine, dpkg -i is fine.

Why must libc.so.6 stay off the Depends line?

libc6 is an Essential package, so every dpkg-based system already has it and the tools never generate a dependency on it. The same filter covers the dynamic loader ld-linux-x86-64.so.2, which libc6 ships. Listing them manually adds bulk to every control file and changes nothing; spend the effort on the five libraries that actually vary between build and target.