How to Build Debian Packages with Meson/Ninja

Bare minimum binaries…

Selam G.
Published in
5 min readMay 8, 2021

--

Author’s Note: To my regular readers, sorry, I know this differs from my usual content and I’m supposed to be a hardware engineer, but this was sooOOO000 frustrating and I had to figure it out myself so I am giving back to the stackoverflow-answer-ers and authors-of-medium-blog-posts-about-very-specific-software-issues, because I have read A TON of those. Plus, dealing with rando firmware issues is an all too frequent struggle for hardware engineers. Of course, I’m also not paywalling it for the same reason, to give back to the community after reading many similar posts trying to figure out weird problems like this. Vive la Open Source (yes, I know, the whole thing is dripping with irony).

I know that only like 5 people in the world will appreciate this, but for those people it will mean tHe woRLd the way similar posts have affected me 😅 wow, community ❤

Perhaps you, like me, are a mechanical engineer or mechatronics engineer who regularly gets roped into firmware tasks. Let’s say someone gave you a nifty lil software package built with meson/ninja, but oh no, you need at minimum a .deb binary package for versioning/ease of installation, etc.

I say this both to give a big internet hug to my fellow startup-y multiple-hat-wearing ME’s, and also to note that I have not now nor ever claimed to be a *~*~Real Software Engineer*~*~, so this is intended to get you from 0 to 1, not 1 to 100. Gotcha?

Not recommended for production (but we’ve all put something like this into production, don’t lie.)

Building Debian Binaries from Meson/Ninja

Most unfortunately, this is gonna be a lot more manual than checkinstall -i or make -j4 .

I highly recommend reviewing this Unix&Linux StackExchange post which I bookmarked and poured over endlessly while trying to figure this out. It’s just about how to build Debian packages generally, something I knew nothing about (and it’s short, unlike my rambling):

0. Go on an’ gechyo Debian build tools…

sudo apt-get install debhelper build-essentials dh-make
  1. Then, make sure you’ve built your packages already with meson build.
  2. If you’re not already, cd into your directory — this being the top level folder where your meson.build is located, not necessarily where your executable is if you initially did something like meson build --prefix=/somewhere/else/ when prototyping.
  3. Now, you’ll need to dh_make --createorig .

Answer the questions with ‘s’ for single package and ‘Y’ to accept.

Debian wants your package names in a certain format. If the folder name is not properly formatted or you get this error:

For dh_make to find the package name and version, the current directory
needs to be in the format of <package>-<version>. Alternatively use the -p flag using the format <name>_<version> to override it.
The directory name you have specified is invalid!

then you should do something like dh_make --createorig -p example_0.0.1

4. Run dh_auto_configure --buildsystem=meson and wait for the process to finish. This is a key feature to support meson/ninja build systems that was only recently rolled into debhelper 12, so make sure you have the right debhelper version if there are errors.

5. dh_make generates the debian/control /compatetc. files for the package building process. You may wish to edit these after auto_configure. See ‘Troubleshooting’ below for when to edit debian/rules.

6. Finally, you’re ready for dpkg-buildpackage -rfakeroot -us -uc -b to build the .deb (the -bflag builds the binary only).

I shamelessly stole this idea from: https://medium.com/@galaktyk01/how-to-build-opencv-with-gstreamer-b11668fa09c

Enjoy!

You did it! Congratulations. Packaging is a magical dark art I still don’t fully understand.

Note that this will set up directories to be installed with something like dpkg -i examplepack_0.0.1-arch.deb , and put stuff into /usr/local .

If you try to dpkg -x into a local folder, the executable will not run properly, even though your initial meson/ninja directories may have been configured to run locally. I thought I had done this incorrectly for two full days at first because of that small discrepancy.

Hopefully I lived up to my own standards:

Appendix: Troubleshooting

If you are failing tests and dependency checks, you may want to force the build by overriding both. Sometimes that can happen especially when the software was built on a PC but your target system is an embedded processor — certain tests can fail (such as display/camera checks) when some hardware is not present. Dependency checks can also fail for custom-built versions of libraries.

This is definitely not recommended for production, but hey, the world is yours to burn.

You can override tests by changing #5 above to:

DEB_BUILD_OPTIONS='nocheck' dpkg-buildpackage -rfakeroot -us -uc -b

And you can override dependency checks by formatting your rulesfile thusly:

%:
dh $@

override_dh_shlibdeps:
dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info

Do not copy/paste the above, because rules is finicky and you have to make sure those spaces just before dh_shlibdeps are actually a single tab key— you may also need to delete any enter key whitespace (I think shift+enter should be okay). Don’t be afraid to try reformatting whitespace a couple times if you get errors related to debian/rules. It may look more like this if you otherwise didn’t edit the file generated by dh_make :

# see ENVIRONMENT in dpkg-buildflags(1)
# package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
%:
dh $@
# dh_make generated override targets
# This is example for Cmake (See https://bugs.debian.org/641051 )
#override_dh_auto_configure:
# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
override_dh_shlibdeps:
dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info

--

--