簡體   English   中英

用Qt編譯項目后復制一個文件到build目錄

[英]Copy a file to build directory after compiling project with Qt

我已經看到了一些建議,但沒有什么真正對我有用。 我只需要將文件復制到所需的目標目錄。

說,例如從這個答案

install_it.path = %{buildDir}
install_it.files += %{sourceDir}/settings.ini

INSTALLS += install_it

變量%{buildDir}%{sourceDir}應該被定義,以完成這項工作。 好的, %{sourceDir}沒有問題:它只是. . 但是我怎樣才能得到%{buildDir}

編輯1

說,我在這里有一個項目my_project

/path/to/my_project

所以,發布構建路徑是這樣的: /path/to/my_project-build-Desktop-release

調試構建路徑是這樣的: /path/to/my_project-build-Desktop-debug

我有文件要復制到這里的目標目錄: /path/to/my_project/copy_to_install_dir

所以,我希望在發布構建時將/path/to/my_project/copy_to_install_dir所有文件復制到/path/to/my_project-build-Desktop-release 並且,調試構建的方式相同。

我找不到包含完整目標路徑的變量,即用於調試構建的/path/to/my_project-build-Desktop-release

以防萬一:我使用 Windows,但無論如何我正在尋找跨平台解決方案。

編輯2

確切的解決方案,對於未來的讀者:

