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:

 1# Binary installer
 2set(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
 3include(GNUInstallDirs)
 4include(InstallRequiredSystemLibraries)
 5
 6set(CPACK_PACKAGE_VENDOR "SPL Group - HEI")
 7
 8if(WIN32 AND NOT UNIX)
 9  # There is a bug in NSI that does not handle full UNIX paths properly.
10  # Make sure there is at least one set of four backlashes.
11  set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/res\\\\cmake.png")
12  set(CPACK_NSIS_DISPLAY_NAME "CMake Example")
13  set(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.spl.hevs.io")
14  set(CPACK_NSIS_MODIFY_PATH ON)
15endif()
16  # here, the whole CPack variables must be set
17include(CPack)
18# Add Prog1 as selection to install
19cpack_add_component(${PROG1_NAME}
20    DISPLAY_NAME "Prog1"
21    DESCRIPTION "Prog1 making an addition"
22)
23# Add Prog2 as selection to install
24cpack_add_component(${PROG2_NAME}
25    DISPLAY_NAME "Prog2"
26    DESCRIPTION "Prog2 making an addition and a substraction"
27)
28# Add libraries and force to install
29cpack_add_component("COMMON"
30    DISPLAY_NAME "Common libs"
31    REQUIRED
32)

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.