Building RTKLIB code in Linux

In my last post I described building the RTKLIB code in Windows. In this post I will describe building the code in Linux. Unlike for Windows, pre-built executables are not available for either the demo5 or the official 2.4.3 versions of RTKLIB, so building your own code is more of a necessity on this platform.

I have built Linux versions of RTKLIB on both a PC running Ubuntu and on a Raspberry Pi and will describe these experiences. My description may be somewhat specific to these platforms but I believe the process should be very similar on any other Linux system.

The original RTKLIB did not support Linux for the GUI apps but a few years ago Jens Reimann created a version using Qt that supports Linux as well. Those changes are now in both the demo5 and the 2.4.3 versions of RTKLIB and I will describe building these on the Ubuntu platform below.

Building the RTKLIB CUIs on a Raspberry Pi

Let’s focus on just the CUI (Character User Interface) RTKLIB apps for the Pi since the GUIs apps are probably not a good choice for this hardware. We’ll start with just compiling a single app. I will assume that you are connected to a headless Pi through an SSH window and that the Pi is already connected to the internet.

In this case, the following set of commands should be all you need to build RTKRCV, the real-time app for generating RTK or PPP solutions.

git clone
cd RTKLIB/app/rtkrcv/gcc

The first line pulls the source code from the Github repository, the second line gets you into the Linux build folder for RTKRCV, and the third line builds the code. The default compiler warning threshold is pickier than for Windows, so you will see some warning messages but you can ignore these. You can build the STR2STR, CONVBIN, RNX2RTKP, and POS2KML in the same way by changing the app name in the second line.

Most likely, the only two apps you would be using on the Pi would be the real-time apps, either RTKRCV or STR2STR. However if you would like to build all five CUI apps with a single command you can run “make” from the /RTKLIB/app folder.

If you do get any build errors it is most likely going to be because you are missing one of the build tools. However I have found that if you are using one of the standard releases of Debian Linux for the Pi, this should not be a problem.

Building the RTKLIB CUIs and GUIs on an Ubuntu PC

In this case I am building the code with Ubuntu 20.04 on a Linux partition on a Windows PC, but I don’t think other platforms should be very different.

Before building either the CUIs or the GUIs you will most likely need to update your build tools. I used the following commands to resolve various build errors I ran into when I started with a fresh installation of Ubuntu 20.04

sudo apt-get update
sudo apt install build-essential
sudo apt-get install libpng-dev
sudo apt-get install qt5-default libqt5serialport5-dev

The first line may not be necessary, it just updates the package lists for the following commands. The second line installs the most common build tools, the third line installs the “png” library, and the last line installs the Qt tools.

Once the tools are installed, you can build the CUI apps using the same process I described above for the Pi.

The GUI apps require the core code be built first before the individual apps, so it is easiest to build all the apps at once rather than one at a time. You can do this with the following commands.

git clone
cd RTKLIB/app
cd ..

The first line pulls the source code from Github and is not necessary if you have already done this to build the CUIs. The second line gets you to the app folder in the RTKLIB code where the third line creates a makefile for the Qt apps. The fourth line gets you back to the top level folder where the fifth line creates the makefile for the full build process. The last line builds all the CUI and GUI apps.

It will take a fairly long time to build everything the first time but if you make any changes to the code, these will usually compile much faster. You will also see many warning messages which you can ignore. To rebuild all the apps, you only need to run the last line. Alternatively, after you have run the full process once, you can run “make” from any of the app folders to rebuild just that app.

Note that this process will overwrite the makefile in the RTKLIB/app folder that we used to build just the CUIs in the earlier step, so if you use this process, you won’t be able to build just the CUI’s as a group anymore.

I have tested these Qt GUI apps only briefly but they seem to be functional. However, the GUI interface does not include some of the config parameters added to the demo5 code that are not in the official 2.4.3 code. I believe as a partial workaround, you can most likely update the config file and load it to the GUI to configure these parameters but I have not actually tested this. The core code is shared between all the apps, so as long as the interface is working, the code behavior should not be different regardless of which app or which version of it you are running.

Please add a comment below if you have any corrections or suggested improvements to the process I have described.

