QMake .pro 파일에서 다른 디버그 / 릴리스 출력 디렉토리를 지정하는 방법


106

Qt 프로젝트가 있고 소스 트리 외부에 컴파일 파일을 출력하고 싶습니다.

현재 다음과 같은 디렉토리 구조가 있습니다.

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

구성 (디버그 / 릴리스)에 따라 빌드 / 디버그 또는 빌드 / 릴리스 디렉토리 아래의 빌드 디렉토리에 결과 파일을 출력하고 싶습니다.

.pro 파일을 사용하여 어떻게 할 수 있습니까?


Qt가 디버그 및 릴리스 빌드를 처리하는 방식은 시간이 지남에 따라 내부적으로 변경됩니다. 그래서 우리는 디버그와 릴리스 사이의 이전 작업 스위치가 이후 버전에서 중단되었음을 발견했습니다. 지금까지 모든 플랫폼과 모든 Qt 버전에서 작동하는 내 솔루션을 참조하십시오. stackoverflow.com/questions/32046181/…
adlag

2
이것은 오래된 질문이므로 훨씬 적은 표로 더 나은 답변 이 있음을 지적 할 가치가 있습니다 .
wardw

답변:


5

짧은 대답은 : 당신은하지 않습니다 .

빌드하려는 빌드 디렉토리에서 qmake다음을 실행해야합니다 make. 따라서 debug디렉토리에서 한 번 , 디렉토리에서 한 번 실행하십시오 release.

이것이 바로 프로젝트를 빌드하는 모든 사람이 작업을 기대하는 방식이며, Qt 자체가 빌드를 위해 설정되는 방식이며, Qt Creator가 .pro파일이 작동 할 것으로 예상하는 방식이기도합니다. 파일이 시작된 qmake다음 make대상이 선택한 구성을위한 빌드 폴더에 있습니다.

이러한 폴더를 생성하고 그 안에 두 개 (또는 그 이상)의 빌드를 수행하려면, qmake를 통해 최상위 프로젝트 파일에서 생성 된 최상위 makefile이 필요합니다.

빌드 구성이 두 개 이상인 것은 드문 일이 아니므로 빌드와 릴리스를 구분하는 데 불필요하게 헌신하고 있습니다. 최적화 수준이 다른 빌드가있을 수 있습니다 . 디버그 / 릴리스 이분법은 편히 쉬는 것이 가장 좋습니다.


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조건부로 s 만 정의한 다음 다른 모든 경로에서 해당 값을 사용하십시오 OBJECTS_DIR = $${DESTDIR}/.obj. 건배!
Xavier Holt

4
이것이 어떻게 사용되는지 / 무엇을하는지 설명해 주시겠습니까? 구현할 때 효과가없는 것 같습니다. 편집 : 디버그를 디버그 (소문자)로 변경하면 작동합니다. 나는 이것이 windows 대 유닉스 대소 문자 구분이라고 생각합니다.
notlesh

9
Windows에서 작동하기 때문에 투표했습니다. 리눅스 (우분투 15.04, Qt는 5.5.0)에 나는 변화했다 DebugdebugReleaserelease.
Jepessen 2015-07-21

Wth? 교차 플랫폼에 너무 많은가? @Jepessen ??
Nils

2
이는 CONFIG에서 릴리스 또는 디버그 만있는 경우에만 작동합니다. 둘 다 구성에 있으면 후자가 사용됩니다.
weeska

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
Cameron

1
이 후에는 선을 같이 추가 할 수 있습니다 : OBJECTS_DIR = $$DESTDIR/.obj MOC_DIR = $$DESTDIR/.moc RCC_DIR = $$DESTDIR/.qrc UI_DIR = $$DESTDIR/.ui CONFIG()턴 아웃 사용하는 몇 가지 문제를 해결하기 위해 release:debug:
카슨 IP를

이것은 선택한 답변보다 더 잘 작동했습니다. 선택한 것이 작동하지만 디버그 및 릴리스가 모두 구성된 경우 두 번째 설정 블록이 유지됩니다.
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 2013

1
최근에 디버그 및 릴리스를 위해 이것을 시도 했습니까? 내 빌드 출력은 구성에 관계없이 항상 릴리스 폴더에있는 것 같습니다. 당신이 생각이 답변을 게시 이후 qmake를 / Qt는 창조주의 행동은 ... 변경되었을 수
SSC

1
릴리스 모드에서 qmake의 추가 인수에 "CONFIG-= debug"를 추가하십시오
Hello W

17

이를 수행하는 올바른 방법은 다음과 같습니다 (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


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은 다른 빌드 디렉토리에서 올바른 인수로 실행됩니다. 그런 다음 간단한 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 ...

그런 다음 빌드 디렉토리에 메이크 파일을 생성 한 다음 그 make아래에 파일도 생성합니다. qmake가 소스 디렉토리에서 실행되지 않는 한 서로 다른 버전이 뒤섞 일 위험이 없습니다 (그렇다면 잘 정리하는 것이 좋습니다!).

그리고 이렇게하면 .pro현재 승인 된 답변 의 파일이 더 간단 해집니다.

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

단일 프로젝트에서 잘 작동하지만 프로젝트와 라이브러리가 있다면 어떨까요? 그런 다음 라이브러리 afaics를 포함하는 빌드 유형 종속 방법이 필요합니다.
Adversus

@Adversus 정확히 무슨 뜻인지 잘 모르겠지만 Qmake 변수 $(OUT_PWD)가 해결책일까요?
hyde

내 질문을 귀하의 예제에 적용하면 다음과 같습니다. 응용 프로그램이 선택하는 가장 깨끗한 방법은 무엇 mylib입니까? 이 작업을 수행하는 "우아한"방법이 있으면 좋겠습니다. 다른 답변의 기술을 사용하는 것 외에 다른 방법은 없습니다. 빌드 유형과 구성을 사용 LIBS하여 현명한 방식으로 채우고 무효화 그림자 빌드의 장점.
Adversus

@Adversus mylib가 동일한 최상위 프로젝트 아래의 subdir 프로젝트 인 경우 일반적으로 mylib.pri 파일을 추가하고 Qmake 변수를 사용하여 그림자 빌드 인 경우에도 항상 올바른 경로를 가져 오는 다른 subdir 프로젝트에 필요한 모든 것을 거기에 넣습니다 . 그러면 다른 subdir .pro 파일은 단순히 있습니다include(../mylib/mylib.pri)
hyde

감사합니다. 이것이 제가 지금하고있는 일입니다. cmake에 하위 프로젝트가있는 프로젝트가있는 경우와 같이 자동으로 처리되는 솔루션이 있으면 좋았을 것입니다. 전체 트리의 소스 빌드.
Adversus

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에서 디버그 / 릴리스 찾기

현재 (디버그 | 릴리스)를 가져옵니다.

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$@
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.