CMake packaging with CPack example

CMake is a meta build system that generates build files such as Makefile, build.ninja, .sln, etc. consumed by the build system such as GNU Make, Ninja, Visual Studio, etc. corresponding to the CMake Generator selected. CMake has a corresponding meta package system CPack. CPack generates configuration files for numerous packaging systems. To distribute code to users without requiring them to compile a project is done via these packages. The reader has probably already installed numerous packages like Windows .msi, Linux .deb/.rpm, and MacOS .dmg. CPack creates these binary packages and even more formats. CPack also creates traditional source tarballs as are also generated by GitHub Releases, but with fine-grained control of the contents.

Assuming the PROJECT_BINARY_DIR is “build”, CPack generates build/CPackConfig.cmake for binary packages and build/CPackSourceConfig.cmake for source packages. CPackConfig.cmake is generated according to install() commands in the CMakeLists.txt files of the project. CPackSourceConfig.cmake works the opposite way–it includes everything not excluded by CPACK_SOURCE_IGNORE_FILES, so we make a file cmake/.cpack_ignore with regex excluding non-source files. As a last step at the end of the main CMakeLists.txt after all install(), we include cmake/cpack.cmake:

As usual:

cmake -B build
cmake --build build

The distribution packaged .zip / .tar.gz files under build/package are generated by:

cpack --config build/CPackSourceConfig.cmake

cpack --config build/CPackConfig.cmake

These can be built by the CI system and uploaded for distribution on GitHub Releases, etc. by configuring the .github/workflows/ci.yml accordingly.