cmake使用教程(十一)-使用cpack打包源码并编写自动化脚本上传到仓库

【cmake系列使用教程】git

cmake使用教程(一)-起步github

cmake使用教程(二)-添加库正则表达式

cmake使用教程(三)-安装、测试、系统自检shell

cmake使用教程(四)-文件生成器缓存

cmake使用教程(五)-cpack生成安装包ruby

cmake使用教程(六)-蛋疼的语法bash

cmake使用教程(七)-流程和循环ide

cmake使用教程(八)-macro和function工具

cmake使用教程(九)-关于安卓的交叉编译post

cmake使用教程(十)-关于file

在前边的文章中已经讲过了如何使用cpack,可是那只是一个官方的简版教程,此次讲解的是我在实际开发Linux c中遇到的一些cpakc的问题。

简介

CPack是做为一个模块出如今cmake构建系统中的,它是一个很是强大的打包工具,能够用来打包二进制文件或者源码。打包好的二进制文件中包含了全部的cmake install命令须要的安装文件。在打包源码时,也能够生成对应的压缩包。 cpack能够依赖cmake构建生成的config文件,也能够本身编写配置文件。我属于比较懒的类型,直接使用cmake生成的config文件吧。generator是一个比较重要的东西,它算是你要生成的打包文件的类型,cpack默认提供了一个列表来指定这个东西。

主要工做流程:

  1. cpack执行
  2. 寻找CPackConfig.cmake文件
  3. 遍历命令行 -G传入的generator参数,假如没有传入参数,则检查CPackConfig.cmake文件或者CPackSourceConfig.cmake文件中的CPAKC_GENERATOR变量,注意这个优先级的问题,命令行参数会覆盖配置文件的参数。
  4. 为每个generator来生成对应的打包文件

流程就是如此简单。

具体配置

这里以我本身的一个开源项目为例子来说解--Sweather,这是个c语言的获取天气的命令行工具。地址:github.com/rangaofei/S…

首先看一下工程目录结构:

.
├── CMakeLists.txt
├── License.txt
├── PIC
├── README.md
├── assets
├── build
├── cmake-build-debug
├── logfile
├── pack
├── sakabrew.sh
└── src
复制代码
  1. CMakeLists.txt是cmake执行的入口文件
  2. License.txt是协议信息
  3. PIC是我本身截的图
  4. README.md是说明文件
  5. assets是资源文件件
  6. build是外部构建的文件夹
  7. cmake-build-debug这个是CLion自动生成的文件夹
  8. src是主要的c文件目录
  9. pack是打包文件的文件夹
  10. sakabrew.sh是我本身编写的自动化文件
  11. logfile是sakabrew.sh文件生成的日志。

主要的CMakeLists.txt配置以下:

CMAKE_MINIMUM_REQUIRED(VERSION 3.8)

set(CMAKE_C_STANDARD 99)
project(SWeather C)

set(VERSION_MAJOR 1)
set(VERSION_MINOR 3)
set(VERSION_PATCH 1)

#采用debug模式时启用'ENABLE_DEBUG'
IF (CMAKE_BUILD_TYPE STREQUAL Debug)
    ADD_DEFINITIONS(-DENABLE_DEBUG)
ENDIF (CMAKE_BUILD_TYPE STREQUAL Debug)

add_subdirectory(src)

include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_DIRECTORY ${PROJECT_SOURCE_DIR}/pack)
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}")
set(PROJECT_VERSION_FULL ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(CPACK_SOURCE_IGNORE_FILES
        ${PROJECT_SOURCE_DIR}/build
        ${PROJECT_SOURCE_DIR}/cmake-build-debug
        ${PROJECT_SOURCE_DIR}/pack
        ${PROJECT_SOURCE_DIR}//.idea
        ${PROJECT_SOURCE_DIR}/.DS_Store
        ${PROJECT_SOURCE_DIR}/.git
        ${PROJECT_SOURCE_DIR}/.gitignore
        ${PROJECT_SOURCE_DIR}/.vscode
        ${PROJECT_SOURCE_DIR}/.PIC
        ${PROJECT_SOURCE_DIR}/assets/city.txt)

set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_PACKAGE_FILE_NAME sweather-${PROJECT_VERSION_FULL})


include(CPack)
复制代码

设置打包文件生成位置和协议信息

set(CPACK_PACKAGE_DIRECTORY ${PROJECT_SOURCE_DIR}/pack)

set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/License.txt")

能够经过CPACK_PACKAGE_DIRECTORY变量配置,我设置的是根目录下的pack文件夹,这样生成的全部文件都会在这里,不会污染其余文件夹。

CPACK_RESOURCE_FILE_LICENSE能够用来指定协议信息

设置版本信息

set(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}")
复制代码

这个也比较简单,版本信息采用cmake中设置的版本信息,后边将会用来生成文件名字。

设置忽略文件

set(CPACK_SOURCE_IGNORE_FILES
        ${PROJECT_SOURCE_DIR}/build
        ${PROJECT_SOURCE_DIR}/cmake-build-debug
        ${PROJECT_SOURCE_DIR}/pack
        ${PROJECT_SOURCE_DIR}/.idea
        ${PROJECT_SOURCE_DIR}/.DS_Store
        ${PROJECT_SOURCE_DIR}/.git
        ${PROJECT_SOURCE_DIR}/.gitignore
        ${PROJECT_SOURCE_DIR}/.vscode
        ${PROJECT_SOURCE_DIR}/.PIC
        ${PROJECT_SOURCE_DIR}/assets/city.txt)
