wake-up-neo.com

QMake - Wie kopiert man eine Datei in die Ausgabe?

Wie kann ich mit qmake eine Datei aus meinem Projekt in das Ausgabeverzeichnis kopieren?

Ich kompiliere unter Linux, aber in Zukunft werde ich es auf Mac und Windows kompilieren.

40
Raphael

Hier ist ein Beispiel aus einem unserer Projekte. Es zeigt, wie Sie Dateien für Windows und Linux in die Variable DESTDIR kopieren.

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))
    }
}
21
sje397

Sie können eine qmake-Funktion für die Wiederverwendbarkeit verwenden:

# 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)
}

dann verwenden Sie es wie folgt:

copyToDestdir($$OTHER_FILES) # a variable containing multiple paths
copyToDestdir(run.sh) # a single filename
copyToDestdir(run.sh README) # multiple files
47
Jake Petroules

Wenn Sie make install verwenden, können Sie die INSTALLS-Variable von qmake verwenden. Hier ist ein Beispiel:

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

dann make install ausführen.

13

Erstellen Sie eine Datei copy_files.prf in einem der Pfade, die qmake für config features verwendet. Die Datei sollte so aussehen:

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}

Wie es funktioniert

Der erste Teil definiert einen zusätzlichen Compiler , der die Dateinamen der Eingabedateien aus der COPY_FILES-Variablen liest. Der nächste Teil definiert die Funktion, mit der ein Ausgabedateiname synthetisiert wird, der jeder Eingabe entspricht. Dann definieren wir die Befehle, die zum Aufrufen dieses "Compilers" verwendet werden, abhängig von der Art der Shell, in der wir uns befinden.

Dann definieren wir ein zusätzliches Makefile-Zielcopy_files.cookie, das vom Ziel compiler_copy_files_make_all abhängt. Letzteres ist der Name des Ziels, das qmake für den zusätzlichen Compiler generiert, den wir im ersten Schritt definiert haben. Dies bedeutet, dass beim Erstellen des copy_files.cookie-Ziels der zusätzliche Compiler aufgerufen wird, um die Dateien zu kopieren.

Wir geben einen Befehl an, der von diesem Ziel ausgeführt werden soll, und touch die Dateien copy_files.cookie und compiler_copy_files_make_all. Durch das Berühren dieser Dateien stellen wir sicher, dass make nicht versucht, die Dateien erneut zu kopieren, es sei denn, ihre Zeitstempel sind aktueller als die berührten Dateien. Schließlich fügen wir copy_files.cookie zur Liste der Abhängigkeiten des make all-Ziels hinzu.

Verwendung

Fügen Sie in Ihrer .pro-Datei copy_files zur Variable CONFIG hinzu:

CONFIG += copy_files

Fügen Sie dann die Dateien der COPY_FILES-Variablen hinzu:

