QMake .pro फ़ाइल में विभिन्न डीबग / रिलीज़ आउटपुट निर्देशिकाओं को निर्दिष्ट करने के लिए कैसे करें


106

मेरे पास एक क्यूटी परियोजना है और मैं स्रोत पेड़ के बाहर संकलन फ़ाइलों का उत्पादन करना चाहूंगा।

वर्तमान में मेरे पास निम्न निर्देशिका संरचना है:

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

कॉन्फ़िगरेशन (डिबग / रिलीज़) के आधार पर, मैं बिल्ड / डीबग या बिल्ड / रिलीज़ निर्देशिका के तहत बिल्ड निर्देशिका के अंदर परिणामी फ़ाइलों को आउटपुट करना चाहूंगा।

मैं .pro फ़ाइल का उपयोग कैसे कर सकता हूं?


जिस तरह से क्यूटी डीबग का इलाज करता है और रिलीज समय के साथ आंतरिक रूप से बदल जाता है। इसलिए हमें पता चला कि डिबग और रिलीज़ के बीच पिछले काम के स्विच बाद के संस्करणों में टूट गए। मेरा समाधान देखें जो सभी प्लेटफार्मों पर और सभी क्यूटी संस्करणों पर अब तक काम करता है। stackoverflow.com/questions/32046181/…
adlag

2
चूंकि यह एक पुराना प्रश्न है, यह इंगित करने के लायक है कि बहुत कम वोटों के साथ बेहतर उत्तर हैं ।
वार्ड

जवाबों:


5

संक्षिप्त उत्तर है: आप नहीं

आपको जो भी निर्माण निर्देशिका में निर्माण करना चाहते हैं, qmakeउसके बाद चलना चाहिए make। इसलिए, इसे एक बार debugनिर्देशिका में, एक बार में चलाएंrelease

यह है कि आपकी परियोजना का निर्माण करने वाला कोई भी व्यक्ति इससे काम करने की उम्मीद करेगा, और यह कि Qt का निर्माण करने के लिए कैसे सेट किया गया है, यह भी है कि Qt Creator आपकी .proफ़ाइल को कैसे व्यवहार करने की उम्मीद करता है : यह बस शुरू होता है qmakeऔर फिरmake आपके लक्ष्य के चुने हुए कॉन्फ़िगरेशन के लिए बिल्ड फ़ोल्डर में।

यदि आप इन फ़ोल्डरों को बनाना चाहते हैं और उनमें दो (या अधिक) का निर्माण करते हैं, तो आपको एक शीर्ष-स्तरीय मेकफाइल की आवश्यकता होगी, संभवतः 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। चीयर्स!
जेवियर होल्ट

4
यह बताते हुए कि यह कैसे उपयोग किया जाता है / यह क्या करता है? जब मैं इसे लागू करता हूं तो इसका कोई प्रभाव नहीं पड़ता है। संपादित करें: अगर मैं डिबग को डिबग (निचले मामले) में बदलता हूं तो यह काम करता है। मुझे संदेह है कि यह एक विंडोज़ बनाम यूनिक्स केस संवेदनशीलता चीज़ है।
प्रात:

9
मैंने इसे वोट दिया क्योंकि यह विंडोज पर काम करता है। लिनक्स (Ubuntu 15.04, क्यूटी 5.5.0) पर मैं परिवर्तन करना पड़ा Debugकरने के लिए debugऔर Releaseकरने के लिए release
जेपसेन

Wth? प्लेटफॉर्म पार करने के लिए इतना? @Jepessen ??
निल्स

2
यह केवल तभी काम करता है जब आपके पास केवल CONFIG में रिलीज़ या डिबग हो। यदि दोनों विन्यास में हैं, तो बाद वाले का उपयोग किया जाएगा।
वसेका

52

लक्ष्य dll / exe के लिए निर्देशिका बदलने के लिए, अपनी प्रो फ़ाइल में इसका उपयोग करें:

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

आप ऑब्जेक्ट फ़ाइलों और moc फ़ाइलों जैसे अन्य बिल्ड लक्ष्यों के लिए निर्देशिकाओं को बदलना चाहते हैं ( विवरण के लिए qmake चर संदर्भ की जाँच करें या qmake CONFIG () फ़ंक्शन संदर्भ )।


5
लेकिन मुझे इसमें $ $ OUT_PWD शामिल करने के लिए बहुत अच्छा लग रहा है, इसलिए DESTDIR = $$ OUT_PWD / डिबग
Ivo

1
@ आईवो: आह! धन्यवाद! मैं हर जगह देख रहा हूँ जिसके लिए चर में वह रास्ता था! : D
कैमरून

1
इसके बाद, आप लाइनों को जोड़ सकते हैं जैसे: OBJECTS_DIR = $$DESTDIR/.obj MOC_DIR = $$DESTDIR/.moc RCC_DIR = $$DESTDIR/.qrc UI_DIR = $$DESTDIR/.ui CONFIG()उपयोग की कुछ समस्याओं को हल करने के लिए निकलता है release:औरdebug:
कार्सन आईपी