install_it.path = $$OUT_PWD
install_it.files = copy_to_install_dir/*

INSTALLS += \
    install_it

選擇的答案是正確的,但它需要調用make install ,在我看來這很煩人或容易出錯。 相反,要將文件復制到構建目錄,請使用:

copydata.commands = $(COPY_DIR) $$PWD/required_files $$OUT_PWD
first.depends = $(first) copydata
export(first.depends)
export(copydata.commands)
QMAKE_EXTRA_TARGETS += first copydata

其中required_files必須替換為您的正確路徑。 $$PWD是當前.pro文件的路徑,你可能不需要這個。

注意:我在這里找到了這個解決方案。 我建議閱讀整篇文章,因為它解釋了它是如何工作的。

有幸浪費了幾個小時,我想我會分享我對此事的發現。 這是 Paglian 方法的修改變體here 由於我使用的是 windows(沒有 mingw),因此該方法不起作用。 所以這是修改后的變體:

# using shell_path() to correct path depending on platform
# escaping quotes and backslashes for file paths
copydata.commands = $(COPY_FILE) \"$$shell_path($$PWD\\archive.png)\" \"$$shell_path($$OUT_PWD)\"
first.depends = $(first) copydata
export(first.depends)
export(copydata.commands)
QMAKE_EXTRA_TARGETS += first copydata

由於這使其跨平台,您當然也可以在 Linux、MacOS 或您擁有的任何設備中使用此方法。 不要請注意,我復制一個文件,所以不是$(COPY_DIR)我使用$(COPY_FILE) 根據需要進行調整。


如果您希望將文件復制到二進制文件結束的確切路徑(因為二進制文件最終將位於 $$OUT_PWD 的子文件夾中(調試發布,至少在使用帶有 MSVC 14/cdb 的 Qt Creator 構建時) .exe/Code::Blocks Makefiles 配置)你需要這個:

# adapted from https://stackoverflow.com/a/2581068
CONFIG(debug, debug|release) {
    VARIANT = debug
} else {
    VARIANT = release
}

請注意,即使二進制文件最終位於子文件夾中,QtCreator 也會從$$OUT_PWD OUT_PWD 執行二進制文件,因此它希望在$$OUT_PWD找到文件資源,而不是調試$$OUT_PWD 例如,這意味着您不能執行QIcon("archive.png")並期望它在可執行文件之外找到它。

這當然很容易通過以下方式解決:

QDir exeDir(QCoreApplication::applicationDirPath());
QIcon qIcon(exeDir.filePath("archive.png"));

如果你決定這是你想要的,你顯然需要像這樣編輯$$(COPY_FILE) (在 .pro 中)的最后一個參數: \\"$$shell_path($$OUT_PWD)\\\\$$VARIANT\\"


需要注意的另一件事是(在我的情況下)Qt Creator (4.0.1) 並不總是構建 .pro 文件,因為它沒有檢測到配置中的任何更改,因此將上述更改反映在 Makefile 中(因此在構建項目時運行)您必須通過從應用程序菜單運行Build->run qmake來手動構建 .pro。 為確保一切順利,請按 Alt+4(無論如何在 Windows 上)查看編譯輸出。

這是我們在 QtSerialPort 中使用的:

target_headers.files  = $$PUBLIC_HEADERS
target_headers.path   = $$[QT_INSTALL_HEADERS]/QtSerialPort
INSTALLS              += target_headers

mkspecs_features.files    = $$QTSERIALPORT_PROJECT_ROOT/src/serialport/qt4support/serialport.prf
mkspecs_features.path     = $$[QT_INSTALL_DATA]/mkspecs/features
INSTALLS                  += mkspecs_features

基本上,您設置目標的文件和路徑,然后將其附加到INSTALLS變量中。 您仍然需要的是$$OUT_PWD變量,我們也在QtSerialPort廣泛使用QtSerialPort 這將為您提供構建目錄的根目錄。

它是那些未記錄的 qmake 功能之一,但它非常有用。

此外,對於一般的源目錄,您不應該假設“。” 等等,因為當您運行包含“.”的包裝器應用程序時,這可能會有所不同。 將指向那個而不是你所期望的:qmake 源項目根。 在這些情況下,使用指向源的PWD變量而不是指向構建文件夾的OUT_PWD更安全。

只是為了粗略地舉例說明這兩個變量與現實世界場景的區別,在這里您可以找到我們在 QtSerialPort 中所做的事情:

system("echo QTSERIALPORT_PROJECT_ROOT = $$PWD >> $$OUT_PWD/.qmake.cache")
system("echo QTSERIALPORT_BUILD_ROOT = $$OUT_PWD >> $$OUT_PWD/.qmake.cache")

其中前者是源項目的根目錄,后者是構建目錄。 它們可能相同,但在許多情況下它們不同,例如,當通過 QtCreator 僅針對其中之一進行構建時。

您可以使用 DESTDIR 和 PWD qmake 變量或 OUT_PWD: http ://qt-project.org/doc/qt-5.1/qmake/qmake-variable-reference.html#destdir

也許以下 QMake 代碼有助於作為起點。 它將最近構建的二進制文件復制到其他目錄“TARGET_DEST”:

TARGET_SRC  = $${_PRO_FILE_PWD_}
TARGET_DEST = $${PWD}/src

CONFIG(debug, debug|release) {
    TARGET_SRC = $${TARGET_SRC}/debug
} else {
    TARGET_SRC = $${TARGET_SRC}/release
}

TARGET_SRC   = $${TARGET_SRC}/$${TARGET}
TARGET_DEST  = $${TARGET_DEST}/$${TARGET}

linux-g++{
    if( equals(TEMPLATE, app) || equals(TEMPLATE, vcapp) ){
        # nothing to do here
    }
    if( equals(TEMPLATE, lib) || equals(TEMPLATE, vclib) ){
        TARGET_SRC   = $${TARGET_SRC}.so
        TARGET_DEST  = $${TARGET_DEST}.so
    }
    QMAKE_POST_LINK += $$quote(cp $${TARGET_SRC} $${TARGET_DEST}$$escape_expand(\n\t))
}

win32 {
    if( equals(TEMPLATE, app) || equals(TEMPLATE, vcapp) ){
        TARGET_SRC   = $${TARGET_SRC}.exe
        TARGET_DEST  = $${TARGET_DEST}.exe
    }
    if( equals(TEMPLATE, lib) || equals(TEMPLATE, vclib) ){
        TARGET_SRC   = $${TARGET_SRC}.dll
        TARGET_DEST  = $${TARGET_DEST}.dll
    }
    TARGET_SRC  ~= s,/,\\,g # fix slashes 
    TARGET_DEST ~= s,/,\\,g # fix slashes
    QMAKE_POST_LINK +=$$quote(cmd /c copy /y $${TARGET_SRC} $${TARGET_DEST}$$escape_expand(\n\t))
}

message("[INFO] Will copy $${TARGET_SRC} to $${TARGET_DEST}")

這是 PKSWE 方法的修改變體。

dummyTarget.commands = @echo After building copy..
QMAKE_EXTRA_TARGETS += dummyTarget
PRE_TARGETDEPS += dummyTarget

toolsCopy.commands = $(COPY_DIR) $$shell_path($$PWD/copyDir/*) $$shell_path($$DESTDIR)
dummyTarget.depends += toolsCopy
QMAKE_EXTRA_TARGETS += toolsCopy

toolsCopyLib.commands = $(COPY_FILE) $$shell_path($$PWD/setting.ini) $$shell_path($${DESTDIR})
dummyTarget.depends += toolsCopyLib
QMAKE_EXTRA_TARGETS += toolsCopyLib

但是,我還有一個問題,如果更改了如何復制? 由於不需要復制時花費了太多時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM