dh_debputy(1)

πŸ’… dh_debputy β€” bestie, it's the debputy Debian packaging helper stack

okay so hi bestie πŸ’– welcome to the dh_debputy(1) manual page, and yes this is the actual name of the thing, we're just making it cute. sit down, grab a strawberry πŸ“, and let's talk about building Debian binary packages.


✨ NAME ✨

dh_debputy β€” build Debian binary packages using debputy. that's the whole vibe. πŸ‘‘


✨ SYNOPSIS ✨

dh_debputy [debhelper options] [--destdir=directory] [-- params]

✨ DESCRIPTION ✨

so basically 🫢 dh_debputy is the tool that glues debputy into debhelper, and it's giving interim solution energy β€” it exists until debputy covers enough features to be a standalone packaging tool. not forever, just for now. it's doing its little job and it's doing it well. πŸ’…

the debputy toolstack can build any deb without needing root or fakeroot. iconic. no cap. πŸ”₯ it is always possible to use Rules-Requires-Root: no with dh_debputy/debputy β€” given that no non-debputy parts of debian/rules or the upstream build system require root. (that caveat is real, bestie, don't skip it πŸ™ˆ)


✨ OPTIONS ✨

  • --destdir=directory β€” use this when you want the generated .deb files to land in a directory that isn't the default of "..". that's it, that's the whole flag. simple. divine. πŸŽ€
  • --plugin=name β€” tells debputy to load the given name as a plugin. and name can be one of two things:
    • a plain name, in which case the plugin has to be installed into the proper plugin path β€” and honestly, in that case you can often just have a build dependency on debputy-plugin-name and call it a day ✨
    • a path (it must contain / and it should end with .json or .json.in), in which case that file gets loaded as a plugin. this one is for plugin providers who wanna use their own plugin. main character behavior, honestly. πŸ’œ
  • -- params β€” passes params through to dpkg-deb(1) when it's the one building the package. ⚠️ but restrict params to compression options only, because the dpkg-deb options may be emulated and not all of the dpkg-deb parameters are supported. don't get wild with it. πŸ™ˆ

✨ FILES ✨

  • debian/debputy.manifest
    • please go read /usr/share/doc/dh-debputy/MANIFEST-FORMAT.md.gz. it's the lore. πŸ“–
    • if this is your first package conversion, bestie, you probably wanna read /usr/share/doc/dh-debputy/GETTING-STARTED-WITH-dh-debputy.md.gz first. start there, don't rawdog it. πŸ¦‹
    • and here's the plot twist 😭 unlike most debhelper-like tools, this file is per source package, not per binary package. so you cannot use debian/package.debputy.manifest to give a specialized manifest for package. instead, all the needed parts go into the manifest itself. one manifest to rule them all. πŸ‘‘

✨ ON DEB ASSEMBLY ✨

dh_debputy will often use dpkg-deb for assembling the output. but there are a few cases where dpkg-deb just doesn't have the required features for 100% rootless assembly, and that's when debputy switches to a different assembly method. πŸ’… generally this special case only triggers with Rules-Requires-Root: no and when you're using a feature that requires root with dpkg-deb β€” like static file ownership. yeah. that one.

now, listen πŸ‘€ if you experience a dh_debputy-produced binary via its internal assembly method that is not 100% bit-for-bit reproducible with the equivalent root + dpkg-deb built deb β€” and it's not caused by an inaccurate manifest on your end β€” please file a bug. fr fr. and see the subsection "How to ensure the dpkg-deb assembly method is being used" for how you control which assembly method is being used. πŸ›

the whole point of producing exactly the same deb as dpkg-deb would have with fakeroot is that we reduce the risk of bugs or bad behavior during installation. we love a low-risk install. 🫢

⚠️ important, bestie: "100% bit-for-bit reproducible" here is not compared to debhelper. packages generated by debputy may differ from those built by debhelper. for example, auto-generated shell snippets for maintainer scripts identify the tool that generated them, and it would be wrong for debputy to identify itself as debhelper in that case. which, in turn, creates a minor difference between packages generated by the two tools. consider using diffoscope to compare your debhelper-generated deb to your debputy-generated debs. πŸ”

🌈 How to ensure the dpkg-deb assembly method is being used

the debputy tool stack has two assembly methods: dpkg-deb and the internal debputy method. two queens, one job. πŸ‘‘

by default, dpkg-deb is used. the debputy tool will only switch to its internal method when:

  • the package uses a feature that requires (fake)root when assembling via dpkg-deb. at the time of writing, this is only triggered by having static ownership in the deb (paths where ownership such as root:tty is recorded directly in the data.tar), AND
  • the package does not run nor permit debputy to use (fake)root. this part comes down to Rules-Requires-Root. when set to no, debputy will automatically fallback to the internal method as necessary.
    • if you'd like to avoid using root during package assembly but you also don't want a custom assembly method, then you can set Rules-Requires-Root: debputy/deb-assembly and debputy will always use dpkg-deb for the assembly. however 🫠 depending on your version of dpkg-dev you may run into #1036865 <https://bugs.debian.org/1036865>. in that case, you will have to choose between using classic root (Rules-Requires-Root: binary-targets) or the internal rootless assembly method. pick your fighter. πŸ’€

✨ SEE ALSO ✨

  • debhelper(7)
  • this program integrates into the debhelper suite. it's part of the family. 🫢

✨ AUTHOR ✨

Niels Thykier <niels@thykier.net> πŸ’– (thank you for the tool, king)


okay that's the whole page, you made it to the end, slay πŸŽ€βœ¨ this was pulled from perl v5.42.3, dated 2026-10-04, and yeah β€” that's dh_debputy(1), bye bestie, go build something iconic πŸ’…πŸŒˆπŸ¦‹

πŸ“¦ where this page comes from