CPack 是 CMake 2.4.2 以后的一个内置工具,用于建立软件的二进制包和源代码包。html
CPack 在整个 CMake 工具链的位置。git
CPack 支持打包的包格式有如下种类:github
软件程序想要在生产环境快速被使用,就须要一个一键安装的安装包,这样生产环境就能够很方便的部署和使用。数据库
C++ 工程大部分都是用 CMake 配置编译, 而 CPack 是 CMake 内置的工具,支持打包成多种格式的安装包。由于是 CMake 的内置工具,因此使用的方式也是经过在 CMakeLists.txt 配置参数,就能达到咱们的需求。使用起来很方便,容易上手。微信
安装 CMake 的时候会把 CPack 一块儿安装了,直接经过 yum 或者 apt-get 安装便可。markdown
这里介绍如何打包 rpm 包,deb 的打包是同样的,区别在于一些配置。Cpack 打包 rpm 用的是 CPack RPM 生成器,用到的配置变量是以 CPACK_RPM_XXX 为前缀。最终经过 rpm-build 这个工具去打包,因此须要安装 rpm-build 这个工具,能够经过 sudo yum install -y rpm-build
安装。下面配置是用 3.14.5 的 CMake 进行测试的。函数
如今有一个工程 example,其目录结构以下:工具
example
|-- CMakeLists.txt // example 的主 CMakeLists.txt 文件
|-- Readme.txt
|-- License.txt
|-- src
| |-- CMakeLists.txt
| |-- MainA.cpp // 可执行文件 Aprogram 的源码
| |__ MainB.cpp // 可执行文件 Bprogram 的源码
|
|-- etc
| |-- CMakeLists.txt
| |-- A.conf // 可执行文件 Aprogram 的配置文件
| |__ B.conf // 可执行文件 Bprogram 的配置文件
|
|__ scripts
|-- preinst // 安装前执行的脚本
|-- postinst // 安装后执行的脚本
|-- prerm // 卸载前执行的脚本
|__ postrm // 卸载后执行的脚本
复制代码
只须要在 example/CMakeLists.txt 文件里面添加以下配置post
# 设置生成的安装包名字
set(CPACK_PACKAGE_NAME "example")
# 设置支持指定安装目录的控制为 ON
set(CPACK_SET_DESTDIR ON)
# 设置安装到的目录路径
set(CPACK_INSTALL_PREFIX "/home/vesoft/install")
# 这是生成的安装的版本号信息
set(CPACK_PACKAGE_VERSION "1.0.0")
# 设置 group 名字
set(CPACK_RPM_PACKAGE_GROUP "vesoft")
# 设置 vendor 名字
set(CPACK_PACKAGE_VENDOR "vesoft")
# 设置 license 信息
set(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0 + Common Clause 1.0")
include(CPack)
复制代码
执行 cmake 命令后, 你会发现当前目录下面多了两个文件 CPackConfig.cmake 和 CPackSourceConfig.cmake。 编译完成后,执行 cpack -G RPM
就可将文件打包成 rpm 包,当前目录下会生成一个 _CPack_Packages 目录和一个以 .rpm 为后缀名的文件 example-1.0.0-Linux.rpm,example-1.0.0-Linux.rpm 就是咱们想要的安装包文件。测试
若是想要查看打包过程的详细输出,能够在命令后面添加 --verbose
。CPack 是根据用户的配置生成_CPack_Packages/Linux/RPM/SPECS/example.spec 文件,而后让 rpm-build 用。
上面配置生成的安装包 example-1.0.0-Linux.rpm里面包含的文件以下:
⚠️注意:假如安装时出现 file /home from install of example-1.0.0-1.x86_64 conflicts with file from package filesystem-3.2-25.el7.x86_64
,那么须要在配置文件里面添加如下配置,让生成的 rpm 文件不包含 /home 和 /home/vesoft 。
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/home")
list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/home/vesoft")
复制代码
咱们要在安装先后、卸载先后作一些事情时,能够经过写相应的脚本文件:
在上述的 CMakeLists.txt 文件里面添加以下配置:
# 设置安装前执行的脚本文件 preinst
set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/scripts/preinst)
# 设置卸载前执行的脚本文件 prerm
set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/scripts/prerm)
# 设置安装后执行的脚本文件 postinst
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/scripts/postinst)
# 设置卸载后执行的脚本文件 postrm
set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/scripts/postrm)
复制代码
CPack 会将上面配置的脚本里面的内容写到生成的 SPEC 文件里面去。
⚠️注意:上述的四个脚本文件须要的权限是全部用户和用户组均能执行,建立完脚本文件后,经过 chmod 755 scripts/*
修改 scripts 目录下面的脚本文件的权限。
执行 sudo rpm -ivh example-1.0.0-Linux.rpm
命令会有如下输出
执行 sudo rpm -e example-1.0.0
会有如下输出
能够看到图片里面绿色和红色字样,就是四个脚本文件的打印输出,分别对应安装先后和卸载先后执行打印。因此用户能够在这四个脚本里面实现本身想要的功能。
上述配置是将全部须要打包的文件打包成一个安装包,但一个项目每每会有多个不一样服务,在实施部署时需安装到不一样的机子上,这个时候若是把全部服务一块儿打包,会致使部署时包太大。这个时候就须要用上 CPack 的 Components 功能。
下面介绍在这个过程须要用到的三个函数:cpack_add_component 和 cpack_add_component_group,还有 install。
如下为添加 install 的函数定义
如下为添加 component 的函数定义
如下为添加 group 的函数定义
以上述为例,假如咱们要将 program A 和它的配置文件 A.conf 打成一个 rpm 包,将 program B 和它的配置文件 B.conf 打成一个 rpm 包,则须要在 CMakeLists.txt 里添加如下内容,把上述配置的 include(CPack) 移到下面配置的位置:
# 设置每一个分组打包成一个 rpm 包
set(CPACK_COMPONENTS_GROUPING ONE_PER_GROUP)
# 设置支持 COMPONENT
set(CPACK_RPM_COMPONENT_INSTALL ON)
include(CPack)
# 添加一个名为 AComponent 的 component
cpack_add_component(AComponent
DISPLAY_NAME "A program"
DESCRIPTION "The program for test"
GROUP Aprogram)
# 添加一个名为 BComponent 的 component
cpack_add_component(BComponent
DISPLAY_NAME "B program"
DESCRIPTION "The program for test"
GROUP Bprogram)
# 添加一个名为 Aprogram 的 group, 这个名字会做为 rpm 包名字的一部分
cpack_add_component_group(Aprogram)
# 添加一个名为 Bprogram 的 group
cpack_add_component_group(Bprogram)
复制代码
而后修改 src/CMakeLists.txt,看下图红框内容,将 program A 二进制文件配置为 AComponent,将 program B 二进制文件配置为 BComponent。
修改 etc/CMakeLists.txt,看下图红框内容,将配置文件 A.conf 配置为 AComponent, 将配置文件 B.conf 配置为 BComponent。
更新 CMakeLists.txt 的配置以后,从新执行下 cmake 命令生成新的 makefile 文件,并执行 cpack -G RPM
,你能够在当前目录下面看到生成两个文件 example-1.0.0-Linux-Aprogram.rpm 和 example-1.0.0-Linux-Bprogram.rpm, 它们各自包含的文件以下:
# 将上述配置设置指定目录这个选项置为 OFF
set(CPACK_SET_DESTDIR OFF)
# 设置可重定目录的选择为 ON
set(CPACK_RPM_PACKAGE_RELOCATABLE ON)
# 设置默认重定的目录
set(CPACK_PACKAGING_INSTALL_PREFIX "/home/vesoft/install")
复制代码
经过上述配置,从新生成的 rpm 包就能够支持安装到其余指定目录,下面是把它安装到 /home/test/install,使用以下:
sudo rpm -ivh example-1.0.0-Linux-Aprogram.rpm --prefix=/home/test/install
复制代码
用户能够经过 CPACK_RPM_SPEC_MORE_DEFINE 这个参数在生成的 SEPC 文件里面增长相应的宏,来应用 rpmbuild 的一些功能开关。
CPack 有不少参数,不一样版本参数有些差别,想要了解更多,能够去 CMake 官网查看,见 CPack。或直接经过 CPack --help
获取参数描述。
Nebula Graph 也是采用 CPack 进行打包成 rpm 和 deb 包,您能够经过 github.com/vesoft-inc/… 获取到 Nebula Graph 每次 release 发布的包。
本文中若有任何错误或疏漏欢迎去 GitHub:github.com/vesoft-inc/… issue 区向咱们提 issue 或者前往官方论坛:discuss.nebula-graph.com.cn/ 的 建议反馈
分类下提建议 👏;加入 Nebula Graph 交流群,请联系 Nebula Graph 官方小助手微信号:NebulaGraphbot
做者有话说:Hi,我是 Laura,是图数据库 Nebula Graph 研发工程师,但愿作的分享能给你们带来帮助,若有不当之处也但愿能帮忙纠正,谢谢~