building a simple qt 6 application with cmake and make

Simple Qt6 application with single menu

I’ve been working on C++ applications, especially those that use C++17 and C++20 standards features. My approach is to start small and simple and then build up from there. For this example I decided to bring my ancient Qt skills up to date with Qt 6. The last time I wrote any serious Qt applications in native C++ was back around 2006/2007, and that was using Qt 4.

I also wanted to incorporate other tools I’ve been learning how to use, specifically CMake. CMake ( ) is a powerful build tool that can help create a cross-platform configuration and build tool. I’ve been using with it with Espressif’s ESP-IDF framework. Because of this, CMake’s use has started to “leak” over into other C++ applications I’ve been working on. Then very recently I decided to pick up developing Qt applications for Linux, and I decided to use CMake to help build them from the get-go.

This application, which I’ve called simple-app, is a bare-bones skeleton that will create a bare window on the desktop and a single drop-down menu with just two entries. You can see a screen capture of it leading this post.

In order to develop with Qt 6, I installed Linux Mint’s Qt 6 package with sudo apt install qt6-base-dev. This installs Qt 6.2.4, the long-term support or LTS version that the KDE desktop uses. I could have gone with a more recent release, such as 6.4, but that would have caused too much friction trying to distribute it to others to use. Going with the version in the repos makes building and distributing it so much easier. And I don’t have to go hunt down all the odd build dependencies that Qt needs to build.

Once you install Qt, you need to install cmake if you don’t have it on your system already. You can either install it via apt, or you can do like I did and download the latest pre-built binary from the CMake website and use it locally in your home directory.

With cmake installed, it’s time to create a build folder and put the necessary files into it. The first file we’ll look at is CMakeLists.txt.

cmake_minimum_required (VERSION 3.25.0)
# Build requirements
include_directories( /usr/include/x86_64-linux-gnu/qt6/
                     /usr/include/x86_64-linux-gnu/qt6/QtWidgets/ )
link_libraries( Qt6Core Qt6Widgets Qt6Gui )
add_compile_options( -fPIC -std=c++20 )
# Project specific
project (simple-app)
add_executable (simple-app simple-app.cpp)

These are the bare CMake essentials necessary to create a make file that will build the application.

  • Line 1 is the cmake minimum version this will work with. If you have an older version of cmake then change this to match it. It should work with older versions, but I can’t guarantee that.
  • Lines 5 and 6 set up the include paths necessary to find the Qt C++ include files. These are the paths created from the installation of qt6-base-dev.
  • Line 7 lists the specific link libraries necessary for the application.
  • Line 8 are specific C++ compiler flags. The -fPIC flag is required by the Qt libraries. The -std=c++20 is required to make sure the code is being compiled to the C++20 standard.
  • Line 12 is the project name. It is actually compiled into the title of the window, which is rather nice.
  • Line 13 associates the application with the source file.

Again, these are the absolute minimum CMake statements.

Here’s the C++ source file.

#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>

class AppWindow : public QMainWindow {
    AppWindow() {
        resize(800, 600);

    QMenu *fileMenu;
    QAction *aboutAction;
    QAction *exitAction;

    void createFileMenu() {
        fileMenu = menuBar()->addMenu(tr("&File"));
        aboutAction = new QAction(tr("&About"), this);
        connect(aboutAction, &QAction::triggered, qApp, &QApplication::aboutQt);
        exitAction = new QAction(tr("E&xit"), this);
        connect(exitAction, &QAction::triggered, this, &QWidget::close);

int main(int argc, char **argv) {
    QApplication app (argc, argv);

    AppWindow window;;

    return app.exec();

This application is about as minimal as possible, at least for me. I wanted a bare window and a single simple drop-down menu, and this produces that. Here’s a basic source breakdown.

  • main() has as little as possible. It instantiates QApplication and AppWindow. It then shows the window (AppWindow), meaning the window created through QMainWindow, and then it starts the entire application execution. That’s it, and frankly, that’s really all that should be there.
  • The public AppWindow is derived from QMainWindow. This appears to be the recommended way to get a window up on a screen. All the other window features are created and then added to QMainWindow.
  • The public constructor, AppWindow::AppWindow, does very little itself. It calls a private function to create the file menu, and then sets the size in pixels (width = 800, height = 600).
  • The other function of note is of course createFileMenu. It shows, in order, how all the elements in the File menu are created. In the past I would create private functions for each menu on the menu bar. It makes it a lot easier to add, modify, or disable menus.

Here are the instructions to build the application. I’m assuming at this point you’ve got Qt 6 installed along with cmake.

  1. Create a folder somewhere in your home directory. For the purposes of this post I’ll give it the same name as the application, or simple-app.
  2. Step into the folder and copy CMakeLists.txt and simple-app.cpp into it.
  3. Run cmake: cmake -B build. This will create a folder beneath your current location, into which the makefile and all other support files are created.
  4. Run make: make -C build. This will build the application, leaving the executable binary in the build folder.
  5. Run the application: ./build/simple-app

You don’t have to create the build subdirectory, but if you don’t then cmake and make litter the work area with a lot of individual build byproduct files. I use the build subdirectory method so that if I check this into Git then my .gitignore file is very simple; all I have to do to have git ignore the build subdirectories is put in an entry for build.

Right now the only “real” working function is the About menu selection. It produces the following dialog when selected:

I want to see Qt’s About because it also includes the licensing terms, which I always check.

I wanted to share this because while it’s minimal, it’s still a useful starting point. I hope you find it useful as well.

One thought on “building a simple qt 6 application with cmake and make

Comments are closed.