2010-10-21 13 views

risposta

19

Ecco un esempio di uno dei nostri progetti. Mostra come copiare i file su DESTDIR per Windows e Linux.

linux-g++{ 
    #... 
    EXTRA_BINFILES += \ 
     $${THIRDPARTY_PATH}/gstreamer-0.10/linux/plugins/libgstrtp.so \ 
     $${THIRDPARTY_PATH}/gstreamer-0.10/linux/plugins/libgstvideo4linux2.so 
    for(FILE,EXTRA_BINFILES){ 
     QMAKE_POST_LINK += $$quote(cp $${FILE} $${DESTDIR}$$escape_expand(\n\t)) 
    } 
} 

win32 { 
    #... 
    EXTRA_BINFILES += \ 
     $${THIRDPARTY_PATH}/glib-2.0/win32/bin/libglib-2.0.dll \ 
     $${THIRDPARTY_PATH}/glib-2.0/win32/bin/libgmodule-2.0.dll 
    EXTRA_BINFILES_WIN = $${EXTRA_BINFILES} 
    EXTRA_BINFILES_WIN ~= s,/,\\,g 
     DESTDIR_WIN = $${DESTDIR} 
    DESTDIR_WIN ~= s,/,\\,g 
    for(FILE,EXTRA_BINFILES_WIN){ 
       QMAKE_POST_LINK +=$$quote(cmd /c copy /y $${FILE} $${DESTDIR_WIN}$$escape_expand(\n\t)) 
    } 
} 
+1

Come può essere corretto? Su Linux Qt5.2.0 '$$ {DESTDIR}' si espande nella stringa vuota. Il percorso per '$ {FILE}' è relativo alla directory di build, non alla directory di origine. – Cuadue

11

Se si utilizza make install, è possibile utilizzare il INSTALLS variable of qmake. Ecco un esempio:

images.path = $${DESTDIR}/images 
images.files += images/splashscreen.png 
images.files += images/logo.png 
INSTALLS  += images 

poi eseguire 'make install'

+0

Posso in qualche modo chiamare automaticamente "make install" in QT Creator ogni volta che costruisco? Mi piace questo approccio indipendente dalla piattaforma, ma voglio che alcuni (pochi) file vengano sempre copiati ogni volta che costruisco in QT Creator. –

+1

@HorstWalter: controlla la variabile QMAKE_POST_LINK. È possibile definire un comando personalizzato da eseguire. In particolare, tuttavia, dice che alcuni backend non lo supportano, quindi non so come sarebbe cross-platform. Se i file sono sempre in giro, puoi anche creare un target personalizzato e rendere il file eseguibile risultante dipendente dal target personalizzato, che copierà quei file. –

42

È possibile utilizzare una funzione di qmake per la riusabilità:

# Copies the given files to the destination directory 
defineTest(copyToDestdir) { 
    files = $$1 

    for(FILE, files) { 
     DDIR = $$DESTDIR 

     # Replace slashes in paths with backslashes for Windows 
     win32:FILE ~= s,/,\\,g 
     win32:DDIR ~= s,/,\\,g 

     QMAKE_POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\\n\\t) 
    } 

    export(QMAKE_POST_LINK) 
} 

quindi utilizzarlo come segue:

copyToDestdir($$OTHER_FILES) # a variable containing multiple paths 
copyToDestdir(run.sh) # a single filename 
copyToDestdir(run.sh README) # multiple files 
+13

Solo una nota: ho usato '$$ OUT_PWD' invece di' $$ DESTDIR' per farlo funzionare. Per il riferimento '$$ OUT_PWD' è la cartella su cui è costruito il programma, e' $$ PWD' è la cartella da cui viene costruito il programma - in altre parole è dove si trova il file .pro. – Logan

+0

