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_64bit-Debug/debug/res
copy /y *.xml ../../build-DEMO-Desktop_Qt_5_6_3_MSVC2015_64bit-Debug/debug/res
mkdir ../../build-DEMO-Desktop_Qt_5_6_3_MSVC2015_64bit-Release/realse/res
copy /y *.xml ../../build-DEMO-Desktop_Qt_5_6_3_MSVC2015_64bit-Release/realse/res

思路是这样的:

  1. 首先创建相应的目录
  2. 将项目下面所有的 xml 文件复制到指定的目录

在我的电脑环境中运行正常,但是问题很明显,如果我换了编译器,或者更换了构建目录,我就得去批处理文件中添加两行代码,

而且还得把所有的文件复制到好几个目录下面。非常麻烦!

我在把源代码拷给别人的时候,由于别人用的编译器是 MinGW 编译器,结果我的批处理文件没有办法直接使用。

所以在别人的编译环境中生成的程序由于缺少资源文件,程序运行不正常。

那么我需要找到一种方法,得到 Qt 构建项目的目录,并将需要的资源文件复制到相应目录下。

解决方案 2.0

QtCreator 编译项目时,IDE 会调用 qmake 根据项目 .pro 文件自动生成一个 Makefile

然后 IDE 就能根据这个 Makefile 对项目进行编译处理。

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

DESTDIR = $$OUT_PWD
defineTest(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\\t)
} 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 sentence
resToDestdir($$XML_FILES)

Qt 官方文档 里对这些用到的变量都有说明。

这里简单说一下。

  • 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_PWD
defineTest(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\\t)
# QMAKE_POST_LINK += echo $$FILE $$escape_expand(\\n\\t)
# 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 folder
XML_FILES = $$PWD/res/*.xml ## note, if there is something wrong when compiling, annote following sentence
resToDestdir($$XML_FILES, res)

总结

最终这个代码可以完美的复制需要的资源文件到指定的目录下,但是还有一些小 bug,偶尔编译时会报错:

mkdir ..\debug\res 目录已经存在,遇到这种情况,重新执行一遍 qmake,再重新编译就好了。

虽然并不完美,但再深入就太累了。

当然还有一种思路,在 qmake 中执行已经写好的 bat 批处理文件,然后将构建目录作为参数传递给批处理文件。

时间有限,没有实现。

Qmake 配置自定义编译过程的更多相关文章

  1. uboot主Makefile分析(t配置和编译过程详解)

    1.编译uboot前需要三次make make distcleanmake x210_sd_configmake -j4 make distclean为清楚dist文件. make x210_sd_c ...

  2. uboot配置和编译过程详解【转】

    本文转载自:http://blog.csdn.net/czg13548930186/article/details/53434566 uboot主Makefile分析1 1.uboot version ...

  3. uboot配置和编译过程详解

    根据朱有鹏老师讲解整理 一.uboot主Makefile分析 1.uboot version确定(Makefile的24-29行) include/version_autogenerated.h文件是 ...

  4. uboot编译: uboot编译配置和编译过程

    jz2440: 韦东山Linux视频第1期_裸板_UBoot_文件系统_驱动初步\第09课第2节 u-boot分析之Makefile结构分析.WMV <嵌入式linux完全开发手册> 15 ...

  5. 关于全志A20的Ubuntu12.04 64位系统下环境配置及编译过程笔记【转】

    本文转载自:https://blog.csdn.net/buqingbuyuan/article/details/43370199 在安装Ubuntu系统之后,安装编译所需的GCC等工具,一般选用GC ...

  6. Qt Creator内qmake配置静态编译

    起因 利用QT Creator编写一些纯C/C++应用,默认配置下是动态编译 解决 解决起来很简单,这里只是附上配置备忘;-) msvc: { QMAKE_CFLAGS_RELEASE += /MT ...

  7. 大型项目使用Automake/Autoconf完成编译配置(标准的编译过程已经变成了简单的三部曲:configure/make/make install,)

    使用过开源C/C++项目的同学们都知道,标准的编译过程已经变成了简单的三部曲:configure/make/make install, 使用起来很方便,不像平时自己写代码,要手写一堆复杂的Makefi ...

  8. 我学C的那些年[ch01]:浅淡C语言的编译过程

    前几天大致学习了C语言的编译过程,那么今天就和大家分享一下 首先,编译C语言,需要一个文本编辑器(windows自带的也行),和一个MinGW编译器(需要配置环境),就可以将.c文件编译成.exe文件 ...

  9. Android编译过程详解(三)

    前面两节讲解了自定义Android编译项和创建Product产品配置文件,除了编译和定义产品相关环境变量外,还需要定义Board相关环境变量. 1. build/core/config.mk 109 ...

随机推荐

  1. fiddler扩展模拟弱网络环境设置

    今天在qq群中有人问到怎么模拟app弱网络环境,我查了下资料,记得之前做测试的时候是设置fiddler断点,app请求后止于fiddler断点,app一直拿不到响应结果就应该要给出网络请求失败的提示, ...

  2. CentOS6.5上Zabbix3.0的RPM安装【二】-汉化

    六.汉化 zabbix实际是有中文语言的,我们可以通过修改web端源文件来开启中文语言.首先点击zabbix监控页面右上角管理员头像进入“用户基本资料设置页面“. 选择中文语言. 点击“Update” ...

  3. MongoDB入门,安装配置与基本CURD操作

    MongoDB特点 MongoDB是NoSQL的一种,非关系型数据库,或者叫不只是关系型数据库(Not Only SQL).MongoDB采用json格式的文档存储,与Redis的key-value有 ...

  4. SQL事务对并发处理的支持

    前言 继上次技术分享后,学到了关于mysql事务的许多新知识,感觉还是蛮有收获的.后来反过来想想,这些东西其实我们都接触过,最起码在自学考试的数据库系统原理那本书里面对事务的讲解,在里面就提到了事务的 ...

  5. 阿里云服务器 ECS 部署lamp:centos+apache+mysql+php安装配置方法 (centos7)

    阿里云服务器 ECS 部署lamp:centos+apache+mysql+php安装配置方法 (centos7) 1.效果图 1 2. 部署步骤 1 1. mysql安装附加(centos7) 7 ...

  6. CUDA中自动初始化显卡设备宏

    每次为了减少初始化的工作量,可以写入下面的宏. #define CUT_DEVICE_INIT(ARGC,ARGV){ \ int deviceCount; \ CUDA_SAFE_CALL_NO_S ...

  7. Orcale常用函数

    1.ascii 作用: 返回指定的字符对应的十进制数 select ascii('A') ,ascii('a'),ascii(' ') from dual; 2.chr 作用:给出整数,返回对应的字符 ...

  8. Flink学习笔记-支持的数据类型

    说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...

  9. P3345 [ZJOI2015]幻想乡战略游戏 动态点分治

    \(\color{#0066ff}{ 题目描述 }\) 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越 ...

  10. HiBench学习笔记

    HiBench资源及教程:https://github.com/intel-hadoop/HiBench 介绍: Hadoop新人 环境 linux 该笔记针对英语弱鸡&自己在使用过程用遇到的 ...