How to specify different Debug/Release output directories in QMake .pro file

I have a Qt project and I would like to output compilation files outside the source tree.

I currently have the following directory structure:

/
|_/build
|_/mylib
  |_/include
  |_/src
  |_/resources

Depending on the configuration (debug/release), I will like to output the resulting files inside the build directory under build/debug or build/release directories.

How can I do that using a .pro file?

Answers


The short answer is: you don't.

You should run qmake followed by make in whatever build directory you want to build in. So, run it once in a debug directory, once in a release directory.

That's how anyone building your project would expect it to work, and that's how Qt itself is set up to build, that's also how Qt Creator expects your .pro file to behave: it simply starts qmake and then make in the build folder for your target's chosen configuration.

If you wish to create these folders and perform the two (or more) builds in them, you'll need a top-level makefile, possibly created from a top-level project file via qmake.

It's not uncommon to have more than two build configurations, so you're unnecessarily committing yourself to only differentiating between a build and a release; you might have builds with different optimization levels, etc. The debug/release dichotomy is best left to rest in peace.


For my Qt project, I use this scheme in *.pro file:

HEADERS += src/dialogs.h
SOURCES += src/main.cpp \
           src/dialogs.cpp

Release:DESTDIR = release
Release:OBJECTS_DIR = release/.obj
Release:MOC_DIR = release/.moc
Release:RCC_DIR = release/.rcc
Release:UI_DIR = release/.ui

Debug:DESTDIR = debug
Debug:OBJECTS_DIR = debug/.obj
Debug:MOC_DIR = debug/.moc
Debug:RCC_DIR = debug/.rcc
Debug:UI_DIR = debug/.ui

It`s simple, but nice! :)


To change the directory for target dll/exe, use this in your pro file:

CONFIG(debug, debug|release) {
    DESTDIR = build/debug
} else {
    DESTDIR = build/release
}

You might also want to change directories for other build targets like object files and moc files (check qmake variable reference for details or qmake CONFIG() function reference).


I have a more compact approach:

release: DESTDIR = build/release
debug:   DESTDIR = build/debug

OBJECTS_DIR = $$DESTDIR/.obj
MOC_DIR = $$DESTDIR/.moc
RCC_DIR = $$DESTDIR/.qrc
UI_DIR = $$DESTDIR/.ui

I use the same method suggested by chalup,

ParentDirectory = <your directory>

RCC_DIR = "$$ParentDirectory\Build\RCCFiles"
UI_DIR = "$$ParentDirectory\Build\UICFiles"
MOC_DIR = "$$ParentDirectory\Build\MOCFiles"
OBJECTS_DIR = "$$ParentDirectory\Build\ObjFiles"

CONFIG(debug, debug|release) { 
    DESTDIR = "$$ParentDirectory\debug"
}
CONFIG(release, debug|release) { 
    DESTDIR = "$$ParentDirectory\release"
}

The correct way to do this is the following (thanks QT Support Team):

CONFIG(debug, debug|release) {
    DESTDIR = build/debug
}
CONFIG(release, debug|release) {
    DESTDIR = build/release
}

OBJECTS_DIR = $$DESTDIR/.obj
MOC_DIR = $$DESTDIR/.moc
RCC_DIR = $$DESTDIR/.qrc
UI_DIR = $$DESTDIR/.u

More info here: https://wiki.qt.io/Qt_project_org_faq#What_does_the_syntax_CONFIG.28debug.2Cdebug.7Crelease.29_mean_.3F_What_does_the_1st_argument_specify_and_similarly_what_is_the_2nd_.3F


Old question, but still worth an up-to-date answer. Today it's common to do what Qt Creator does when shadow builds are used (they are enabled by default when opening a new project).

For each different build target and type, the right qmake is run with right arguments in a different build directory. Then that is just built with simple make.

So, imaginary directory structure might look like this.

/
|_/build-mylib-qt5-mingw32-debug
|_/build-mylib-qt5-mingw32-release
|_/build-mylib-qt4-msvc2010-debug
|_/build-mylib-qt4-msvc2010-release
|_/build-mylib-qt5-arm-debug
|_/build-mylib-qt5-arm-release
|_/mylib
  |_/include
  |_/src
  |_/resources

And the improtant thing is, a qmake is run in the build directory:

cd build-mylib-XXXX
/path/to/right/qmake ../mylib/mylib.pro CONFIG+=buildtype ...

Then it generates makefiles in build directory, and then make will generate files under it too. There is no risk of different versions getting mixed up, as long as qmake is never run in the source directory (if it is, better clean it up well!).

And when done like this, the .pro file from currently accepted answer is even simpler:

HEADERS += src/dialogs.h
SOURCES += src/main.cpp \
           src/dialogs.cpp

It's also useful to have a slightly different name for the output executable. You can't use something like:

release: Target = ProgramName
debug: Target = ProgramName_d

Why it doesn't work is not clear, but it does not. But:

CONFIG(debug, debug|release) {
    TARGET = ProgramName
} else {
    TARGET = ProgramName_d
}

This does work as long as the CONFIG += line precedes it.


The new version of Qt Creator also has a "profile" build option between debug and release. Here's how I'm detecting that:

CONFIG(debug, debug|release) {  DEFINES += DEBUG_MODE }
else:CONFIG(force_debug_info) { DEFINES += PROFILE_MODE }
else {                          DEFINES += RELEASE_MODE }

Need Your Help

Saving "Messages" from users in mysql without SQL Injection

php mysql sql pdo sql-injection

I've a script which Takes $_POST['messages'] and then saves the user's messages to MySQL database.

How to perform uint32/float conversion with SSE?

c x86 sse simd

In SSE there is a function _mm_cvtepi32_ps(__m128i input) which takes input vector of 32 bits wide signed integers (int32_t) and converts them into floats.