QMake .pro dosyasında farklı Debug / Release çıktı dizinleri nasıl belirtilir


106

Bir Qt projem var ve derleme dosyalarını kaynak ağacının dışında çıkarmak istiyorum.

Şu anda aşağıdaki dizin yapısına sahibim:

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

Yapılandırmaya bağlı olarak (hata ayıklama / yayınlama), sonuçta ortaya çıkan dosyaları build / debug veya build / release dizinleri altındaki build dizininde çıkarmak isterim.

Bunu bir .pro dosyası kullanarak nasıl yapabilirim?


Qt'nin hata ayıklamayı ele alma ve derlemeleri yayınlama yöntemi zaman içinde dahili olarak değişti. Böylece, hata ayıklama ve yayınlama arasındaki önceki çalışma anahtarlarının sonraki sürümlerde kırıldığını keşfettik. Şimdiye kadar tüm platformlarda ve tüm Qt sürümlerinde çalışan çözümüme bakın. stackoverflow.com/questions/32046181/…
adlag

2
Bu eski bir soru olduğu için , çok daha az oyla daha iyi cevaplar olduğuna işaret etmeye değer .
wardw

Yanıtlar:


4

Kısa cevap: yapmıyorsun .

Kaçmalısın qmakeardından makeiçeri yapı istediğini inşa dizin içinde. Yani, bir kez çalıştırmak debugbir kez, dizine releasedizine.

Bu, projenizi oluşturan herhangi birinin onun çalışmasını bekler ve Qt'nin kendisi de bu şekilde kurulur, Qt Creator .prodosyanızın da böyle davranmasını bekler : basitçe başlar qmakeve ardından makehedefinizin seçilen yapılandırması için derleme klasöründe.

Bu klasörleri oluşturmak ve içlerinde iki (veya daha fazla) yapıyı gerçekleştirmek istiyorsanız, muhtemelen qmake aracılığıyla üst düzey bir proje dosyasından oluşturulmuş üst düzey bir makefile'a ihtiyacınız olacaktır.

İkiden fazla yapı konfigürasyonuna sahip olmak alışılmadık bir durum değildir, bu nedenle gereksiz yere kendinizi yalnızca bir yapı ve bir sürüm arasında ayrım yapmaya adarsınız; farklı optimizasyon seviyelerine sahip yapılarınız olabilir, vb . Hata ayıklama / serbest bırakma ikilemi en iyisi huzur içinde yatmaktır.


152

Qt projem için, bu şemayı * .pro dosyasında kullanıyorum:

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

Basit ama güzel! :)


18
Tam ihtiyacım olan şey! Ve bir not: Yalnızca tanımlamak etrafında geçmek için bile İşleri kolaylaştırmak için DESTDIRşartlı s, ardından diğer tüm yolları bu değeri kullanın: OBJECTS_DIR = $${DESTDIR}/.obj. Şerefe!
Xavier Holt

4
Bunun nasıl kullanıldığını / ne işe yaradığını açıklamayı düşünüyor musunuz? Bunu uyguladığımda hiçbir etkisi yok gibi görünüyor. edit: Debug'ı debug olarak değiştirirsem (küçük harf) çalışır. Bunun Windows vs unix büyük / küçük harf duyarlılığı olgusundan şüpheleniyorum.
notlesh

9
Windows'ta çalıştığı için oy verdim. Linux'ta (Ubuntu 15.04, Qt 5.5.0) ' Debuga debugve' a Releasegeçmek zorunda kaldım release.
Jepessen

Ne? Çapraz platform için bu kadar çok şey var mı? @Jepessen ??
Nils

2
Bu yalnızca CONFIG'de ya sürümünüz ya da hata ayıklamanız olduğunda çalışır. Her ikisi de yapılandırmadaysa, ikincisi kullanılacaktır.
weeska

52

Hedef dll / exe dizinini değiştirmek için, bunu pro dosyanızda kullanın:

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

Nesne dosyaları ve moc dosyaları gibi diğer yapı hedeflerinin dizinlerini de değiştirmek isteyebilirsiniz ( ayrıntılar için qmake değişken başvurusunu veya qmake CONFIG () işlev başvurusunu kontrol edin ).


5
Ama buna $$ OUT_PWD eklemeyi çok daha hoş buldum, bu yüzden DESTDIR = $$ OUT_PWD / hata ayıklama
Ivo

1
@Ivo: Ah! Teşekkür ederim! Hangi değişkenin bu yolu içerdiğini her yerde arıyordum! : D
Cameron

1
Bunlardan sonra, çizgiler gibi ekleyebilirsiniz: OBJECTS_DIR = $$DESTDIR/.obj MOC_DIR = $$DESTDIR/.moc RCC_DIR = $$DESTDIR/.qrc UI_DIR = $$DESTDIR/.ui CONFIG()dönüşler dışarı kullanmanın bazı sorunları çözmek için release:vedebug:
Carson Ip

