首页 文章

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

提问于
浏览
24

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

比方说,例如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

5 回答

  • 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功能之一,但它非常有用 .

    此外,对于一般的源目录,您不应该假设"."等等,因为当您运行包装器应用程序时可能会有所不同,其中_1255203将指向该而不是您所期望的: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构建时只为其中一个 .

  • 29

    所选答案是正确的但它需要调用 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 文件的路径,您可能不需要这个 .

    Note :我找到了这个解决方案here . 我建议阅读整篇文章,因为它解释了它的工作原理 .

  • 12

    我有幸浪费了几个小时,我以为'd share my findings on the matter. This in a modified variant of Paglian'方法here . 自从我'm using windows (without mingw) that method doesn'工作 . 所以这是修改后的变体:

    # 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_FILE) 而不是 $(COPY_DIR) . 根据需要进行调整 .


    如果你想将文件复制到二进制文件最终的确切路径(因为二进制文件将在$$ 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 中找到文件资源,而不是调试子文件 . 这意味着你例如不能做 QIcon("archive.png") 并期望它除了可执行文件之外找到它 .

    这当然可以通过以下方式轻松解决:

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

    如果您认为这是您想要的,您显然需要编辑 $$(COPY_FILE) (in .pro)的最后一个参数,如下所示: \"$$shell_path($$OUT_PWD)\\$$VARIANT\"


    另外需要注意的是(在我的情况下,无论如何)Qt Creator(4.0.1)没有检测到配置中的任何更改,因此要在Makefile中反映上述更改(因此在构建项目时运行) )您必须通过从应用程序菜单运行 Build->run qmake 来手动构建.pro . 为确保一切顺利,请按Alt 4(在Windows上)查看编译输出 .

  • 3

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

  • 2

    也许以下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}")
    

相关问题