DEV Community


Posted on • Originally published at on

Packaging with CPack in NebulaGraph Database

Packaging with CPack in NebulaGraph

CPack is a powerful, easy to use, cross-platform software packaging tool distributed with CMake since version 2.4.2. It helps create binary package and source code package. The following figure shows where CPack locates in the whole CMake tool chain.

CPack supports the following types of package formats:

  • 7Z (7-Zip file format)
  • DEB (Debian packages)
  • External (CPack External packages)
  • IFW (Qt Installer Framework)
  • NSIS (Null Soft Installer)
  • NSIS64 (Null Soft Installer (64-bit))
  • NuGet (NuGet packages)
  • RPM (RPM packages)
  • STGZ (Self extracting Tar GZip compression
  • TBZ2 (Tar GZip compression)
  • TXZ (Tar XZ compression)
  • TZ (Tar Compress compression)
  • ZIP (ZIP file format)

Why Packaging Tools

The one-click installation package facilitates the deployment and usage of your software in production so that you can concentrate on your work rather than the software itself.

CPack can be used by specifying a CPackConfig.cmake file without CMake or as a module of CMake. As a built-in tool for CMake, CPack supports to generate the binary installer in multiple formats and is easy to use. You can just configure it in the CMakeLists.txt file.

How to Install CPack

CPack is installed along with CMake or you can install it separately via yum or apt-get.

A Packaging Example

Basic Configuration

The rpm files are very similar to deb files and their differences lie mainly in configurations. Here we use rpm packages as an example. CPack packages rpm with the CPack RPM generator. All the configurations used are prefixed with CPACK_RPM. The rpm-build tool is used to build the package, so make sure it has already been installed. You can install rpm-build via sudo yum install -y rpm-build. In our example, we're using CMake 3.14.5.

The following is the structure of our sample project:

  |-- CMakeLists.txt // Main CMakeLists.txt file of the project 
  |-- Readme.txt 
  |-- License.txt 
  |-- src 
  | |-- CMakeLists.txt 
  | |-- MainA.cpp // Source code of the executable file Aprogram 
  | |\_\_ MainB.cpp // Source code of the executable file Bprogram 
  |-- etc 
  | |-- CMakeLists.txt 
  | |-- A.conf // Configuration file of the executable file Aprogram
  | |\_\_ B.conf // Configuration file of the executable file Bprogram 
  |\_\_ scripts 
     |-- preinst // Script to be executed before installation 
     |-- postinst // Script to be executed after installation 
     |-- prerm // Script to be executed before uninstallation 
     |\_\_ postrm // Script to be executed after uninstallation
Enter fullscreen mode Exit fullscreen mode

Add the following configurations to the example/CMakeLists.txt file.

# Set Package Name 
set(CPACK\_PACKAGE\_NAME "example") 
# Enable Customized Installation Directory With ON 
# Set Installation Directory 
set(CPACK\_INSTALL\_PREFIX "/home/vesoft/install") 
# Set The Version Information of The Installation Package
# Set The Group Name 
set(CPACK\_RPM\_PACKAGE\_GROUP "vesoft") 
# Set The Vendor Name 
set(CPACK\_PACKAGE\_VENDOR "vesoft") 
# Set The License Information 
set(CPACK\_RPM\_PACKAGE\_LICENSE "Apache 2.0 + Common Clause 1.0") include(CPack)
Enter fullscreen mode Exit fullscreen mode

When the cmake command is run, two new files will be generated in the current directory: CPackConfig.cmake and CPackSourceConfig.cmake. When compilation is completed, run cpack -G RPM to pack the files into an rpm package. You will find a new directory _CPack_Packages and a file with .rpm extension example-1.0.0-Linux.rpm is generated in the current directory. The installation package file is named example-1.0.0-Linux.rpm , which is the target package.

If you want to check detailed outputs when packing, add --verbose behind the cpack -G RPM command. CPack generates the _CPack_Packages/Linux/RPM/SPECS/example.spec file which is used to build the rpm based on the customer configuration.

The installation package example-1.0.0-Linux.rpm generated by the above configuration contains the following files:

Note: if there is a conflict during the installation like this file /home from install of example-1.0.0-1.x86_64 conflicts with file from package filesystem-3.2-25.el7.x86_64, add the following configurations to exclude /home and /home/vesoft in the generated rpm file.

Enter fullscreen mode Exit fullscreen mode

Adding Behaviors

You can embed a pre/post (un)installation script in the spec file:

  • preinst: Pre install script
  • postinst: Post install script
  • prerm: Pre uninstall script
  • postrm: Post uninstall script

Add the following configurations in the above CMakeLists.txt file:

# Set the script preinst to be executed before installation
# Set the script prerm to be executated before uninstallation set(CPACK\_RPM\_PRE\_UNINSTALL\_SCRIPT\_FILE ${CMAKE\_CURRENT\_SOURCE\_DIR}/scripts/prerm) 
# Set the script postinst to be executed after installation set(CPACK\_RPM\_POST\_INSTALL\_SCRIPT\_FILE ${CMAKE\_CURRENT\_SOURCE\_DIR}/scripts/postinst) 
# Set the script postrm to be executed after uninstallation set(CPACK\_RPM\_POST\_UNINSTALL\_SCRIPT\_FILE ${CMAKE\_CURRENT\_SOURCE\_DIR}/scripts/postrm)
Enter fullscreen mode Exit fullscreen mode

Note: The above four scripts require execute permissions for all users and user groups. You can change the file permissions under the script directory with chmod 755 scripts/* after creating the scripts.

Call the sudo rpm -ivh example-1.0.0-Linux.rpm and you'll see the following outputs:

Run the sudo rpm -e example-1.0.0 and you'll see the following outputs:

The green and red words in the pictures are the printouts of the pre/post (un)installation scrip, which indicates they are executed as expected or not.

Generating Multiple Packages With CPackComponent

The above configuration packs all the files to a single installation package. However, often a project contains multiple services which will be deployed on different machines. In this case, you don’t want to pack all of them into one package because this will make the package too large in size. At this time, you need the CPack components.

We will introduce to you the three CPack component functions in the following section: cpack_add_component , cpack_add_component_group and install.

Add a definition for the install function:

Add a definition for the cpack_add_component function:

Add a definition for the cpack_add_component_group function:

Assume we are packing program A and its configuration file A.conf into an rpm package, program B and its configuration file B.conf into another rpm package, we need to replace the include(CPack) of the above example/CMakeLists.txt with the following configurations:

# Set one rpm package per group 


# Add a component named AComponent 
cpack\_add\_component(AComponent DISPLAY\_NAME "A program" DESCRIPTION "The program for test" GROUP Aprogram) 
# Add a component named BComponent 
cpack\_add\_component(BComponent DISPLAY\_NAME "B program" DESCRIPTION "The program for test" GROUP Bprogram) 
# Add a group named Aprogram, this will make part of the rpm package name 
# Add a group named Bprogram 
Enter fullscreen mode Exit fullscreen mode

Then modify src/CMakeLists.txt, as show below, the config the COMPONENT option of installation rules of program A and B to AComponent and BComponent

So as the etc/CMakeLists.txt

After that, re-run cmake command to generate a new makefile. Then call cpack -G RPM. Two files will be generated under the current directory, i.e. example-1.0.0-Linux-Aprogram.rpm and example-1.0.0-Linux-Bprogram.rpm , each of which contains the following files:

More Common Parameters

# Set the default reset directory 
set(CPACK\_PACKAGING\_INSTALL\_PREFIX "/home/vesoft/install")
Enter fullscreen mode Exit fullscreen mode

The relocatable RPM can be installed using:

sudo rpm -ivh example-1.0.0-Linux-Aprogram.rpm --prefix=/home/test/install
Enter fullscreen mode Exit fullscreen mode

You can use CPACK_RPM_SPEC_MORE_DEFINE option to add any %define lines to the generated spec file.

More About CPack

There are many parameters for CPack. And parameters in different versions may vary. Please refer to the CPack Site for details or use CPack --help for more information.

Applying CPack in NebulaGraph Database

We use CPack to pack rpm and deb packages for Nebula Graph. Click here to get packages of each release version.

You might also like:

  1. Automating Your Project Processes with Github Actions
  2. Practice Jepsen Test Framework in NebulaGraph
  3. Integrating Codecov Test Coverage With NebulaGraph

Hi, I’m Laura, an engineer at NebulaGraph. Hope my post is of help to you. Please let me know if you have any ideas about this. Thanks~

Like what we do ? Star us on GitHub.

Originally published at on May 19, 2020.

Top comments (0)