Perché questo ha 'defineTest' invece di' defineReplace'? Non ho potuto ottenere qmake per costruire questo con 'defineReplace', ma non capisco perché. I [docs] (http://doc.qt.io/qt-5/qmake-language.html#test-functions) dicono che "Questo tipo di funzione dovrebbe essere usato solo nelle espressioni condizionali" che non è vero in questo Astuccio. – Phlucious

+0

Ho incontrato strani problemi di formattazione con la piattaforma MinGW quando è stato copiato più di un file. Ho dovuto modificare la riga 'QMAKE_POST_LINK' a' QMAKE_POST_LINK + = $$ QMAKE_COPY $$ preventivo ($$ FILE) $$ preventivo ($$ DDIR) $$ escape_expand (\\ n \\ t \\ n \\ t) 'Le nuove righe multiple erano necessarie perché un percorso di Windows può terminare con' \\ ', ma che sfugge alla linea e continua fino alla successiva. –

3

Ho trovato che dovevo modificare la risposta data da sje397. per Qt5 Beta1 insieme a QtCreator 2.5.2. Io uso questo script per copiare i file qml nella directory di destinazione come un passo aggiuntivo dopo che la compilazione è stata completata.

Il mio file .pro ha il seguente codice

OTHER_FILES += \ 
    Application.qml 

# Copy qml files post build 
win32 { 
    DESTDIR_WIN = $${DESTDIR} 
    DESTDIR_WIN ~= s,/,\\,g 
    PWD_WIN = $${PWD} 
    PWD_WIN ~= s,/,\\,g 
    for(FILE, OTHER_FILES){ 
     QMAKE_POST_LINK += $$quote(cmd /c copy /y $${PWD_WIN}\\$${FILE} $${DESTDIR_WIN}$$escape_expand(\\n\\t)) 
    } 
} 
unix { 
    for(FILE, OTHER_FILES){ 
     QMAKE_POST_LINK += $$quote(cp $${PWD}/$${FILE} $${DESTDIR}$$escape_expand(\\n\\t)) 
} 

}

Nota che uso uso $$ PWD_WIN di fornire il percorso completo del file sorgente per il comando di copia.

3

Creare un file copy_files.prf in uno dei percorsi che qmake utilizza per config features. Il file dovrebbe essere simile a questo:

QMAKE_EXTRA_COMPILERS += copy_files 
copy_files.name = COPY 
copy_files.input = COPY_FILES 
copy_files.CONFIG = no_link 

copy_files.output_function = fileCopyDestination 
defineReplace(fileCopyDestination) { 
    return($$shadowed($$1)) 
} 

win32:isEmpty(MINGW_IN_SHELL) { 
    # Windows shell 
    copy_files.commands = copy /y ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} 
    TOUCH = copy /y nul 
} 
else { 
    # Unix shell 
    copy_files.commands = mkdir -p `dirname ${QMAKE_FILE_OUT}` && cp ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} 
    TOUCH = touch 
} 

QMAKE_EXTRA_TARGETS += copy_files_cookie 
copy_files_cookie.target = copy_files.cookie 
copy_files_cookie.depends = compiler_copy_files_make_all 

win32:!mingw { 
    # NMake/MSBuild 
    copy_files_cookie.commands = $$TOUCH $** && $$TOUCH [email protected] 
} 
else { 
    # GNU Make 
    copy_files_cookie.commands = $$TOUCH $< && $$TOUCH [email protected] 
} 

PRE_TARGETDEPS += $${copy_files_cookie.target} 

Come funziona

La prima parte definisce un extra compiler, che leggerà i nomi dei file di input dalla variabile COPY_FILES. La parte successiva definisce la funzione che utilizzerà per sintetizzare un nome file di output corrispondente a ciascun input. Quindi definiamo i comandi utilizzati per richiamare questa "compilatore", a seconda di quale tipo di shell ci troviamo.

allora definiamo un extra makefile targetcopy_files.cookie, che dipende dal target compiler_copy_files_make_all. Quest'ultimo è il nome del target che qmake genera per il compilatore extra definito nel primo passaggio. Ciò significa che quando viene creato il target copy_files.cookie, verrà richiamato il compilatore aggiuntivo per copiare i file.

Specifichiamo un comando da eseguire da questa destinazione, che sarà touch i file copy_files.cookie e compiler_copy_files_make_all. Toccando questi file, ci assicuriamo che make non provi a copiare nuovamente i file a meno che i loro timestamp siano più recenti dei file toccati. Infine, aggiungiamo copy_files.cookie all'elenco delle dipendenze della destinazione make all.

Come usarlo

Nel file .pro, aggiungere copy_files alla CONFIG variabile:

CONFIG += copy_files 

quindi aggiungere i file alla variabile COPY_FILES:

COPY_FILES += docs/*.txt 
1

Come Oltre a Jake's answer e @Phlucious com si può usare la funzione qmake defineReplace che si adatta meglio a questo caso d'uso. Dopo aver utilizzato l'esempio fornito, ho riscontrato un problema, in cui qmake ha saltato l'ultima azione del link post che ho aggiunto. Questo potrebbe essere un problema con l'esportazione della variabile anche se il contenuto sembrava abbastanza bene tutto il tempo. Per farla breve, qui ist il codice modificato

defineReplace(copyToDir) { 
    files = $$1 
    DIR = $$2 
    LINK = 

    for(FILE, files) { 
     LINK += $$QMAKE_COPY $$shell_path($$FILE) $$shell_path($$DIR) $$escape_expand(\\n\\t) 
    } 
    return($$LINK) 
} 

Questa funzione generale di copia può essere utilizzato da alcune funzioni di convenienza come questo

defineReplace(copyToBuilddir) { 
    return($$copyToDir($$1, $$OUT_PWD)) 
} 

Il secondo prende un solo argomento (uno o più file) e fornisce un percorso fisso. Praticamente come nella risposta ai riferimenti.

Ma ora si noti la differenza invocazione

QMAKE_POST_LINK += $$copyToBuilddir(deploy.bat) 

Come si può vedere, è possibile collegare il comando tornato a QMAKE_PRE_LINK per una flessibilità ancora maggiore.

+0

Sì. vale la pena avere la versione con la directory di destinazione. Ne avevo bisogno anche perché DESTDIR non è sempre impostato. –

Problemi correlati