Post

How to use Cpack and NSIS to Package applications on Windows

Basic Setup

Assuming you have your base project(ABC) setup with CMake, let’s get started.

Download and Install NSIS from here. We’ll need this to use CPack with NSIS.

Icons on Widows

Let’s add an icon to our built application by creating a file called abc.rc which is a resource file used by MSVCC to apply icons, among other stuff.

1
IDI_ICON1               ICON        DISCARDABLE            "abc.ico"

Add this definition to our add_executable command

1
2
3
4
5
add_executable(abc 
${ABC_SOURCE_DIR}/assets/abc.rc
${SOURCES} 
# other stuff
)

Windows Specific Config

Next we need to define our install targets that CPack will pick up on

1
2
3
4
install(TARGETS abc 
         #other stuff
         DESTINATION bin
    )

Here, bin is any folder you want to put your built application in. In this case, running the installer will install abc.exe into C:\Program Files(x86)\abc\bin\abc.exe .

Normally, you would set the install target’s DESTINATION to ${CMAKE_INSTALL_PREFIX} However, CPack will give you an error: ABSOLUTE path INSTALL DESTINATION forbidden (by caller):

After what seemed like an eternity of google searching, I came across a solution

You are trying to install some files using an ABSOLUTE path DESTINATION. 99.999% of the time this is an error on the Windows platform.

Normally you should be installing files to a RELATIVE path DESTINATION.

Cpack Config

Additional stuff that you can configure

1
2
3
4
5
6
7
8
9
10
11
12
    include(InstallRequiredSystemLibraries)
    set(CPACK_PACKAGE_INSTALL_DIRECTORY "
    set(CPACK_GENERATOR "NSIS")
    set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
    set(CPACK_PACKAGE_VERSION "${ABC_VERSION_MAJOR}.${ABC_VERSION_MINOR}")
    set(CPACK_PACKAGE_VERSION_PATCH "0")
    set(CPACK_PACKAGE_VENDOR "David Velho")
    set (CPACK_NSIS_MODIFY_PATH "ON")
    set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY ${PROJECT_NAME})
    set(CPACK_SOURCE_GENERATOR "TGZ")
    set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
    set(CPACK_SOURCE_IGNORE_FILES ${CPACK_IGNORE_FILES})

Some additional fields

1
2
3
4
5
6
7
    set(CPACK_NSIS_INSTALLED_ICON_NAME "${ABC_SOURCE_DIR}/assets/abc.ico")
    set(CPACK_NSIS_HELP_LINK ${APP_URL})
    set(CPACK_NSIS_URL_INFO_ABOUT ${APP_URL})
    set(CPACK_NSIS_CONTACT ${APP_EMAIL})
 set(CPACK_NSIS_CREATE_ICONS_EXTRA
    "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\abc.lnk' '$INSTDIR\\\\bin\\\\abc.exe' "
    )

Let’s give the generated installer an icon

1
set(CPACK_NSIS_MUI_ICON "${ABC_SOURCE_DIR}/assets/abc.ico")

And last, the NSIS installer script that CMake will read from and substitute the values into

1
set(CMAKE_MODULE_PATH  ${PROJECT_SOURCE_DIR}/assets/nsis ${CMAKE_MODULE_PATH})

Where assets/nsis has a file called NSIS.definitions.nsh.in which is a script file needed by NSIS. CMake will read this file and substitute the values in so that NSIS can read it

NSIS.definitions.nsh.in :

1
2
3
4
5
6
7
8
9
10
11
!define VERSION "@APP_VERSION@"
!define APP_VERSION "@APP_VERSION@"
!define APP_NAME "@APP_NAME@"
!define EXE_NAME "@EXE_NAME@"
!define README_FILE "README"
!define LICENSE_FILE "@PROJECT_SOURCE_DIR@resourcestextLICENSE"
!define MUI_ICON "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@.ico"
!define MUI_UNICON "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@.ico"
!define MUI_WELCOMEFINISHPAGE_BITMAP "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@-banner.bmp"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@-banner.bmp"
!define PATCH  "0"

Let’s include CPack and some NSIS config files

1
2
3
4
5
    include(CPack)
    configure_file(
    ${PROJECT_SOURCE_DIR}/assets/nsis/NSIS.definitions.nsh.in
    ${CMAKE_CURRENT_BINARY_DIR}/assets/nsis/NSIS.definitions.nsh
    )

Assuming you’ve added CMake to PATH during installation, you should have cpack in path. You can (while in the build directory) build the installer with

1
2
3
4
5
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
MSBuild.exe abc.sln
cpack -C Release

Additional Resources

This post is licensed under CC BY 4.0 by the author.