[Update 6/23/21: Jens Reimann has recently merged the b34 changes into his fork of RTKLIB which does support the Qt GUIs. I have pulled his set of Qt build files into the demo5 code. The demo5 Qt GUIs now build and are reasonably functional but will still require some updating to include the config parameters unique to the demo5 code. RTKCONV and RTKPOST appear to be working fine but I notice that RTKPLOT does not seem to be fully functional in either his version or the demo5 version. My bandwidth to support this platform is fairly limited so I would be happy to accept pull requests to the demo5 code for any Qt related fixes and improvements.

The build instructions have changed slightly to work with his code

cd app/qtapp

[Update 1/19/21: Version b34 of the official 2.4.3 RTKLIB code has just been released. It is a major rewrite of the user interface and the changes have not been incorporated into the Qt files. The Qt files are still in the repository but are planned to be dropped in the next release since they are no longer functional. I will be following the lead of the 2.4.3 code in the demo5 version, so unless this changes, the Qt code will not have any future in either codebase. Other readers have reported success using WINE to run the Windows executables, so for those who don’t need to build custom versions of the code, this might be a better choice.]

37 thoughts on “Building RTKLIB code in Linux”

  1. Hello and many thanx for all the work you did, especially around ublox! I spend a lot of time starting from official library and trying to get nice results comparing to an emlid solution. After switching to your optimized library, I now get a correct position even if my base localization is a disaster (sort of balcony on a building ;-)). By correct I understand very close to what I get from the emlid module (“let’s not be more royalist than the king” – I don’t know if this expression exists but, as you can read, English is not my mother language :-()

    My next job is now to use a public base network ( but can apply to any of this sort) in mobility. My purpose is to select automatically the closest moutpoint available (I know it could be not the better but I prefer to start with a simple case :-)).
    For this I’d like to know if there is an easy way to always get an output from “rtkrcv”, even in the worst conditions (well, after getting a position of course :-)).
    What I’ve in my mind is to periodically get list of mountpoints, sort them by distance (easy) from the current position and, if trigger say ok, switch to the new mountpoint (if differ :-)) by changing config file and restart. That’s why I need the position…

    Sure, I can start in “single” mode then switch but there is maybe a smarter solution…

    Thanks for comments


    1. As long as the “out-outsingle” option in the config file is set to “on”, then you should be getting position output in rtkrcv, even when the solution is only single mode.


      1. Hello and sorry for my late reply 😉
        Well, you’re right, I just test it, changing to a wrong passwd my connection with the ntripcaster and, even if I cannot reach it, I get a position… much less stable (of course), but I get a position!
        So I know can go to my mounting point selection step 🙂


  2. Hello and thank you for the detail content about RTKLIB!
    I am using the RNX2RTKP app in an Linux Server environment for processing data for a GNSS receiver in PPP-Static mode. Everything is working fine but I want to check the contribution of Ocean Tide Loading (OTL) correction for my location. I have downloaded the BLQ file for my location from here ( and I have added the path in the rnx2rtkp config file as file-blqfile , exactly as it is mentioned in rtklib manual. I have set the tides correction on, but the RNX2RTKP doesnot seem to look for this file. Moreover I want to add, that I do not have this issue while loading the ERP file, and when the file directory is wrong I get an error message on the terminal. Also the solid earth tides correction is running normal.

    Has anyone faced the same issue with the CUI version of RTKPOST before?
    Thank you in advance 🙂


  3. Thanks on behalf of Linux users !
    I succeeded to compile in Linux Mint 19.3, with some fixes.
    The process has slightly changed (from readme.txt file) :
    GUIs (Qt based):
    1) cd app/qtapp
    2) qmake
    3) make
    4) ./install_qtapp

    Furthermore, due to some changes to the last versions of the compiler, the programs created are considered as libraries by the system (and not ELF). So one needs to add the following to .qmake.stash file (hidden file !) :
    QMAKE_CFLAGS += -no-pie
    QMAKE_CXXFLAGS += -no-pie
    QMAKE_LFLAGS += -no-pie -fPIC

    I tried for now Rtknavi, which works fine, but title and legend are missing on satellite bars window.


    1. cd to the relevant app path for instance /home/GitFolder/RTKLIB/app/rtkpost_qt. Then invoke RTKPOST by typing ./rtkpost_qt

      You can also invoke it directly by ./home/GitFolder/RTKLIB/app/rtkpost_qt/rtkpost_qt at the prompt


  4. Hi Tim,
    As many posted before me – excellent material.
    I have been using the QT binaries from Emlid on Ubuntu 18 for a while but I have a need for CUI so I came across your post on building it on Linux.
    However, I came across a issue where the Emlit RTLIB version (B33) is able to solve a data set (almost 100% Q=1) where as the rnx2rtkp that I got by following the build instructions here simply gave Q=0 for the entire data. I used the exact same input OBS and NAV files and also the same config file using the -k flag. I didn’t get any errors during the build process or during the run. It simply returned Q=0.

    Would you (or anyone else 🙂 ) happen to have a pointer?
    Appreciate it


    1. Incidentally, building from here resulted in a float solution, again using exactly the same input files and config file. One additional observation is that the Emlid Qt RTKPOST binary (b33) ran significantly faster on the same ubuntu 18.04 machine, i.e. Qt version ran for roughly 90 sec while the CLI executable ran for over 10 minutes on the same data.


        1. Hi Gideon. In general, the Emlid and demo5 versions of RTKLIB are very close to each other and should give very similar results. I was not able to duplicate the problem you saw with the demo5 code using the data you sent me but am hoping we can figure out what is going on if you can send me the config file you used for your testing.


          1. Hi,
            First of all, amazing blog, you are a reference in the GPS sector….

            I have a terrible problem: I have compiled the demo5 github in Linux pretty well, no problem at all.
            After that, I have tested the AP str2str to send ntrip correction to my zed-F9P GPS, and perfect, I can see how the light signals in the GPS indicates me that it is receiving the ntrip correction. For doing that, I write in the console this line:

            str2str -in ntrip://user:passwd@ -out serial://ttyACM0:9600

            As you can see in the command line, I am “capturing” the serial port, so, now I cannot use rtkrcv or the GPS itself because the serial port is used by the str2str….

            I have been looking for a solution , but I dont know how to take now the GPS signal….
            Can anybody help me?

            Thanks a lot

            Rafael Chao


          2. Hi Rafael. Add a “#1000” to the end of the line to redirect the incoming serial stream to TCP/IP port 1000 as shown below or you can use any other port number. You can then use this TCP/IP port as in input to RTKRCV or another instance of STR2STR

            str2str -in ntrip://user:passwd@ -out serial://ttyACM0:9600#1000

            By the way, from the mount point name in your example, it looks like you may be using a VRS (Virtual Reference Station) stream which will only start streaming corrections after you provide it the approximate location of your receiver with an NMEA GGA message. STR2STR can be set up to do this with the -n (nmea request cycle) and -p (position) options as described in the manual. For example:

            str2str -in ntrip://user:passwd@ -p 41.500 100.100 0.0 -n 1 -out serial://ttyACM0:9600#1000


          3. Great comment !!!!!

            Lets try to add some more value !!!
            I read in the manual, that instead of using the command -p to indicate the position, we can use the command “-b 1” so str2str will take the position from the gps automatically….

            str2str -in ntrip://user:passwd@ -p 41.500 100.100 0.0 -n 1 -out serial://ttyACM0:9600#1000

            We an use:
            str2str -in ntrip://user:passwd@ -b 1 -out serial://ttyACM0:9600#1000

            Please notice that we got rid of the command “-n 1” as well….

            In the first command, it can interested for a base station.

            The second command is more interesting to be used in the rover.

            Thanks to all of you !!!!


  5. Tim, Thx again for the Linux build instructions, it seems to have worked well!

    Do you have any suggestions for an easy way to test RTKNAVI to make sure it’s just getting a basic solution (i.e., non RTK mode)? I’d like to be able to do a quick test with recorded data, and then maybe via streamed data as well. I looked through you blog posts, but didn’t see any on just how to do a quick, non-RTK verification test on RTKNAVI.

    My reason for asking is that I’m messing around with building GNSS-SDDRLIB (Ubuntu and Win10) and trying to get it to stream RTCM3 to RTKNAVI for a solution, but having issues so I want to verify my RTKNAVI build is solid.

    Thx much!



    1. Hi Don. If you just configure the rover input to RTKNAVI (no base), and set the Positioning mode in the Options menu to “Single”, RTKNAVI will give you a standard precision solution. If you are using recorded data inputs to RTKNAVI, be sure to enable “Time Tags” both when recording the data and when playing it back. The time tags can be a little tricky, so it’s sometimes easier to avoid post-processing with RTKNAVI.


      1. Thanks Tim, that helps. Unfortunately I can’t quite configure the F9P to emulate the GNSS-SDRLIB output (RTCM 1019, 1077) because it turns out I can’t config the F9P to output 1019. But your suggestion helps, I can still test basic functionality of RTKNAVI to make sure it seems to be working. Thx again, Don


  6. Hello Tim. Recently I have been doing tests with Reach M2 (Rover) and a ZED-F9P (Base) module integrated to an MCU with RTKLIB CUI str2str.
    I have not obtained FIX solutions
    str2str -in serial: // ttyS0: 115200 # ubx -out serial: // ttyS1: 9600 # rtcm3 -p -13.541239941 -40.64661978 220.35 -msg “1006, 1074, 1084, 1094,1124”
    Is there any recommendation for Reach M2?

    1 -msg “1006 (10), 1074 (5), 1084 (5), 1094 (5), 1124 (5)”

    2 -msg “1006 (1), 1074 (1), 1084 (1), 1094 (1), 1124 (1)

    3 -msg “1006 (10), 1074 (10), 1084 (10), 1094 (10), 1124 (10)”


    1. Hi Neilon. The Reach M2 uses a u-blox F9P so any of my recommendations for the F9P should work with the M2. Your STR2STR command line above is set up to convert messages to RTCM3 but this should not be necessary if you have the receiver configured to output RTCM3 messages already and may be causing problems. See the RTKLIB manual for more details. I would also suggest using the 10×7 MSM messages rather than the 10×4 messages since they contain a little more info, but this is probably not your problem. Also, check the M2 output to make sure the M2 is outputting 1006 base location messages. If it’s not configured properly, it won’t send out any 1006 messages and this will prevent getting a fix. This is a very common problem.


  7. Hi Tim,

    Great post. Do you expect that these instructions would also be applicable for macOS? There appears to be full support for Qt and Qt Serial Port as well as libpng on macOS.



    1. brew install qt

      cd RTKLIB/app
      cd ..

      Apps are in their directories
      rtkplot in RTKLIB⁩ ▸ ⁨app⁩ ▸ ⁨rtkplot_qt⁩
      rtknavi in RTKLIB⁩ ▸ ⁨app⁩ ▸ ⁨rtknavi_qt⁩



      1. Hi Yves,
        Trying to install RTKLIB in my ubuntu 18.04. I did install qt5-default. I run qmake but I could not. No makefile is created. I have my qmake installed at /usr/lib/qt5/bin/qmake

        Nothing is created under running “qmake” inside
        cd RTKLIB/app

        Any help is appreciated


        1. Hi Yacob,

          The Qt code has not been well maintained in the 2.4.3 or demo5 versions of RTKLIB and starting with version b34, the Qt make files were removed from the 2.4.3 code. I have followed suit and removed them from the demo5 code since the amount of work required to port the b34 changes into the Qt code would be significant. The b33 version of the demo5 code still has the Qt make files, builds, and is mostly functional, although some config options are not supported. Another option is the Emlid version of RTKLIB which is still at the b33 version, but more fully supports the Qt builds.


      1. I only tried the GUI versions, but I assume that command line versions will also run. The former work so well that it’s not clear why anyone would bother compiling for native linux.


        1. Hi Ken. Yes, apparently Tomoji and team have been very busy this past year. Their b34 commit has 1,064 changed files with 279,767 additions and 312,550 deletions! I just checked in a partial merge into a new branch on the rtklibexplorer repository. I will keep it here until it is more complete and stable. Currently RTKCONV, RTKPOST, CONVBIN, and RNX2RTKP appear to be functional in this branch. I haven’t had much chance to play with the new code but I am seeing noticeable improvements in both speed and performance, with lots of changes to better support the newer constellations. There’s also a lot of housekeeping changes that make the merge painful but should be helpful in the long term.


        2. And I forgot to say that I was able to build the _Qt versions under the latest Linux Mint, no issues.
          Thanks a lot for the Linux tutorial and work updating the _Qt stuff.


  8. Thanks for this post.

    I was actually able to follow your post and compile the CUIs and GUIs on manjaro, very nice. One problem I seem to have is that the different GUIs are not connected to each other. I am not able to run rtklaunch_qt and start the different apps from there? I have to open them individually. I imagine some environmental variables might not be set up correctly. Do you have any suggestion?


    1. Hi Christoph. I haven’t tried rtklaunch_qt but I assume it is like rtklaunch which requires all executables to be in the same folder. It looks like “make install” after “make” is supposed to copy all the Qt files into the “../RTKLIB_bin/bin” folder but it doesn’t look like this is fully functional. For now, I suspect rtklaunch_qt will work if you either manually copy the files to a single folder or write a short batch file to do this.


      1. Hi Tim,

        This Rafael Chao answering your post. Thanks a lot.
        May be I had a wrong understanding about str2str AP. I thought str2str just sent info from one place to another place, but now I understand from your post, that It can send all the GPS information (already ntrip fixed) to the tcp port #1000 as indicated in your post. Is that understanding correct?


  9. Thanks, Tim for this post! It’s very helpful. I could repeat your processes (CUI, GUI) successfully. Below is a minor blockers I encountered and its solution.

    Problem met while building qt version: “Project ERROR: Unknown module(s) in QT: serialport”
    Solved by: sudo apt-get install libqt5serialport5-dev


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: