qmake

Other topics

Default "pro" file.

qmake is a build automation tool, which is shipped with Qt framework. It does similar job to tools such as CMake or GNU Autotools, but it is designed to be used specifically with Qt. As such it is well integrated with Qt ecosystem, notably Qt Creator IDE.

If you start Qt Creator and select File -> New File or Project -> Application -> Qt Widgets application, Qt Creator will generate a project skeleton for you along with a "pro" file. The "pro" file is processed by qmake in order to generate files, which are in turn processed by underlying build systems (for example GNU Make or nmake).

If you named your project "myapp", then "myapp.pro" file will appear. Here's how such default file looks like, with comments, that describe each qmake variable, added.

# Tells build system that project uses Qt Core and Qt GUI modules.
QT       += core gui

# Prior to Qt 5 widgets were part of Qt GUI module. In Qt 5 we need to add Qt Widgets module.
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

# Specifies name of the binary.
TARGET = myapp

# Denotes that project is an application.
TEMPLATE = app

# List of source files (note: Qt Creator will take care about this list, you don't need to update is manually).
SOURCES += main.cpp\
        mainwindow.cpp

# List of header files (note: Qt Creator will take care about this list).
HEADERS  += mainwindow.h

# List of "ui" files for a tool called Qt Designer, which is embedded into Qt Creator in newer versions of IDE (note: Qt Creator will take care about this list).
FORMS    += mainwindow.ui

Preserving source directory structure in a build (undocumented "object_parallel_to_source" option).

If you like to organize your project by keeping source files in different subdirectories, you should know that during a build qmake will not preserve this directory structure and it will keep all the ".o" files in a single build directory. This can be a problem if you had conflicting file names in different directories like following.

src/file1.cpp
src/plugin/file1.cpp

Now qmake will decide to create two "file1.o" files in a build directory, causing one of them to be overwritten by another. The buld will fail. To prevent this you can add CONFIG += object_parallel_to_source configuration option to your "pro" file. This will tell qmake to generate build files that preserve your source directory structure. This way your build directory will reflect source directory structure and object files will be created in separate subdirectories.

src/file1.o
src/plugin/file1.o

Complete example.

QT += core
TARGET = myapp
TEMPLATE = app

CONFIG += object_parallel_to_source

SOURCES += src/file1.cpp \
           src/plugin/file1.cpp

HEADERS  += src/plugin/file1.h

Note that object_parallel_to_source CONFIG option is not officially documented.

Simple Example (Linux)

Window.h

#include <QWidget>

class Window : public QWidget
{
    Q_OBJECT
public:
    Window(QWidget *parent = Q_NULLPTR) : QWidget(parent) {}
}

main.cpp

#include <QApplication>
#include "Window.h"

int main()
{
    QApplication app;
    Window window;
    window.show();
    return app.exec();
}

example.pro

# The QT variable controls what modules are included in compilation.
# Note that the 'core' and 'gui' modules are included by default.
# For widget-based GUI applications, the 'widgets' module needs to be added.
QT += widgets  

HEADERS = Window.h # Everything added to the HEADER variable will be checked 
                   # to see if moc needs to run on it, and it will be run if
                   # so.

SOURCES = main.cpp # Everything added to the SOURCES variable will be compiled
                   # and (in the simple example) added to the resulting
                   # executable.

Command Line

# Assuming you are in a folder that contains the above files.
> qmake         # You can also add the example.pro file if needed
> make          # qmake creates a Makefile, this runs make on it.
> ./example     # The name of the executable defaults to the .pro file name.

SUBDIRS example

The SUBDIRS ability of qmake can be used to compile a set of libraries, each of which depend on another. The example below is slightly convoluted to show variations with the SUBDIRS ability.

Directory Structure

Some of the following files will be omitted in the interest of brevity. They can be assumed to be the format as non-subdir examples.