复制代码

这个地方须要注意,最好不要用正则表达式,容易发生错误,这里吧全部不须要的文件都排除在了外边,固然这种简洁的方式是简历在外部构建的基础上的。在构建的时候进入buid文件夹执行build命令,就能够不污染源文件。

设置生成器

set(CPACK_SOURCE_GENERATOR "TGZ")

这里有一个对应的关系:

  1. 7Z-7Zzip-(.7z)
  2. TBZ2(tar.bz2)
  3. TGZ(.tar.gz)
  4. TXZ(.tar.xz)
  5. TZ(.tar.Z)
  6. ZIP(.zip)

我选择的是TGZ,因此生成的文件的扩展名称将会是.tar.gz,这个后缀将会在下边介绍的打包名称后添加。

设置文件打包文件名称

set(PROJECT_VERSION_FULL ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(CPACK_SOURCE_PACKAGE_FILE_NAME sweather-${PROJECT_VERSION_FULL})
复制代码

打包文件名称不须要设置后缀,系统会自动根据generator来生成后缀。 在我这个文件中生成的打包文件名称将会是sweather-1.3.1.tar.gz

这样咱们就完成了主要的配置,而后进入build文件夹,执行cmake ..便可生成cpack须要的配置文件,此处我要打包源文件,因此继续执行cpack --config CPackSourceConfig.cmake,这样就在pack文件夹下生成了上边设置好的文件。

自动化构建上传到brew仓库

上传到github不难,可是修改rb文件上传至本身的homebrew-saka仓库是比较麻烦的,须要修改下载地址和SHA256码。因此我本身写了一个自动化构建上传的shell脚本,主要流程:

  1. 寻找build文件夹,没有就生成
  2. 进入build文件夹,清空该文件夹下的全部文件
  3. 执行cmake ..外部构建程序
  4. 执行打包命令并写入日志文件
  5. 读取日志文件中最后一行生成的文件名称,版本名称,校验码存入变量
  6. 自动生成的文件须要添加值git仓库,上传至远程仓库
  7. 进入homebrew --repo rangaofei/saka目录,进入程序脚本文件夹
  8. 替换对应的ruby脚本(sweather.rb)中的下载地址和SHA256.
  9. 添加文件,上传至远程仓库

主要代码以下:

#!/usr/bin/env bash
# 寻找build文件夹,不存在就建立
function findBuild(){
    if [ ! -d "./build" ];then
        mkdir ./build
    else
        echo "build文件夹已经存在"
    fi
}
 # 进入build文件夹,清除全部的缓存文件
function cmakeOutBuild(){
    cd ./build
    echo "进入build文件夹,即将清除文件缓存"
    rm -rf ./*
    echo "build文件夹缓存清理完毕,即将执行外部构建"
    cmake ..
    echo "外部构建执行完成"
}
# 打包文件
function cmakePackage(){
    cpack --config CPackSourceConfig.cmake
}
 # 读取日志文件,读入文件名称
function readLogFile(){
    if [ -e "logfile" ];then
        tmp_path=`echo $(pwd) | sed -n "s#/#\\\\\/#gp"`
        echo "$tmp_path"
        package_name=`sed -n '$p' logfile |sed -n "s/.*CPack:.*\($tmp_path.*tar\.gz\).*generated./\1/gp"`
        package_version=`echo "${package_name}" | sed -n 's/.*pack\/\(.*\)\.tar\.gz/\1/gp'|sed -n 's/\./\\\\./gp'`
        echo "---name:${package_name}\n---version:${package_version}\n"
    else
        echo "file not found"
    fi
}
 # 本地提交git仓库,而后推送至远程仓库
function commitToGitHub(){
    if [ ! -n "$package_name" ];then
        echo "不能提交"
    else
        git add ${package_name}
        git commit -m "new version"
        git push
    fi
}
 # 本地提交至brew仓库,远程提交
function commitToBrew(){
    if [ ! -n "$package_name" ];then
        echo "不能提交到brew"
    else
        fileSHA256=`openssl dgst -sha256 ${package_name}|sed -n "s/.*= \(.*\)/\1/gp"`
        echo "$fileSHA256"
        cd $(brew --repo rangaofei/saka)/Formula
        sed -i -n "s/sweather-[0-9]\.[0-9]\.[0-9]/sweather-1\.3\.1/g" sweather.rb
        sed -i -n "s/sha256 \".*\"/sha256 \"$fileSHA256\"/g" sweather.rb
        git add sweather.rb
        git commit -m "new version:$package_version"
        git push
        cd -

    fi

}
findBuild
cmakeOutBuild

if [ ! -e "CPackSourceConfig.cmake" ];then
    echo "未找到打包文件,请从新执行此脚本"
else
    echo "已生成打包文件,即将开始打包"
    name=`cmakePackage`
    echo "------------------------------"
    echo "$name"| tee -a ../logfile
fi
cd ..
readLogFile
#commitToGitHub
commitToBrew

复制代码

这样就完成了全部的工做,下次只须要执行. ./sakabrew.sh便可自动构建文件并上传至仓库了。

最后,附上之前的文章地址和github地址

github地址:github.com/rangaofei/S…

HomeBrew常规使用教程:juejin.im/post/5a559b…

最后的最后,再写一点我最近的感想,否极不必定会泰来。我这条咸鱼应该翻身无望了,备受打击以后我感受只能作一条最咸的咸鱼。

相关文章
相关标签/搜索