Skip to content

CPack

CPack is the packager system, gathering the installation files into an all-in-one installer.

Basis

CPack is "independent" from CMake, in the way that one can choose which targets have to be deployed or not.

No new file is needed, simply a few lines added to the CMakeLists.txt.

Learning by doing

The example from CMake is modified to integrate CPack and generate the installer for both programs. The installer will be for Windows.

The files are available here.

Install

First, we will add an install() command for each library and program generated. E.g. for the library, the command will look like: install(TARGETS ${PROJECT_NAME} DESTINATION "./" COMPONENT COMMON). The TARGETS define which targets to install (here the library target), then where to put the file with DESTINATION (./ meaning at the root of the install path, and finally under which COMPONENT it is installed (e.g. the libraries can be grouped under the same component named COMMON)).

Once the various install() commands are defined, one can run CMake with install as build target. It will deploy the files under the path defined with CMAKE_INSTALL_PREFIX. It is then possible to check that everything is installed correctly.

Package

Next step is to package everything into an installer. Since all the install commands are ready, it is simply left to configure the packager. Here will the NSIS installer be used.

The top CMakeLists is modified by adding the following lines:

# Binary installer
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ".") #output dlls under given folder and not bin/ or lib/ ; else will not work on windows without some specific HKEY_REGISTRY paths set
include(GNUInstallDirs)
include(InstallRequiredSystemLibraries)

set(CPACK_PACKAGE_VENDOR "SPL Group - HEI")

if(WIN32 AND NOT UNIX)
  # There is a bug in NSI that does not handle full UNIX paths properly.
  # Make sure there is at least one set of four backlashes.
  set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/res\\\\cmake.png")
  set(CPACK_NSIS_DISPLAY_NAME "CMake Example")
  set(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.spl.hevs.io")
  set(CPACK_NSIS_MODIFY_PATH ON)
endif()
  # here, the whole CPack variables must be set
include(CPack)
# Add Prog1 as selection to install
cpack_add_component(${PROG1_NAME}
    DISPLAY_NAME "Prog1"
    DESCRIPTION "Prog1 making an addition"
)
# Add Prog2 as selection to install
cpack_add_component(${PROG2_NAME}
    DISPLAY_NAME "Prog2"
    DESCRIPTION "Prog2 making an addition and a substraction"
)
# Add libraries and force to install
cpack_add_component("COMMON"
    DISPLAY_NAME "Common libs"
    REQUIRED
)
With that set, the target package can be built through CMake. It will generate the installer. It should be tested against a fresh OS to ensure no library is missing.

Example with Qt

Qt also offers a packager named IFW, compatible with CMake. It can be used along with windeployqt, which is able to retrieve the necessary Qt DLLs and prepare a tree for the program to work. See an example under Gitlab.