我已经看到了一些建议,但没有任何真正对我有用的东西。我只需要将文件复制到所需的目标目录。
比如来自this answer:
install_it.path = %{buildDir}
install_it.files += %{sourceDir}/settings.ini
INSTALLS += install_it
应该定义变量%{buildDir}
和%{sourceDir}
,以使其发挥作用。好的,%{sourceDir}
没有问题:它只是.
。但是我怎样才能获得%{buildDir}
?
EDIT1
说,我这里有一个项目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,但无论如何我正在寻找跨平台解决方案。
EDIT2
准确的解决方案,面向未来的读者:
install_it.path = $$OUT_PWD
install_it.files = copy_to_install_dir/*
INSTALLS += \
install_it
答案 0 :(得分:30)
所选答案是正确的,但需要拨打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
文件的路径,您可能不需要此文件。
注意:我找到了这个解决方案here。我建议阅读整篇文章,因为它解释了它的工作原理。
答案 1 :(得分:14)
有幸浪费了几个小时,我想我会就此事分享我的发现。这是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( debug 或发布的子文件夹中)结束,至少在用Qt Creator构建MSVC 14 / cdb.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
中找到文件资源,而不是 debug subdir。这意味着你可以做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上)看作编译输出。
答案 2 :(得分:12)
这就是我们在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
中广泛使用该变量。这将为您提供构建目录的根目录。
这是未记录的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建立其中一个时。
答案 3 :(得分:3)
您可以使用DESTDIR和PWD qmake变量或OUT_PWD:http://qt-project.org/doc/qt-5.1/qmake/qmake-variable-reference.html#destdir
答案 4 :(得分:3)
以下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}")
答案 5 :(得分:0)
这是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
但是,我还有另一个问题,如果更改了如何复制?,因为不需要复制会花费太多时间。