CMake packaging with CPack example

CMake has a corresponding meta package system CPack, which generates configuration files for numerous packaging systems. Distributing code and binary executablees and libraries to users without requiring them to compile a project is done via these packages. CPack creates these binary packages like Windows .msi, Linux .deb/.rpm, macOS .dmg, etc. CPack also creates traditional source archives 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.

Note that in general “install()” DESTINATION should always use relative paths. CPack ignores install() items with absolute DESTINATION.

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.