project_dir/
-project.pro
-common.pri
-build.pro
-main.cpp
-logic/
----logic.pro
----some logic files
-gui/
----gui.pro
----gui files

project.pro

This is the main file that enables the example. This is also the file that would be called with qmake on the command line (see below).

TEMPLATE = subdirs  # This changes to the subdirs function.  You can't combine 
                    # compiling code and the subdirs function in the same .pro
                    # file.

# By default, you assign a directory to the SUBDIRS variable, and qmake looks
# inside that directory for a <dirname>.pro file.
SUBDIRS = logic

# You can append as many items as desired.  You can also specify the .pro file
# directly if need be.
SUBDIRS += gui/gui.pro

# You can also create a target that isn't a subdirectory, or that refers to a
# different file(*).
SUBDIRS += build
build.file = build.pro # This specifies the .pro file to use
# You can also use this to specify dependencies.  In this case, we don't want 
# the build target to run until after the logic and gui targets are complete.
build.depends = logic gui/gui.pro

(*) See The reference documentation for the other options for a subdirs target.

common.pri

#Includes common configuration for all subdirectory .pro files.
INCLUDEPATH += . ..
WARNINGS += -Wall

TEMPLATE = lib

# The following keeps the generated files at least somewhat separate 
# from the source files.
UI_DIR = uics
MOC_DIR = mocs
OBJECTS_DIR = objs

logic/logic.pro

# Check if the config file exists
! include( ../common.pri ) {
    error( "Couldn't find the common.pri file!" )
}

HEADERS += logic.h
SOURCES += logic.cpp

# By default, TARGET is the same as the directory, so it will make 
# liblogic.so (in linux).  Uncomment to override.
# TARGET = target

gui/gui.pro

! include( ../common.pri ) {
    error( "Couldn't find the common.pri file!" )
}

FORMS += gui.ui
HEADERS += gui.h
SOURCES += gui.cpp

# By default, TARGET is the same as the directory, so it will make 
# libgui.so (in linux).  Uncomment to override.
# TARGET = target

build.pro

TEMPLATE = app

SOURCES += main.cpp

LIBS += -Llogic -Lgui -llogic -lgui

# This renames the resulting executable
TARGET = project

Command Line

# Assumes you are in the project_dir directory
> qmake project.pro # specific the .pro file since there are multiple here.
> make -n2 # This makes logic and gui concurrently, then the build Makefile.
> ./project # Run the resulting executable.

Library example

A simple example to make a library (rather than an executable, which is the default). TEMPLATE variable specifies type of the project you are making. lib option allows makefile to build a library.

library.pro

HEADERS += library.h
SOURCES += library.cpp

TEMPLATE = lib

# By default, qmake will make a shared library.  Uncomment to make the library 
# static.
# CONFIG += staticlib

# By default, TARGET is the same as the directory, so it will make 
# liblibrary.so or liblibrary.a (in linux).  Uncomment to override.
# TARGET = target

When you are building a library, you can add options dll (default), staticlib or plugin to CONFIG.

Creating a project file from existing code

If you have a directory with existing source files, you can use qmake with the -project-option to create a project file.

Let's assume, the folder MyProgram contains the following files:

  • main.cpp
  • foo.h
  • foo.cpp
  • bar.h
  • bar.cpp
  • subdir/foobar.h
  • subdir/foobar.cpp

Then by calling

qmake -project

a file MyProgram.pro is created with the following content:

######################################################################
# Automatically generated by qmake (3.0) Mi. Sep. 7 23:36:56 2016
######################################################################

TEMPLATE = app
TARGET = MyProgram
INCLUDEPATH += .

# Input
HEADERS += bar.h foo.h subdir/foobar.h
SOURCES += bar.cpp foo.cpp main.cpp subdir/foobar.cpp

The code can then be built as described in this simple example.

Contributors

Topic Id: 4438

Example Ids: 15509,15975,16534,16535,16536,20988

This site is not affiliated with any of the contributors.