如何在 QMake .pro 文件中指定不同的调试/发布输出目录

发布于 2024-08-27 18:08:29 字数 235 浏览 7 评论 0原文

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

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

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

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

如何使用 .pro 文件执行此操作?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

極樂鬼 2024-09-03 18:08:29

对于我的 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

它很简单,但很好! :)

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! :)

终遇你 2024-09-03 18:08:29

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

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

您可能还想更改其他构建目标的目录,例如对象文件和 moc 文件(检查 qmake 变量参考 了解详细信息或 qmake CONFIG() 函数参考)。

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).

指尖凝香 2024-09-03 18:08:29

我有一个更紧凑的方法:

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 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
乖乖 2024-09-03 18:08:29

正确的方法如下(感谢 QT 支持团队):

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

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

日久见人心 2024-09-03 18:08:29

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

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"
}
栖竹 2024-09-03 18:08:29

老问题,但仍然值得最新的答案。如今,当使用影子构建时,通常会执行 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

重要的是,在build目录下运行了一个qmake

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

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

当这样做时,当前接受的答案中的 .pro 文件更加简单:

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

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
不知在何时 2024-09-03 18:08:29

简短的回答是:你不

您应该在您想要构建的任何构建目录中运行qmake,然后运行make。因此,在debug目录中运行一次,一旦进入release 目录。

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

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

拥有两个以上的构建配置并不罕见,因此您不必要地致力于仅区分构建和发布;您可能有不同优化级别的构建,等等。 调试/发布二分法最好不要打扰。

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.

风筝在阴天搁浅。 2024-09-03 18:08:29

为输出可执行文件使用稍微不同的名称也很有用。您不能使用类似的内容:

release: Target = ProgramName
debug: Target = ProgramName_d

尚不清楚为什么它不起作用,但事实并非如此。但是:

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

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

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.

手心的温暖 2024-09-03 18:08:29

新版本的 Qt Creator 还在调试和发布之间提供了“配置文件”构建选项。我是这样检测的:

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

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 }
天生の放荡 2024-09-03 18:08:29

这是我针对不同调试/发布输出目录的 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 
lt; -o"$@"

$(OutRootDir)/$(DebugDir)/%.$(ObjExt):   %.c | $(OutRootDir)/$(DebugDir)
    $(CC) -I$(INCLUDE) $(CFLAGS) -c 
lt; -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$@

This is my Makefile for different debug/release output directories. This Makefile was tested successfully on Ubuntu linux. It should work seamlessly on Windows provided that Mingw-w64 is installed correctly.

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 
lt; -o"$@"

$(OutRootDir)/$(DebugDir)/%.$(ObjExt):   %.c | $(OutRootDir)/$(DebugDir)
    $(CC) -I$(INCLUDE) $(CFLAGS) -c 
lt; -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$@
孤单情人 2024-09-03 18:08:29

不确定是否有人会遇到像我这样的问题,但我会分享我的设置。
我使用中央 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”来构建调试或发布。
谁有更好的解决方案,请分享。

Not sure if anyone will face issues like me, but I'd share my setup.
I use a central proj.pri file to store general settings. I have PKG.pro in each subdirs which is already designed for debug mode. So when I try to build both debug and release, I don't want to modify every PKG.pro in each subdir. I added same

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

which doesn't work since in each subdir, DESTDIR will get evaluated again. it ends a double debug or release. To avoid this, you have to use only one DESTDIR set, then in each subdir, you can include this proj.pri file. This way, you don't need to write one DIR setup.
And "qmake CONFIG=debug" or "qmake CONFIG=release" is needed to build debug or release.
Anyone has better solution, please share.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文