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

我有一个 Qt 项目,我想输出源树之外的编译文件。

I currently have the following directory structure:

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

根据配置(调试/发布) ,我希望将结果文件输出到 build/debug 或 build/release 目录下的 build 目录中。

我如何使用. pro 文件做到这一点?

123225 次浏览

要更改目标 dll/exe 的目录,请在您的专业文件中使用:

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

您可能还希望更改其他构建目标的目录,如对象文件和 moc 文件(有关详细信息,请参阅 变量引用qmake CONFIG() function reference)。

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

很简单,但是很好! :)

我用的是 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"
}

我有一个更简洁的方法:

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


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

对输出可执行文件使用稍微不同的名称也很有用:

release: Target = ProgramName
debug: Target = ProgramName_d

为什么它不起作用还不清楚,但它确实不起作用。但是:

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

只要 CONFIG +=行在它之前,它就可以工作。

老问题了,但还是值得一个最新的答案。如今,在使用影子构建时,Qt Creator 所做的事情很常见(在打开新项目时默认启用影子构建)。

对于每个不同的生成目标和类型,在不同的生成目录中使用正确的参数运行正确的 qmake。那么这只是用简单的 make构建的。

所以,假想的目录结构可能是这样的。

/
|_/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

重要的是,在构建目录中运行 qmake:

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

然后它在构建目录中生成 makefile,然后 make也将在其下生成文件。只要不在源目录中运行 qmake,就不存在不同版本混淆的风险(如果存在,最好将其清理干净!).

当这样做时,目前公认的答案中的 .pro文件就更简单了:

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

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

更多信息请点击: 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

简短的回答是: 你不知道

您应该在希望构建的任何构建目录中运行 qmakemake。因此,在 debug目录中运行一次,在 release目录中运行一次。

这是任何构建项目的人都希望它能够工作的方式,这也是 Qt 本身设置构建的方式,这也是 Qt Creator 期望你的 .pro文件的行为方式: 它只是在构建文件夹中为你的目标选择的配置启动 qmake,然后启动 make

如果希望创建这些文件夹并在其中执行两个(或更多)构建,则需要一个顶级 makefile,可能通过 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. 调试/发布的二分法最好保持平静。

Qt Creator 的新版本在调试和发布之间还有一个“ profile”构建选项。我是这样发现的:

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

这是针对不同调试/发布输出目录的 Makefile。这个 Makefile 已经在 Ubuntu linux 上成功测试过了。如果 Mingw-w64安装正确,它应该可以在 Windows 上无缝地工作。

ifeq ($(OS),Windows_NT)
ObjExt=obj
mkdir_CMD=mkdir
rm_CMD=rmdir /S /Q
else
ObjExt=o
mkdir_CMD=mkdir -p
rm_CMD=rm -rf
endif


CC     =gcc
CFLAGS =-Wall -ansi
LD     =gcc


OutRootDir=.
DebugDir  =Debug
ReleaseDir=Release




INSTDIR =./bin
INCLUDE =.


SrcFiles=$(wildcard *.c)
EXEC_main=myapp


OBJ_C_Debug   =$(patsubst %.c,  $(OutRootDir)/$(DebugDir)/%.$(ObjExt),$(SrcFiles))
OBJ_C_Release =$(patsubst %.c,  $(OutRootDir)/$(ReleaseDir)/%.$(ObjExt),$(SrcFiles))


.PHONY: Release Debug cleanDebug cleanRelease clean


# Target specific variables
release: CFLAGS += -O -DNDEBUG
debug:   CFLAGS += -g


################################################
#Callable Targets
release: $(OutRootDir)/$(ReleaseDir)/$(EXEC_main)
debug:   $(OutRootDir)/$(DebugDir)/$(EXEC_main)


cleanDebug:
-$(rm_CMD) "$(OutRootDir)/$(DebugDir)"
@echo cleanDebug done


cleanRelease:
-$(rm_CMD) "$(OutRootDir)/$(ReleaseDir)"
@echo cleanRelease done


clean: cleanDebug cleanRelease
################################################


# Pattern Rules
# Multiple targets cannot be used with pattern rules [https://www.gnu.org/software/make/manual/html_node/Multiple-Targets.html]
$(OutRootDir)/$(ReleaseDir)/%.$(ObjExt): %.c | $(OutRootDir)/$(ReleaseDir)
$(CC) -I$(INCLUDE) $(CFLAGS) -c $< -o"$@"


$(OutRootDir)/$(DebugDir)/%.$(ObjExt):   %.c | $(OutRootDir)/$(DebugDir)
$(CC) -I$(INCLUDE) $(CFLAGS) -c $< -o"$@"


# Create output directory
$(OutRootDir)/$(ReleaseDir) $(OutRootDir)/$(DebugDir) $(INSTDIR):
-$(mkdir_CMD) $@


# Create the executable
# Multiple targets [https://www.gnu.org/software/make/manual/html_node/Multiple-Targets.html]
$(OutRootDir)/$(ReleaseDir)/$(EXEC_main): $(OBJ_C_Release)
$(OutRootDir)/$(DebugDir)/$(EXEC_main):   $(OBJ_C_Debug)
$(OutRootDir)/$(ReleaseDir)/$(EXEC_main) $(OutRootDir)/$(DebugDir)/$(EXEC_main):
$(LD) $^ -o$@

不确定是否有人会遇到像我这样的问题,但我会分享我的设置。 我使用一个中央 proj.pri 文件来存储常规设置。我有 PKG.pro 在每个子目录已经为调试模式设计。因此,当我尝试构建调试和发布版本时,我不想修改每个子目录中的每个 PKG.pro。我也加了一样的

DESTDIR = $${SOMEOTHERPATH}
release: DESTDIR = $${DESTDIR}/release
debug:   DESTDIR = $${DESTDIR}/debug


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

它不工作,因为在每个子目录中,DESTDIR 将被再次计算。它结束了双重调试或释放。为了避免这种情况,您必须只使用一个 DESTDIR 集,然后在每个子目录中都可以包含这个 proj.pri 文件。这样,您就不需要编写一个 DIR 设置。 并且“ qmake CONFIG = debug”或“ qmake CONFIG = release”是构建调试或发布所必需的。 Anyone has better solution, please share.