QT C++工程CI环境笔记
开发环境
- Ubuntu18.04 or Ubuntu20.04
- Qt Creator 4.6.x (Based on Qt 5.11.x)
- APT list: apt-transport-https git dh-make build-essential autoconf autotools-dev qt5-default libssl-dev qt5keychain-dev devscripts
项目结构
项目主体结构是根据Qt, 用.pro文件组织, 项目最外层TEMPLATE用subdirs, 用于引入项目主pro文件, 这样便于将源代码放入子目录, 实际的项目pro文件在子目录下. 最外层还有对应的说明文件, 授权文件和Gitlab CI配置等.
├── .git
├── .gitignore
├── .gitlab-ci.yml # Gitlab CI配置文件
├── LICENSE
├── README.md # 项目Readme
├── rockbb # 实际源代码目录
│ ├── app-entry # 为debian/ubuntu提供的桌面图标配置文件及图标文件
│ │ ├── rockbb.desktop
│ │ └── rockbb.png
│ ├── *.cpp
│ ├── *.h, *.ui
│ ├── config.h # 全局配置, namespace rockbb
│ ├── debian # deb打包时需要的文件
│ │ ├── changelog # 软件历史版本信息, 有格式要求
│ │ ├── compat # debhelper压缩级别, 最新的是10, 如果要兼容可以用9
│ │ ├── control # 软件的包名, 维护者, 编译工具依赖, 安装依赖等
│ │ ├── copyright # 标准版权信息, 例如GPLv3
│ │ └── rules # 编译和打包命令, 在这里将资源文件复制到deb包的标准位置
│ ├── res.qrc # 资源文件, 在这个文件里记录images目录里的各个文件
│ ├── images
│ │ ├── rockbb-off.png
│ │ ├── rockbb-on.png
│ │ ├── rockbb.png
│ ├── main.cpp # 程序入口
│ └── rockbb.pro # 主要项目文件
├── rockbb-project.pro # 项目入口文件(用于引入rockbb.pro)
└── rockbb-project.pro.user # Qt Creator产生的本地开发配置文件, 需要从gitignore中排除
Qt对非Qt项目文件的支持不好, 在project视图下默认不展示不相关的文件, 如果要显示, 需要在.pro文件中使用 OTHER_FILES 将需要显示在工作区的文件包含进来.
如果切换到File System视图, 默认不显示点开头的隐藏文件, 需要在模块右上角选项中勾上"Show Hidden Files", 才会展示.gitlab-ci.yml这些文件.
开发编译和测试
在本地通过Qt Creator完成, 编译, Debug和运行有Ctrl+B, F5, Ctrl+R等快捷方式.
项目文件中常用的变量及说明
- QT
指定项目用到的Qt模块, 在编译阶段, 被指定的Qt模块头文件会被include并且被链接. 默认Qt会包含core和gui, 如果项目不需要gui, 需要用 QT -= gui 显式排除. - QTPLUGIN
指定需要链接到最终可执行文件的静态Qt插件, 成为内建资源. - CONFIG
在这里设置项目编译选项, 不同的值对应qmake内部不同的处理, 常用值包括 release, debug, debug_and_release, warn_on, warn_off, c99, c11, c++11, static等 - DEFINES
qmake adds the values of this variable as compiler C preprocessor macros (-D option). - DESTDIR
指定最终生成的可执行文件的路径. - OBJECTS_DIR
指定存放编译过程中中间对象的存放路径 - MOC_DIR
Specifies the directory where all intermediate moc files should be placed. - RCC_DIR
Specifies the directory for Qt Resource Compiler output files. - LIBS
指定需要被链接到项目的库. 如果使用Unix形式的 -l(library) 和 -L (library path) 参数, qmake 可以在Windows下正确识别处理. - QMAKE_CXXFLAGS
Specifies the C++ compiler flags for building a project. The value of this variable is typically handled by qmake or qmake.conf and rarely needs to be modified. The flags specific to debug and release modes can be adjusted by modifying the QMAKE_CXXFLAGS_DEBUG and QMAKE_CXXFLAGS_RELEASE variables, respectively. - SOURCES
Specifies the names of all source files in the project - HEADERS
Defines the header files for the project. - PWD
解析为包含被解析的当前文件的完整路径. This can be useful to refer to files within the source tree when writing project files to support shadow builds. - INCLUDEPATH
指定编译时 #include 应该查找的目录, 如果目录带空格, 需要用双引号包围. - TARGET
指定最后生成的可执行文件名. 默认等于项目文件名.
项目文件中的语法
变量赋值方式
VAR = foobar => 在qmake执行的时候给VAR变量赋值(值为foobar)
$$VAR => 在qmake执行的时候, 使用VAR对应的QMake变量值, 例如$$PWD
$${VAR} => 和上面一样只不过将变量显式指出
$(VAR) => 在Makefile运行时取环境变量的值
$$(VAR) => 在qmake运行时取环境变量的值
包含第三方项目的pri文件
include(path/to/some.pri)
区分debug和release做不同配置
debug: {
...
}
release: {
...
}
代码仓库
在本地通过 git remote add 将github添加为上游仓库, 这样项目对应的就有 origin 和 github 两个上游, 在本地编译通过后, push origin master可以触发测试环境的gitlab进行集成, 在gitlab测试通过后, 可以push gitlab master将代码提交到github.
测试集成
测试环境的持续集成, 使用Gitlab + Gitlab Runner实现. 有条件的话Gitlab Runner应当跑在独立的服务器上, 另外如果需要构建异构系统例如Windows, OSX等, 都需要将Runner跑在独立的服务器上. 如果只需要构建Linux下的发行版, 可以放在一起. Gitlab Runner需要Docker环境, 最好使用Ubuntu较新的发行版.
gitlab 12.10.6, gitlab-runner 12.10.2, docker 19.03.6
Gitlab配置
略. 这里主要是创建group, project, user, 获取group下的runner token
Gitlab Runner配置
准备Docker镜像, 对于不同的发行版发布, 要准备对应的发行版镜像, 再将这些镜像作为Runner, 注册到Gitlab. 举例Ubuntu18.04的Dockerfile
from ubuntu:bionic
ADD setup.sh /opt/
RUN /bin/bash /opt/setup.sh
和setup.sh, 这个脚本用于切换到较快的apt源, 以及准备编译环境.
#!/bin/sh
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted" > /etc/apt/sources.list
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted" >> /etc/apt/sources.list
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic universe" >> /etc/apt/sources.list
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates universe" >> /etc/apt/sources.list
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic multiverse" >> /etc/apt/sources.list
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates multiverse" >> /etc/apt/sources.list
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse" >> /etc/apt/sources.list
echo "deb http://security.ubuntu.com/ubuntu bionic-security main restricted" >> /etc/apt/sources.list
echo "deb http://security.ubuntu.com/ubuntu bionic-security universe" >> /etc/apt/sources.list
echo "deb http://security.ubuntu.com/ubuntu bionic-security multiverse" >> /etc/apt/sources.list
#requirements
apt-get update
apt-get -y install apt-transport-https git dh-make build-essential autoconf autotools-dev qt5-default libssl-dev qt5keychain-dev devscripts
对于Ubuntu20.04, 在apt install 过程中会出现tzdata等需要交互的安装导致镜像制作失败, 需要在apt-get update前加上这句
export DEBIAN_FRONTEND=noninteractive
制作镜像, 将镜像注册为Runner
# 制作镜像
docker build -t ubuntu_focal_runner:1.0 ubuntu_focal/
# 注册到gitlab
gitlab-runner register --non-interactive --url "http://172.17.54.139/" --registration-token "x7sx4rte_acSXrmznJBz" --description "Ubuntu 20.04 x64 runner" --executor "docker" --docker-image "ubuntu_focal_runner:1.0" --tag-list "ubuntu-2004-64" --run-untagged="false" --locked="false" --access-level="not_protected"
测试镜像是否可用:
对于刚建好的容器镜像, 需要在跑任务前实际执行一下构建, 可以通过 docker run -it --rm [image] bash 的方式, 在命令行下手动git clone项目文件, 执行编译. 如果有问题, 需要在这一步重新制作镜像来解决. 不同的发行版, gcc/g++版本可能会不一样, Ubuntu16.04(GCC 5.4), Ubuntu18.04(GCC 7.5), Ubuntu20.04(GCC9.3), Debian8&10(GCC 8.3)
对于runner, 需要注意的有两点:
- 每个runner需要带一个 --tag-list "ubuntu-2004-64" 参数, 里面可以配一个或多个tag, 这个tag-list 结合 .gitlab-ci.yml文件里的 tags 参数, 可以让发行版各自执行对应的任务.
- 如果希望Runner就近pull镜像, 在注册完runner后, 需要修改 /etc/gitlab-runner/config.toml 文件, 在每个runner的[runners.docker]配置下, 增加一行配置. 默认为"always", 会主动去docker hub 拉取, 因为自建的镜像只存在本地, 从而导致任务失败.
volumes = ["/cache"]
pull_policy = "if-not-present" # 增加这行
shm_size = 0
项目 .gitlab-ci.yml 配置
参考
https://docs.gitlab.com/ee/ci/quick_start/
https://docs.gitlab.com/ee/ci/yaml/
根据.gitlab-ci.yml里的任务配置, gitlab在收到新的push后, 会触发产生pipeline, 里面是满足条件的, 分配到对应runner的job. 如果中途有job失败, 整个pipeline就会失败, 不再往下执行.
Github发布
对于版本间一个完整的开发周期, 以上一个版本号Tag提交为开始, 以下一个版本号提交为结束.
开发阶段
假设已经发布的版本号为1.1, 进入当前开发周期后, 首先修改以下文件
- config.h: 版本号修改为 1.2-dev
因为测试集成产生的版本号为特殊版本号, 并且会完全覆盖debian/changelog, 故这一阶段还不需要修改changelog
预发布阶段
在测试结束后, 进入发布准备工作, 需要修改以下文件
- config.h: 版本号修改为 1.2
- debian/changelog: 加入自上个版本至今的改动说明
对commit ID打tag, 并生成正式版的release
# 加tag
git tag -a 0.1.0 94ca32cbc4bd685774f22d95c66d58c79dccf95f
# 触发测试执行任务, 打包正式版
push origin --tags
本地对release进行测试
发布阶段
将tag推送到github
git push github --tags
之后, github会自动对新tag产生release, 可以手工在此release下添加文字和对应的release软件包
QT C++工程CI环境笔记的更多相关文章
- Qt Creator 源码学习笔记03,大型项目如何管理工程
阅读本文大概需要 6 分钟 一个项目随着功能开发越来越多,项目必然越来越大,工程管理成本也越来越高,后期维护成本更高.如何更好的组织管理工程,是非常重要的 今天我们来学习下 Qt Creator 是如 ...
- Qt for Android开发环境搭建及测试过程记录
最近学习了Qt的QML编程技术,感觉相较于以前的QtGUI来说更方便一些,使用QML可以将界面与业务逻辑解耦,便于开发. QML支持跨平台,包括支持Android平台,因此可以使用Qt的QML进行An ...
- Jenkins+Gitlab搭建持续集成(CI)环境
利用Jenkins+Gitlab搭建持续集成(CI)环境 Permalink: 2013-09-08 22:04:00 by hyhx2008in intern tags: jenkins gitla ...
- React项目搭建基于Karma的CI环境
简介 在浏览Github的时候是否经常看到这样的CI图标呢? 本文即为介绍如何为基于React的项目配置CircleCI的自动化测试环境 源码在此 本地实现 项目依赖如下: "devDepe ...
- Qt Creator 源码学习笔记04,多插件实现原理分析
阅读本文大概需要 8 分钟 插件听上去很高大上,实际上就是一个个动态库,动态库在不同平台下后缀名不一样,比如在 Windows下以.dll结尾,Linux 下以.so结尾 开发插件其实就是开发一个动态 ...
- 以QT为例谈环境搭建
以QT为例谈环境搭建 作者:哲思 时间:2022.1.5 邮箱:1464445232@qq.com GitHub:zhe-si (哲思) (github.com) 前言 自从实习结束,好久没写博客了. ...
- QT搭建Ffmpeg开发环境gcc版本
1 先安装qt 解压ffmpeg包 2打开qt创建工程 3 导入头文件和库文件 这里一定要注意gcc版本和库的版本一定要一致 4 添加一下简单的源代码 1 #include <libavcode ...
- Qt的IDE开发环境(KDevelop,MonKey Studio,QDevlop,Dev-cpp,Cobras,Edyuk)
讲到Qt的IDE开发环境,本人一直在Windows下使用VC6.0 + Qt4.3.1开发程序.但转到Linux下,使用Fedora中自带的KDevelop + Qt4.3.1开发程序. 最近一直做Q ...
- Jenkins+Maven+Git CI环境搭建手册
Jenkins+Maven+Git CI环境搭建手册 环境: OS:Linux version 2.6.32-220.23.2.ali878.el6.x86_64 (ads@kbuild) (gcc ...
- paip.c++ qt 项目工程互相引用的方法
paip.c++ qt 项目工程互相引用的方法 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/ ...
随机推荐
- SV OOP-2
静态变量 继承性(Inheritance) 抽象类和虚方法virtual methods 多态(Ploymorphism) 通过基类的变量可以使用子类的对象 基类中定义的virtual functio ...
- SV 字符串类型
概述 常见使用方式 string b; string b=""; // 拼接字符串 string a = {"hi",b}; // 将字符串a赋值给[15:0] ...
- IDEA中无法调出中文输入法?
参考链接:idea写代码时无法切换到中文输入
- SSM整合 - 环境配置
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- Prometheus+alertmanager实现告警的简单验证
Prometheus+alertmanager实现告警的简单验证 背景 学习源自: http://www.mydlq.club/article/126/ 上午没搞定, 中午睡不着,继续学习处理. 发现 ...
- [转帖]浅谈RAID写惩罚(Write Penalty)与IOPS计算
https://www.dell.com/community/%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E5%92%8C%E4%BF%9D%E6%8A%A4-%E8%B ...
- 【转帖】Linux开发工具 — readelf、objdump、hexdump
本博文的主要内容是:1)readelf工具查看ELF文件的信息:2)hexdump工具查看这块内存:3)objdump工具对文件进行反汇编. 前一段时间对Linux不熟,所以很多命令不知道.学习C时候 ...
- [转帖]通过架设Cockpit服务 使用Web浏览器监测管理多个Linux服务器
Cockpit是一个易于使用,轻量级和简单但功能强大的工具,通过单个Web浏览器监视和管理多个远程Linux服务器. 如果你管理着一台 Linux 服务器,那么你可能正在寻找一个可靠的管理工具.为了这 ...
- [转帖]python中input()、print()用法
https://www.cnblogs.com/lei3082195861/p/16967109.html 1.input()函数常涉及的强制类型转换 第一种是在键入时进行转换,例如:a = int( ...
- PG13 离线安装的简单办法
1. 发现上班时间公司的网络几乎不可用 还是得找时间下载好离线包才可以. 找了一个最简单的办法 地址 https://yum.postgresql.org/ 选择版本 这次我选择最新的 继续之后继续选 ...