[英]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.