2010-08-31 17 views
13

Abbiamo una base di codice abbastanza grande. La maggior parte del codice è compilata usando qmake per produrre i makefile. Tuttavia, alcuni sottoprogetti vengono generati eseguendo file batch o eseguendo altri programmi.Esecuzione di un programma/script da QMake

Mi piacerebbe essere in grado di avere tutto compilato usando qmake, ma non riesco a capire come ottenere qmake per eseguire semplicemente uno script.

Una cosa che ho provato è usare QMAKE_EXTRA_TARGETS nel mio file pro, in questo modo:

TEMPLATE = lib 
SOURCES = placeholder.cpp 
CONFIG += no_link staticlib 
batch_runner.target = placeholder.cpp 
batch_runner.commands = my_batch_file.bat 
QMAKE_EXTRA_TARGETS = batch_runner 

Ho poi avere il file batch prodotti placeholder.cpp in questo modo:

# do the real work here 
# ... 
# create placeholder.cpp so qmake and nmake are happy 
echo // dummy >> placeholder.cpp 

Sembra funzionare bene. Il problema è che è un po 'ingarbugliato. Se non specifichi batch_runner.target (cioè lo lascio in bianco) o non metti placeholder.cpp in SOURCES, il file batch non viene mai eseguito. Questo perché qmake non sta facendo batch_runner.commanda l'azione per qualsiasi altra dipendenza nel Makefile.

C'è un modo migliore per ottenere QMake per costruire un Makefile in modo che uno script venga eseguito quando viene eseguito il Makefile?

risposta

14

Sembra QMAKE_POST_LINK funziona bene per questo genere di cose.

Questo sembra portare a termine il lavoro. my_batch_file.bat viene eseguito quando nmake viene eseguito (anziché quando qmake viene eseguito) e non è necessario fare nulla di divertente con i target segnaposto o i file.

È probabile che non abbia bisogno di tutti gli elementi elencati in "CONFIG".

TEMPLATE = lib 
TARGET = 
CONFIG += no_link target_predeps staticlib 

QMAKE_POST_LINK = my_batch_file.bat 
QMAKE_CLEAN  += batch_output.obj 
6

Provare il system() command. Ad esempio:

system(pwd) 
+1

Interessante. Funziona, ma il comando viene eseguito quando viene eseguito 'qmake' piuttosto che quando viene eseguito 'nmake'. Capita anche di essere eseguito tre volte piuttosto che una volta dovrebbe essere effettivamente eseguito. –

+1

Potrebbe essere necessario aggiungere un ambito per garantire che venga eseguito una sola volta. –

+0

Ho appena aggiunto l'ambito all'esempio in modo che il comando venga eseguito una sola volta quando viene eseguito qmake. – pixelgrease

1

È possibile utilizzare la configurazione SUBDIRS per eseguire più destinazioni diverse, anche dallo stesso makefile. Questo potrebbe funzionare particolarmente bene con i tuoi obiettivi extra, in quanto una configurazione di subdir può specificare un target specifico nel makefile da eseguire (vedi undocumented qmake per i dettagli). In questo caso, inserirò tutti i comandi di compilazione "normali" in un file .pro, i comandi di compilazione esterni in un altro e un file .pro sottodirectory per crearli tutti. Non ho provato nulla del genere, ma dovrebbe funzionare.

regular.pro:

SOURCES += main.cpp 
TARGET = regular.exe 

external.pro:

batch_runner.commands = my_batch_file.bat 
QMAKE_EXTRA_TARGETS += batch_runner 

other_runner.commands = other_batch_file.bat 
QMAKE_EXTRA_TARGETS += other_runner 

do_it_all.pro:

TEMPLATE = subdirs 
CONFIG += ordered 

regular.file = regular.pro 
SUBDIRS += regular 

batch.file = external.pro 
batch.target = batch_runner 
SUBDIRS += batch 

other.file = external.pro 
other.target = other_runner 
SUBDIRS += other 
+0

Questo ha lo stesso problema che ho descritto nella mia domanda originale. Il target extra non verrà eseguito a meno che il .target non sia specificato (non puoi semplicemente specificare i comandi) e il .target deve essere effettivamente richiesto da qualche altra parte del Makefile, altrimenti non verrà eseguito. –

5

Ecco un'altra soluzione:

TEMPLATE = aux 
OBJECTS_DIR = ./ 
DESTDIR = ./ 

first.commands = my_batch_file.bat 
QMAKE_EXTRA_TARGETS += first 
QMAKE_CLEAN += batch_output.obj 

Il modello aux produce fondamentalmente un makefile che non fa niente quando viene eseguito senza specificare un bersaglio.Le variabili OBJECTS_DIR e DESTDIR sono impostate sulla directory corrente per impedire che qmake crei le directory debug e release (è importante impostarle su ./ e non solo su ., almeno su Windows). Quindi, usando QMAKE_EXTRA_TARGETS, ridefiniremo il target first per eseguire il comando personalizzato quando il makefile è invocato senza target.

È un po 'hacky ma fa il lavoro.

Aggiunta: Se si vuole evitare che la generazione di tre makefiles (Makefile, Makefile.Debug, Makefile.Release), è possibile aggiungere

CONFIG -= debug_and_release 

Tuttavia, se si utilizza questo ea seconda di come il makefile è invocato (sempre invocato manualmente, invocato dai "sottodirectory" * .pro file della directory madre, ...), potrebbe essere necessario creare falsi valori debug e release per evitare errori "nessuna regola per rendere la destinazione ...". Ad esempio:

release.target = release 
release-clean.target = release-clean 
release-install.target = release-install 
[...] 
debug.target = debug 
debug-clean.target = debug-clean 
debug-install.target = debug-install 
[...] 
QMAKE_EXTRA_TARGETS += release release-clean release-install [...] 
QMAKE_EXTRA_TARGETS += debug debug-clean debug-install [...]