如何在QMake .pro文件中指定不同的Debug / Release输出目录


106

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

我目前具有以下目录结构:

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

根据配置(调试/发行版),我想将生成的文件输出到build / debug或build / release目录下的build目录中。

我该如何使用.pro文件呢?


Qt处理调试和发布版本的方式在内部随时间而改变。因此,我们发现调试和发行版之间的先前工作切换在更高版本中中断。请参阅到目前为止可在所有平台和所有Qt版本上使用的我的解决方案。stackoverflow.com/questions/32046181/…–
adlag

2
由于这是一个古老的问题,值得指出的是,票数少的更好的答案
wardw

Answers:


5

简短的答案是:您不会

你应该运行qmake,然后make在任何build目录你想建立的。所以,在运行一次它debug的目录,一旦在release目录中。

这就是任何构建您的项目的人希望它工作的方式,这就是Qt本身被设置为构建的方式,这也是Qt Creator期望您的.pro文件表现的方式:它只是启动qmake,然后make在目标所选配置的构建文件夹中。

如果要创建这些文件夹并在其中执行两个(或多个)构建,则需要一个顶级makefile,可能是通过qmake从顶级项目文件中创建的。

拥有两个以上的构建配置并不少见,因此您不必要地致力于仅区分构建和发行版。您可能会使用不同的优化级别进行构建,等等。最好让调试/发布二分法安息。


151

对于我的Qt项目,我在* .pro文件中使用以下方案:

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

很简单,但是很好!:)


18
正是我所需要的!还有一个注意事项:为了使事情更容易切换,只需DESTDIR有条件地定义,然后在所有其他路径中使用该值:OBJECTS_DIR = $${DESTDIR}/.obj。干杯!
Xavier Holt'3

4
介意解释此方法的用途/作用?当我实现它时,它似乎没有任何作用。编辑:如果我将调试更改为调试(小写),它将起作用。我怀疑这是Windows vs Unix区分大小写的东西。
notlesh

9
我投票支持它,因为它可以在Windows上运行。在Linux(Ubuntu的15.04,QT 5.5.0),我不得不改变DebugdebugReleaserelease
杰普森,2015年

什么 有这么多跨平台?@杰普森?
Nils

2
仅当在CONFIG中只有发行版或调试版时,这才有效。如果两者都在配置中,则将使用后一个。
weeska '16

52

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

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

您可能还想更改其他构建目标的目录,例如目标文件和moc文件(请查看qmake变量参考以获取详细信息或qmake CONFIG()函数参考)。


5
但是我发现在其中包含$$ OUT_PWD更好,所以DESTDIR = $$ OUT_PWD / debug
Ivo,

1
@Ivo:啊!谢谢!我一直在到处寻找包含该路径的变量!:D
卡梅伦

1
此后,您可以添加以下行:OBJECTS_DIR = $$DESTDIR/.obj MOC_DIR = $$DESTDIR/.moc RCC_DIR = $$DESTDIR/.qrc UI_DIR = $$DESTDIR/.ui CONFIG()原来可以解决使用release:和的一些问题debug:
Carson Ip 2015年

这比所选答案更好。选定的选项起作用,但是如果同时配置了调试和发布,则保留第二个设置块。
Paulo Carvalho

42

我有一个更紧凑的方法:

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

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

2
您的答案是将编译器构建输出放在单独目录中的最新方法。
SIFE

1
您最近是否尝试过调试和发布?无论采用哪种配置,我的构建输出似乎总是以发布文件夹结尾。自从您发布此答案以来,qmake / Qt Creator的行为可能已更改……
ssc 2015年

1
尝试在“发布”模式中将“ CONFIG-= debug”添加到qmake的其他参数中
Hello W


13

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

12

旧问题,但仍值得最新答案。今天,当使用阴影构建时(通常在打开新项目时默认启用它们),通常会执行Qt Creator的操作。

对于每个不同的构建目标和类型,qmake权限在不同的构建目录中使用正确的参数运行。然后,这就是用simple构建的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

至关重要的是,a 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

对于单个项目来说效果很好,但是如果您有一个项目和一个库呢?然后,您需要一种依赖于构建类型的方式来包括库afaics。
2015年

@Adversus我不确定您的确切意思,但是Qmake变量可能$(OUT_PWD)是解决方案吗?
海德2015年

当我将问题应用于您的示例时,它变成:应用程序的最干净方法是什么mylib?我想如果有一种“优美的”方式来做到这一点,除了使用其他答案中的技术外,我看不到其他方式:使用构建类型和配置以LIBS一种聪明的方式填充,从而无效影子构建的优势。
Adversus

@Adversus如果mylib是同一顶级项目下的子目录项目,我通常会添加一个mylib.pri文件,并将其他子目录项目需要的所有内容放在该目录中,使用Qmake变量始终正确获取路径,即使它是影子构建。然后其他subdir .pro文件将仅具有include(../mylib/mylib.pri)
hyde 2015年

谢谢,这就是我现在正在做的事情,很高兴能找到一个可以自动解决的解决方案,例如当您在cmake中有一个带有子项目的项目,然后可以轻松地做出不同的整个树的源代码构建。
2015年

3

为输出可执行文件使用略有不同的名称也很有用。您不能使用以下内容:

release: Target = ProgramName
debug: Target = ProgramName_d

为何不起作用尚不清楚,但事实并非如此。但:

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

只要CONFIG +=行在前,它就起作用。


1

新版本的Qt Creator在调试和发布之间还具有“配置文件”构建选项。这是我检测到的方式:

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

0

1.在CONFIG中找到Debug / Release

获取当前(调试|发布)。

specified_configs=$$find(CONFIG, "\b(debug|release)\b")
build_subdir=$$last(specified_configs)

(可能是多个,因此请仅在构建中保留最后指定的位置):

2.设置DESTDIR

使用它具有构建子目录名称

DESTDIR = $$PWD/build/$$build_subdir

0

这是我用于不同调试/发布输出目录的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$@
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.