36

我已经看到了一些建议,但没有什么对我真正有用。我只需要将文件复制到所需的目标目录。

例如,从这个答案说

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
4

6 回答 6

44

选择的答案是正确的,但它需要调用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

Whererequired_files必须替换为您的正确路径。$$PWD是当前.pro文件的路径,你可能不需要这个。

注意:我在这里找到了这个解决方案。我建议阅读整篇文章,因为它解释了它是如何工作的。

于 2016-04-05T22:55:42.910 回答
19

有幸为此浪费了几个小时,我想我会分享我对此事的发现。这是 Paglian 方法的修改变。由于我使用的是 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 的子文件夹中结束(debugrelease,至少在使用带有 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,而不是在调试子目录中。这意味着您例如不能做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 上)查看编译输出。

于 2016-08-30T18:10:14.067 回答
14

这就是我们在 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 仅为其中之一构建时。

于 2013-09-28T12:10:11.497 回答
3

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

于 2013-09-28T12:05:53.730 回答
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}")
于 2017-03-16T17:07:51.230 回答
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

但是,我还有一个问题,如果更改了如何复制?因为不需要复制需要太多时间。

于 2019-10-25T10:59:45.643 回答