COPY_FILES += docs/*.txt
3
Oktalist

Ich fand, dass ich die Antwort von sje397 ändern musste. für Qt5 Beta1 zusammen mit QtCreator 2.5.2 . Ich verwende dieses Skript, um die qml-Dateien nach Abschluss des Builds als zusätzlichen Schritt in das Zielverzeichnis zu kopieren.

Meine .pro-Datei enthält den folgenden Code

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))
}

}

Beachten Sie, dass ich mit $$ PWD_WIN den vollständigen Pfad zur Quelldatei für den Kopierbefehl angeben kann.

3
eatyourgreens

Qt 5.6 hinzugefügt dies als nicht dokumentiertes Feature:

CONFIG *= file_copies

Erfassen Sie einen Namen, um die Dateien zu beschreiben, die Sie kopieren möchten:

COPIES += myDocumentation

Listen Sie die Dateien auf, die Sie kopieren möchten, in ihrem Member .files:

myDocumentation.files = $$files(text/docs/*.txt)

Geben Sie den Zielpfad im Member .path an:

myDocumentation.path = $$OUT_PWD/documentation

Geben Sie optional einen Basispfad an, der von den Quellpfaden abgeschnitten werden soll:

myDocumentation.base = $$PWD/text/docs

Im Grunde funktioniert es, wenn Sie die gleichen Dinge wie viele der anderen Antworten hier tun. Siehe file_copies.prf für die blutigen Details.

Die Schnittstelle ist der für INSTALLS sehr ähnlich.

1
Oktalist

Als Ergänzung zu Jakes Antwort und @Phlucious-Kommentar kann die Funktion qmake defineReplace verwendet werden, die für diesen Anwendungsfall besser geeignet ist. Nachdem ich das bereitgestellte Beispiel verwendet hatte, trat ein Problem auf, bei dem qmake die letzte hinzugefügte Link-Aktion übersprang. Dies könnte ein Problem beim Export der Variablen sein, obwohl der Inhalt die ganze Zeit ziemlich gut aussah. Lange Geschichte, hier ist der modifizierte Code

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)
}

Diese allgemeine Kopierfunktion kann von einigen Komfortfunktionen wie dieser verwendet werden

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

Die zweite nimmt nur ein Argument (eine oder mehrere Dateien) und stellt einen festen Pfad bereit. Ziemlich das gleiche wie in den Referenzen.

Man beachte nun aber den Unterschied beim Aufruf

QMAKE_POST_LINK += $$copyToBuilddir(deploy.bat)

Wie Sie sehen, können Sie den zurückgegebenen Befehl an QMAKE_PRE_LINK anhängen, um noch mehr Flexibilität zu erhalten.

1
maxik

definieren Sie zuerst irgendwo unten (was aus XD Rahmen besteht):

# --------------------------------------
# This file defines few useful functions
# --------------------------------------

#copyDir(source, destination)
# using "Shell_path()" to correct path depending on platform
# escaping quotes and backslashes for file paths
defineTest(copyDir) {
    #append copy command
    !isEmpty(xd_copydir.commands): xd_copydir.commands += && \\$$escape_expand(\n\t)
    xd_copydir.commands += ( $(COPY_DIR) \"$$Shell_path($$1)\" \"$$Shell_path($$2)\" || echo \"copy failed\" )
    #the qmake generated MakeFile contains "first" and we depend that on "xd_copydir"
    first.depends *= xd_copydir
    QMAKE_EXTRA_TARGETS *= first xd_copydir

    export(first.depends)
    export(xd_copydir.commands)
    export(QMAKE_EXTRA_TARGETS)
}

#copy(source, destination) (i.e. the name "copyFile" was reserved)
defineTest(copy) {
    #append copy command
    !isEmpty(xd_copyfile.commands): xd_copyfile.commands += && \\$$escape_expand(\n\t)
    xd_copyfile.commands += ( $(COPY_FILE) \"$$Shell_path($$1)\" \"$$Shell_path($$2)\" || echo \"copy failed\" )
    #the qmake generated MakeFile contains "first" and we depend that on "xd_copyfile"
    first.depends *= xd_copyfile
    QMAKE_EXTRA_TARGETS *= first xd_copyfile

    export(first.depends)
    export(xd_copyfile.commands)
    export(QMAKE_EXTRA_TARGETS)
}

und verwenden Sie es in Ihrem Projekt wie:

include($$PWD/functions.prf) #optional

copy($$PWD/myfile1.txt, $$DESTDIR/myfile1.txt)
copy($$PWD/README.txt, $$DESTDIR/README.txt)
copy($$PWD/LICENSE, $$DESTDIR/LICENSE)
copyDir($$PWD/redist, $$DESTDIR/redist) #copy "redist" folder to "$$DESTDIR"

beachten Sie, dass alle Dateien kopiert werden sollten, bevor der Link erstellt wird

0
Top-Master

Definieren Sie zunächst die folgenden beiden Funktionen zur Unterstützung von Windows/Unix.

defineReplace(nativePath) {
    OUT_NATIVE_PATH = $$1
    # Replace slashes in paths with backslashes for Windows
    win32:OUT_NATIVE_PATH ~= s,/,\\,g
    return($$OUT_NATIVE_PATH)
}

# Copies the given files to the destination directory
defineReplace(copyToDestDirCommands) {
    variable_files = $$1
    files = $$eval($$variable_files)
    DDIR = $$nativePath($$2)
    win32:DDIR ~= s,/,\\,g
    POST_LINK = echo "Copying files to $$DDIR" $$escape_expand(\\n\\t)

    win32 {
        POST_LINK += $$QMAKE_MKDIR $$quote($$DDIR) 2>&1 & set errorlevel=0 $$escape_expand(\\n\\t)
    }
    !win32 {
        POST_LINK += $$QMAKE_MKDIR -p $$quote($$DDIR) $$escape_expand(\\n\\t)
    }

    for(ORIGINAL_FILE, files) {
        FILE = $$nativePath($$ORIGINAL_FILE)
        POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\\n\\t)
    }

    return ($$POST_LINK)
}

Anschließend können Sie den folgenden Code verwenden, um die zuvor definierten Funktionen aufzurufen, um Dateien in einen bestimmten Ordner zu kopieren und das Verzeichnis bei Bedarf zu erstellen. Dies wird unter Win32 getestet, Linux-Tests sind willkommen.

BATOS_FILES = \
    $$BATOS_BIN_ROOT/batos-core.dll \
    $$BATOS_BIN_ROOT/batos-pfw.dll \
    $$BATOS_BIN_ROOT/dre.dll \
    $$BATOS_BIN_ROOT/log4qt.dll

QMAKE_POST_LINK += $$copyToDestDirCommands(BATOS_FILES, $$DESTDIR)

BATOS_PLUGINS_FILES = \
    $$BATOS_BIN_ROOT/plugins/com.xaf.plugin-manager.dll \
    $$BATOS_BIN_ROOT/plugins/org.commontk.eventadmin.dll

QMAKE_POST_LINK += $$copyToDestDirCommands(BATOS_PLUGINS_FILES, $$DESTDIR/plugins)
0
lygstate