/ Adam's Pile of Hacks / blog

Building rtl-sdr and friends for Windows in January 2020

January 5, 2020

Just a quick write up of what I’ve done to get rtl-sdr and kalibrate-rtl building for Windows.

TL;DR: Builds can be found at my releases page, interesting Dockerfiles are rtlsdr builder and kalibrate builder

Choosing a build environment

I initially tried MSYS2, but I wasn’t able to get things working properly. I forgot to write down what went wrong, but I may revisit it.

I knew Fedora had a pretty complete set of mingw64 packages, so it was my next choice. I also wanted to automate the builds somewhat - you can check out the GitHub links above to see how that was done.

Where to start

Getting this working was a two step process - build librtlsdr and then build kalibrate-rtl. kalibrate-rtl is a utility that will attempt to ‘calibrate’ your RTL based receiver by finding local cell tower frequencies. There is a build from 2015 floating around but this didn’t work with my dongle.

Step 1

From the rtlsdr dockerfile, you can see it’s not particularly complicated (thank you, Osmocom contributors!). There’s a pretty amazing setup provided by the mingw-filesystem package that means I can call mingw-cmake and have things happen without having to mess around with environment variables and paths.

Step 2

This is where it got a bit more fiddly. After working out what the bootstrap script wanted (autoconf, automake, libtool), I got some errors about Windows.h not being found. It seems like the Windows build was set up to build on Windows itself, and as such wasn’t expecting a case sensitive filesystem. Symlinking windows.h and Windows.h got around this.

The second problem was right at the end of the build, it’d bail out and complain about not being able to find -lrt - librt. I really have no idea what this library does, but it doesn’t exist on Windows or MinGW. I’m lucky that hacking it out with sed worked because I don’t want to learn autotools unless I really have to.

Step 3

Figuring out the dependencies was only slightly annoying. At one point I was using ldd to find everything but I’m not sure if it was on Linux or Windows. If anyone knows a better way of collecting up DLLs at the end of a build script, let me know via this blog specific email address.

One problem that threw me for a loop was a crash in a couple of the utilities - in cmd.exe they would just silently exit with no error, in Explorer they’d pop up with the following error:

The application was unable to start correctly (0xc000007b)

That 0xc000007b error means that a DLL didn’t load correctly, and in this case means that a 32 bit DLL loaded where a 64 bit DLL was expected. What?

Many, many Windows issues can be solved by staring at procmon for a long time - this one’s no exception.

procmon showing libwinpthread-1.dll being loaded from my OneDrive folder instead of where I expected

See that DLL load? I had it in my path for something else and because of the wonky way Windows loads DLLs, it was being picked up as I was missing libwinpthread-1.dll in the application folder. Sigh.

With everything built it was just a matter of setting up a GitHub release and writing this post.


Thank you to drone.io and packet.net for providing extremely fast build infrastructure for open source projects. I’m not being paid to write this - drone.io is free for my usage, but I did once receive promo credit from packet.net for a blog post I still feel guilty about not finishing. Last I looked, builds were running on monster AMD Epyc boxes.