यह एक चयनित उत्तर की तुलना में बेहतर काम करता है। चयनित एक काम करता है, लेकिन यदि डिबग और रिलीज़ दोनों को कॉन्फ़िगर किया गया है, तो सेटिंग्स का दूसरा ब्लॉक रहता है।
पाउलो कार्वाल्हो

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
क्या आपने हाल ही में डिबग और रिलीज़ दोनों के लिए यह कोशिश की है? मेरा बिल्ड आउटपुट हमेशा रिलीज़ फ़ोल्डर में समाप्त होता है, कोई फर्क नहीं पड़ता कि कौन सा कॉन्फ़िगरेशन; क्यूमेक / क्यूटी क्रिएटर का व्यवहार तब से बदल सकता है क्योंकि आपने इस उत्तर को पोस्ट किया है ...
ssc

1
रिलीज मोड में qmake के अतिरिक्त तर्कों के लिए "CONFIG - = डिबग" को जोड़ने की कोशिश करें
हैलो डब्ल्यू

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.2_mean_.3F_What_does_the_1st_argument_specify_sim_and_mower_and


13

मैं उसी विधि का उपयोग करता हूं, जो चालूप द्वारा सुझाई गई है,

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 क्रिएटर क्या करता है जब शैडो बिल्ड का उपयोग किया जाता है (वे एक नया प्रोजेक्ट खोलते समय डिफ़ॉल्ट रूप से सक्षम होते हैं)।

प्रत्येक अलग बिल्ड लक्ष्य और प्रकार के लिए, दाईं 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 ...

फिर यह निर्माण निर्देशिका में makefiles उत्पन्न करता है, और फिर make इसके तहत फाइलें भी उत्पन्न करेगा। अलग-अलग संस्करणों के मिश्रित होने का कोई खतरा नहीं है, जब तक कि क्यूमेक को स्रोत निर्देशिका में कभी नहीं चलाया जाता है (यदि यह है, तो इसे अच्छी तरह से साफ करें!)।

और जब ऐसा किया जाता है, तो .proवर्तमान में स्वीकृत उत्तर की फ़ाइल और भी सरल है:

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

एक ही परियोजना के लिए ठीक काम करता है, लेकिन अगर आपके पास एक परियोजना और एक पुस्तकालय है तो क्या होगा? फिर आपको लाइब्रेरी एफैक्स को शामिल करने का एक बिल्ड-डिपेंडेंट-डिपेंडेंट तरीका चाहिए।
एडवरसस

@ विज्ञापन मुझे यकीन नहीं है कि आप वास्तव में क्या मतलब है, लेकिन शायद Qmake चर $(OUT_PWD)समाधान है?
हाइड

जब मैं अपने प्रश्न को आपके उदाहरण पर लागू करता हूं तो यह बन जाता है: आवेदन लेने के लिए सबसे साफ तरीका क्या है mylib? मुझे यह पसंद है अगर ऐसा करने के लिए एक "सुशोभित" तरीका होगा, मुझे अन्य उत्तरों से तकनीकों का उपयोग करने के अलावा कोई रास्ता नहीं दिखाई देता है: LIBSएक स्मार्ट तरीके से भरने के लिए बिल्ड प्रकार और कॉन्फ़िगरेशन का उपयोग करें , अशक्त छाया निर्माण का लाभ।
एडवर्सस

@ Adversus यदि mylib एक ही शीर्ष स्तर की परियोजना के तहत उप-प्रोजेक्ट परियोजना है, तो मैं आमतौर पर एक mylib.pri फ़ाइल जोड़ूंगा, और सब कुछ अन्य सबडिर प्रोजेक्ट्स को वहां रख सकता हूं, Qmake चरों का उपयोग करके पथ को हमेशा सही पाने के लिए, भले ही वह शैडो बिल्ड हो। तब अन्य उप-प्रॉप .pro फाइलों में बस होगाinclude(../mylib/mylib.pri)
हाइड करें

धन्यवाद, यह इस तरह का है जो मैं अभी कर रहा हूं, यह एक समाधान होना अच्छा है जहां इस पर ऑटो-देखभाल की जाती है, जैसे कि जब आपके पास सीमेक में सबप्रोजेक्ट्स के साथ एक परियोजना है और फिर आसानी से अलग-अलग कर सकते हैं- स्रोत पूरे पेड़ का निर्माण करता है।
एडवर्सस

3

आउटपुट निष्पादन योग्य के लिए थोड़ा अलग नाम रखना भी उपयोगी है। आप कुछ का उपयोग नहीं कर सकते हैं:

release: Target = ProgramName
debug: Target = ProgramName_d

यह काम क्यों नहीं करता स्पष्ट नहीं है, लेकिन यह नहीं करता है। परंतु:

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

यह तब तक काम करता है जब तक कि यह CONFIG +=लाइन पहले से न हो जाए।


1

क्यूटी क्रिएटर के नए संस्करण में डिबग और रिलीज़ के बीच एक "प्रोफ़ाइल" बिल्ड विकल्प भी है। यहां बताया गया है कि मैं कैसे पता लगा रहा हूं:

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

यह विभिन्न डिबग / रिलीज़ आउटपुट निर्देशिकाओं के लिए मेरा मेकफाइल है। इस मेकफाइल को उबंटू लाइनक्स पर सफलतापूर्वक परीक्षण किया गया था। यह विंडोज पर मूल रूप से काम करना चाहिए बशर्ते कि मिंगव-डब्ल्यू 64 सही ढंग से स्थापित हो।

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$@
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.