使用Qt编译项目后,将文件复制到构建目录

时间:2013-09-28 11:49:07

标签: qt qmake

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

比如来自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

6 个答案:

答案 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

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

相关问题