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 包,您能夠經過 https://github.com/vesoft-inc/nebula/releases 獲取到 Nebula Graph 每次 release 發佈的包。
本文中若有任何錯誤或疏漏歡迎去 GitHub:https://github.com/vesoft-inc/nebula issue 區向咱們提 issue 或者前往官方論壇:https://discuss.nebula-graph.com.cn/ 的 建議反饋
分類下提建議 ?;加入 Nebula Graph 交流羣,請聯繫 Nebula Graph 官方小助手微信號:NebulaGraphbot
做者有話說:Hi,我是 Laura,是圖數據庫 Nebula Graph 研發工程師,但願作的分享能給你們帶來幫助,若有不當之處也但願能幫忙糾正,謝謝~