2010-04-05 10 views
91

Tengo un proyecto de Qt y me gustaría generar archivos de compilación fuera del árbol de fuentes.Cómo especificar diferentes directorios de salida de Debug/Release en el archivo .pro de QMake

que actualmente tiene la siguiente estructura de directorios:

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

Dependiendo de la configuración (debug/release), me gustaría dar salida a los archivos resultantes en el interior del directorio de construcción bajo construcción/depuración o los directorios de construcción/de liberación .

¿Cómo puedo hacer eso usando un archivo .pro?

+0

La forma en que Qt trata las versiones de depuración y liberación modificadas internamente a lo largo del tiempo. Así que descubrimos que los switches de trabajo anteriores entre depuración y liberación se rompieron en versiones posteriores. Vea mi solución que funciona en todas las plataformas y en todas las versiones de Qt hasta ahora. http://stackoverflow.com/questions/32046181/how-to-detect-qt-creators-target-debug-release-visual-studio/32048654#32048654 – adlag

Respuesta

134

Para mi proyecto Qt, que utilizan este esquema en el archivo * .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 

It `s sencilla, pero agradable! :)

+17

¡Justo lo que necesitaba! Y una nota: para hacer las cosas aún más fáciles de cambiar, solo defina su 'DESTDIR's condicionalmente, y luego use ese valor en todas sus otras rutas:' OBJECTS_DIR = $$ {DESTDIR} /. Obj'. ¡Aclamaciones! –

+4

¿Te importa explicar cómo se usa/qué hace? Parece que no tiene ningún efecto cuando lo implemento. * edit: * si cambio Debug para depurar (minúsculas), funciona. Sospecho que esto es una cosa de sensibilidad de mayúsculas y minúsculas frente a Windows. – notlesh

+7

Lo voté porque funciona en Windows. En Linux (Ubuntu 15.04, Qt 5.5.0) tuve que cambiar 'Debug' por' debug' y 'Release' por' release'. – Jepessen

42

Para cambiar el directorio de destino DLL/EXE, utilizar esto en su pro archivo:

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

Usted también puede cambiar directorios para otros tipos de generación como archivos de objetos y archivos moc (comprobar qmake variable reference para más detalles o qmake CONFIG() function reference).

+5

Pero me ha parecido mucho mejor incluir $$ OUT_PWD en esto, entonces DESTDIR = $$ OUT_PWD/debug – Ivo

+1

@Ivo: ¡Ah! ¡Gracias! ¡He estado buscando por todas partes qué variable contenía ese camino! : D – Cameron

+1

Después de esto, se puede añadir líneas como: 'OBJECTS_DIR = $$ DESTDIR/obj MOC_DIR = $$ DESTDIR/.moc RCC_DIR = $$ DESTDIR/.qrc UI_DIR = $$ DESTDIR/.ui' 'CONFIG()' resulta para resolver algunos problemas de uso de 'release:' y 'debug:' –

13

utilizo el mismo método sugerido por 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" 
} 
38

que tienen un enfoque más compacta:

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

Su respuesta es la forma más reciente de colocar la salida de compilación del compilador en un directorio separado. – SIFE

+1

¿Has probado esto recientemente tanto para depurar como para liberar? mi salida de compilación siempre parece terminar en la carpeta de lanzamiento, sin importar qué configuración; El comportamiento de qmake/Qt Creator puede haber cambiado desde que publicaste esta respuesta ... – ssc

+0

Intenta agregar "CONFIG - = debug" a los argumentos adicionales de qmake en el modo Release –

1

También es útil tener un nombre ligeramente diferente para el ejecutable de salida. No puede usar algo como:

release: Target = ProgramName 
debug: Target = ProgramName_d 

Por qué no funciona no está claro, pero no es así. Pero:

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

Esto funciona siempre y cuando la línea de CONFIG += precede.

+0

los nombres son al revés, pero funciona –

6

Pregunta anterior, pero todavía vale la pena una respuesta actualizada. Hoy es común hacer lo que hace Qt Creator cuando se usan compilaciones de sombreados (están habilitadas por defecto al abrir un nuevo proyecto).

Para cada destino y tipo de compilación diferente, se ejecuta el derecho qmake con los argumentos correctos en un directorio de compilación diferente. Entonces eso acaba de construirse con simple make.

Por lo tanto, la estructura de directorios imaginarios podría verse así.

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

Y lo más improtante es, un qmake se ejecuta en el directorio de construcción:

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

Entonces se genera archivos make en el directorio de construcción, y luego make generará los archivos bajo él también. No hay riesgo de que se mezclen versiones diferentes, siempre y cuando qmake nunca se ejecute en el directorio de origen (si es así, mejor ¡límpielo bien!).

Y cuando se hace así, el archivo .pro de la respuesta aceptada actualmente es aún más simple:

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

Works bien para un solo proyecto, pero ¿y si tienes un proyecto y una biblioteca? Entonces necesita una forma dependiente de buildtype de incluir los elementos de la biblioteca. – Adversus

+0

@Adversus No estoy seguro de qué quiere decir exactamente, pero quizás la variable Qmake '$ (OUT_PWD)' ¿es la solución? – hyde

+0

Cuando aplico mi pregunta a su ejemplo, se convierte en: ¿cuál es la forma más limpia para que una aplicación recoja 'mylib'? Me gustaría que hubiera una manera "elegante" de hacer esto, no veo otra manera que usar las técnicas de las otras respuestas: use el tipo de compilación y config para llenar 'LIBS' en un dispositivo inteligente. manera, anulando la ventaja de la construcción de la sombra. – Adversus

9

La forma correcta de hacerlo es la siguiente (gracias QT equipo de apoyo):

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 

Más información aquí: 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

+0

¡Muy buen punto! :) – Tarod

0

La respuesta corta es: usted no.

debería ejecutar qmake seguido por make en cualquier directorio de construcción se quiere construir. Por lo tanto, se ejecuta una vez en un directorio debug, una vez en un directorio release.

Eso es como cualquier construcción de su proyecto sería esperar que funcione, y así es como Qt sí está configurado para construir, eso es también la forma en Qt Creator espera su archivo .pro comportarse, sino que sólo comienza qmake y luego make en la carpeta de compilación para la configuración elegida de tu objetivo.

Si desea crear estas carpetas y realizar las dos (o más) compilaciones en ellas, necesitará un archivo make de nivel superior, posiblemente creado a partir de un archivo de proyecto de nivel superior a través de qmake.

No es raro tener más de dos configuraciones de compilación, por lo que se compromete innecesariamente a solo diferenciar entre una compilación y una versión; es posible que tenga compilaciones con diferentes niveles de optimización, etc. La dicotomía de depuración/liberación es mejor dejarla en paz.

0

La nueva versión de Qt Creator también tiene una opción de compilación de "perfil" entre la depuración y la versión. Así es como estoy detectando eso:

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