我有一个Qt项目,我想在源代码树之外输出编译文件。
我目前具有以下目录结构:
/
|_/build
|_/mylib
|_/include
|_/src
|_/resources
根据配置(调试/发行版),我想将生成的文件输出到build / debug或build / release目录下的build目录中。
我该如何使用.pro文件呢?
我有一个Qt项目,我想在源代码树之外输出编译文件。
我目前具有以下目录结构:
/
|_/build
|_/mylib
|_/include
|_/src
|_/resources
根据配置(调试/发行版),我想将生成的文件输出到build / debug或build / release目录下的build目录中。
我该如何使用.pro文件呢?
Answers:
简短的答案是:您不会。
你应该运行qmake
,然后make
在任何build目录你想建立的。所以,在运行一次它debug
的目录,一旦在release
目录中。
这就是任何构建您的项目的人希望它工作的方式,这就是Qt本身被设置为构建的方式,这也是Qt Creator期望您的.pro
文件表现的方式:它只是启动qmake
,然后make
在目标所选配置的构建文件夹中。
如果要创建这些文件夹并在其中执行两个(或多个)构建,则需要一个顶级makefile,可能是通过qmake从顶级项目文件中创建的。
拥有两个以上的构建配置并不少见,因此您不必要地致力于仅区分构建和发行版。您可能会使用不同的优化级别进行构建,等等。最好让调试/发布二分法安息。
对于我的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
很简单,但是很好!:)
DESTDIR
有条件地定义,然后在所有其他路径中使用该值:OBJECTS_DIR = $${DESTDIR}/.obj
。干杯!
Debug
对debug
和Release
对release
。
要更改目标dll / exe的目录,请在您的pro文件中使用以下目录:
CONFIG(debug, debug|release) {
DESTDIR = build/debug
} else {
DESTDIR = build/release
}
您可能还想更改其他构建目标的目录,例如目标文件和moc文件(请查看qmake变量参考以获取详细信息或qmake CONFIG()函数参考)。
OBJECTS_DIR = $$DESTDIR/.obj MOC_DIR = $$DESTDIR/.moc RCC_DIR = $$DESTDIR/.qrc UI_DIR = $$DESTDIR/.ui
CONFIG()
原来可以解决使用release:
和的一些问题debug:
我有一个更紧凑的方法:
release: DESTDIR = build/release
debug: DESTDIR = build/debug
OBJECTS_DIR = $$DESTDIR/.obj
MOC_DIR = $$DESTDIR/.moc
RCC_DIR = $$DESTDIR/.qrc
UI_DIR = $$DESTDIR/.ui
正确的方法如下(感谢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_likely_what_is_the_2nd_.3F
我使用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"
}
旧问题,但仍值得最新答案。今天,当使用阴影构建时(通常在打开新项目时默认启用它们),通常会执行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
$(OUT_PWD)
是解决方案吗?
mylib
?我想如果有一种“优美的”方式来做到这一点,除了使用其他答案中的技术外,我看不到其他方式:使用构建类型和配置以LIBS
一种聪明的方式填充,从而无效影子构建的优势。
include(../mylib/mylib.pri)
这是我用于不同调试/发布输出目录的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$@