Bu, seçilen cevaptan daha iyi çalıştı. Seçileni çalışır, ancak hem hata ayıklama hem de bırakma yapılandırılırsa, ikinci ayar bloğu kalır.
Paulo Carvalho

42

Daha kompakt bir yaklaşımım var:

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
Cevabınız, derleyici derleme çıktısını ayrı bir dizine koymanın daha yeni bir yoludur.
SIFE

1
bunu son zamanlarda hem hata ayıklama hem de sürüm için denediniz mi? derleme çıktım, hangi yapılandırma olursa olsun, her zaman sürüm klasöründe bitiyor gibi görünüyor; qmake / Qt Creator davranışı, bu yanıtı gönderdikten sonra değişmiş olabilir ...
ssc

1
Qmake'nin ek argümanlarına Release modunda "CONFIG - = debug" eklemeyi deneyin
Merhaba W

17

Bunu yapmanın doğru yolu şudur (teşekkürler QT Destek Ekibi):

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

Daha fazla bilgi burada: 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.3F_is_the_2nd


13

Chalup tarafından önerilen aynı yöntemi kullanıyorum,

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

Eski soru, ama yine de güncel bir cevaba değer. Günümüzde, gölge yapılar kullanıldığında Qt Creator'ın yaptığı şeyi yapmak yaygındır (yeni bir proje açarken varsayılan olarak etkinleştirilirler).

Her farklı derleme hedefi ve türü için, doğru qmake, farklı bir yapı dizininde doğru bağımsız değişkenlerle çalıştırılır. O zaman bu sadece basit bir şekilde inşa edilmiştir make.

Yani hayali dizin yapısı şöyle görünebilir.

/
|_/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

Ve önemli olan şey, qmakeinşa dizininde a çalıştırılmasıdır:

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

Daha sonra derleme dizininde makefiles oluşturur ve makebunun altında da dosyalar üretir. Qmake asla kaynak dizinde çalıştırılmadığı sürece farklı sürümlerin karışması riski yoktur (eğer öyleyse, daha iyi temizleyin!).

Ve böyle yapıldığında .pro, şu anda kabul edilen cevabın dosyası daha da basittir:

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

Tek bir proje için iyi çalışıyor, peki ya bir projeniz ve bir kütüphaneniz varsa? O halde, kütüphane afaiklerini dahil etmenin yapı türüne bağlı bir yoluna ihtiyacınız var.
Adversus

@Adversus Tam olarak ne demek istediğinizden emin değilim, ancak Qmake değişkeni $(OUT_PWD)çözüm olabilir mi?
hyde

Sorumu örneğinize uyguladığımda şu olur: Bir uygulamanın alması için en temiz yol mylibnedir? Bunu yapmanın "zarif" bir yolu olsaydı, diğer yanıtlardaki teknikleri kullanmaktan başka bir yol görmüyorum: LIBSakıllıca doldurmak için derleme türünü ve yapılandırmayı kullanın , geçersiz kılın gölge yapısının avantajı.
Adversus

@Adversus mylib, aynı üst düzey proje altındaki alt dizin projesiyse, genellikle bir mylib.pri dosyası eklerim ve gölge yapı olsa bile yolları her zaman doğru bir şekilde elde etmek için Qmake değişkenlerini kullanarak diğer alt dizin projelerinin ihtiyaç duyduğu her şeyi oraya koyardım. Daha sonra, diğer alt dizin .pro dosyalarınainclude(../mylib/mylib.pri)
hyde

teşekkürler, şu anda yaptığım şey bu, bunun otomatik olarak halledildiği bir çözüme sahip olmak güzel olurdu, örneğin cmake'da alt projeleri olan bir projeniz varsa ve sonra kolayca farklı şeyler yapabiliyorsanız. tüm ağacın kaynağı oluşturur.
Adversus

3

Yürütülebilir çıktı için biraz farklı bir ada sahip olmak da yararlıdır. Şunun gibi bir şey kullanamazsınız:

release: Target = ProgramName
debug: Target = ProgramName_d

Neden işe yaramadığı net değil, ama olmuyor. Fakat:

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

Bu, CONFIG +=satır önünden geçtiği sürece çalışır.


1

Qt Creator'ın yeni sürümü, hata ayıklama ve yayınlama arasında bir "profil" oluşturma seçeneğine de sahiptir. Bunu şu şekilde tespit ediyorum:

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

0

1. CONFIG'de Hata Ayıklama / Bırakma Bulun

Geçerli olanı alın (hata ayıklama | yayın).

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

(Birden çok olabilir, bu nedenle derlemede yalnızca son belirtilenleri koruyun):

2. DESTDIR'i ayarlayın

Yapı alt dizin adına sahip kullanın

DESTDIR = $$PWD/build/$$build_subdir

0

Bu, farklı hata ayıklama / yayın çıkış dizinleri için benim Makefile dosyam. Bu Makefile, Ubuntu linux üzerinde başarıyla test edildi. Mingw-w64 doğru bir şekilde kurulduğu takdirde Windows üzerinde sorunsuz çalışmalıdır.

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$@
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.