您好,欢迎来到意榕旅游网。
搜索
您的当前位置:首页Qmake配置自定义编译过程

Qmake配置自定义编译过程

来源:意榕旅游网
Qmake配置⾃定义编译过程

Qmake 配置⾃定义编译过程

需求:动态更换资源⽂件

在 Windows10 下编写 Qt 项⽬时,有这样的需求:

程序⽤到的资源⽂件可以动态更换⽽不需要重新编译整个项⽬

解决⽅案 0.1

将所有的资源⽂件全部放到 qrc ⽂件中,由 Qt 负责管理资源⽂件。

但是这种⽅法在每次更改了 res 中的⽂件后都需要重新编译程序。⽐较⿇烦。

新的需求

于是需求变成了:

将源代码⽬录下的 res ⽂件夹下的 xml ⽂件全部复制到编译好的程序同级⽬录下

解决⽅案 1.0

最初的解决⽅案是在 res ⽬录下编写⼀个批处理⽂件:update.bat,然后每次更新了 xml ⽂件后,

⼿动执⾏这个批处理⽂件。由于 xml ⽂件写好后基本上不需要怎么修改,所以写完代码后在⾃⼰的环境中运⾏起来没有问题,不会出现程序运⾏时找不到 xml ⽂件的情况。该批处理⽂件的内容如下:

mkdir ../../build-DEMO-Desktop_Qt_5_6_3_MSVC2015_bit-Debug/debug/res

copy /y *.xml ../../build-DEMO-Desktop_Qt_5_6_3_MSVC2015_bit-Debug/debug/resmkdir ../../build-DEMO-Desktop_Qt_5_6_3_MSVC2015_bit-Release/realse/res

copy /y *.xml ../../build-DEMO-Desktop_Qt_5_6_3_MSVC2015_bit-Release/realse/res

思路是这样的:

1. ⾸先创建相应的⽬录

2. 将项⽬下⾯所有的 xml ⽂件复制到指定的⽬录

在我的电脑环境中运⾏正常,但是问题很明显,如果我换了编译器,或者更换了构建⽬录,我就得去批处理⽂件中添加两⾏代码,⽽且还得把所有的⽂件复制到好⼏个⽬录下⾯。⾮常⿇烦!

我在把源代码拷给别⼈的时候,由于别⼈⽤的编译器是 MinGW 编译器,结果我的批处理⽂件没有办法直接使⽤。所以在别⼈的编译环境中⽣成的程序由于缺少资源⽂件,程序运⾏不正常。

那么我需要找到⼀种⽅法,得到 Qt 构建项⽬的⽬录,并将需要的资源⽂件复制到相应⽬录下。

解决⽅案 2.0

⽤ QtCreator 编译项⽬时,IDE 会调⽤ qmake 根据项⽬ .pro ⽂件⾃动⽣成⼀个 Makefile。然后 IDE 就能根据这个 Makefile 对项⽬进⾏编译处理。

经过⼀番搜索,在 上搜到了可⽤的内容,然后我在 .pro ⽂件末尾添加了这些内容(修改了部分内容):

DESTDIR = $$OUT_PWDdefineTest(resToDestdir) { files = $$1

for(FILE, files) {

DDIR = $$RAWDDIR

# Replace slashes in paths with backslashes for Windows win32:DDIR ~= s,/,\\\\,g win32:FILE ~= s,/,\\\\,g

QMAKE_POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\\\\n\\\) }

export(QMAKE_POST_LINK) return(true)}

# update xml files into proper folder

XML_FILES = $$PWD/res/*.xml

## note, if there is something wrong when compiling, annote following sentenceresToDestdir($$XML_FILES)

⾥对这些⽤到的变量都有说明。这⾥简单说⼀下。

DESTDIR: 指定放置 target ⽂件的位置

QMAKE_POST_LINK: 在链接 TARGET 后指定要执⾏的命令

export(variablename): 将 variablename 在函数的局域上下⽂中的值导出到全局上下⽂defineTest:定义⼀个测试函数,以便复⽤代码(尽管这⾥并没有复⽤代码:))

经过⼏次尝试后,发现要运⾏ .pro ⽂件中的这段代码需要每次都重新编译。因为直接在 QtCreator 中点击编译会先⽐较

⽂件,如果没有更改源⽂件(或者说被依赖⽂件没有更新,那么编译就可以跳过)。⽽且每次更改了 .pro ⽂件都需要先运⾏⼀次 qmake,确保 Makefile 是最新的。

解决⽅案 2.9

我对代码进⾏了修改,添加了创建⽬录的语句,并⽤ exists 函数判断是否存在⽬录,如果不存在就创建。

在 Windows 上,⽬录分隔符是反斜杠 \"\" ,因此直接利⽤ win32:DDIR 进⾏判断是否存在相应⽬录, exists 函数返回的都是 false。对此已经有说明了:

Note: \"/\" should be used as a directory separator, regardless of the platform in use.即:

注意: ⽬录分隔符应该⽤ “/” ,不论你⽤的是什么平台。

所以判断⽬录是否已经存在需要⽤最开始的斜杠分隔符,但是创建⽬录的命令还是要⽤反斜杠(调⽤的是 Windows 的命令⾏)。最终修改后的 qmake 代码:

#-----------------------------------# @author BriFuture

# @details this is used for automated build#

# Copies the given files to the destination directory#-----------------------------------## set destdir

DESTDIR = $$OUT_PWDdefineTest(resToDestdir) { files = $$1 ddir = $$2

for(FILE, files) {

# Replace slashes in paths with backslashes for Windows DDIR = $$DESTDIR/$$ddir

## if res folder is created, then no need to exec mkdir

## note, whatever the platform you are using( Windows, Linux, Mac), ## the directory seperator must be slash \"/\" !exists($$DDIR) {

log($$DDIR not exists) mkpath($$DDIR) }

win32:DDIR ~= s,/,\\\\,g win32:FILE ~= s,/,\\\\,g

QMAKE_POST_LINK += $$QMAKE_COPY $$quote($$FILE) $$quote($$DDIR) $$escape_expand(\\\\n\\\)# QMAKE_POST_LINK += echo $$FILE $$escape_expand(\\\\n\\\)# message(FILE $$FILE) }

# QMAKE_POST_LINK += echo $$quote($$PWD == $$DESTDIR)# message(LINK: $$QMAKE_POST_LINK) export(QMAKE_POST_LINK) return(true)}

# update xml files into proper folderXML_FILES = $$PWD/res/*.xml

## note, if there is something wrong when compiling, annote following sentenceresToDestdir($$XML_FILES, res)

总结

最终这个代码可以完美的复制需要的资源⽂件到指定的⽬录下,但是还有⼀些⼩ bug,偶尔编译时会报错:mkdir ..\\debug\\res ⽬录已经存在,遇到这种情况,重新执⾏⼀遍 qmake,再重新编译就好了。虽然并不完美,但再深⼊就太累了。

当然还有⼀种思路,在 qmake 中执⾏已经写好的 bat 批处理⽂件,然后将构建⽬录作为参数传递给批处理⽂件。时间有限,没有实现。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务