CPack NSIS on Windows packaging tutorial

David Velho
2 min readMay 5, 2021

--

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.

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.

ID1_ICON1 ICON DISCARDABLE "abc.ico"

Add this definition to our add_executable command

add_executable(abc 
${ABC_SOURCE_DIR}/assets/abc.rc
${SOURCES}
# other stuff
)

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

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


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

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

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

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 :

!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

 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

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
MSBuild.exe abc.sln
cpack -C Release

Additional Resources

- CPack NSIS
- CPack Start Menu Link
- CMake CPack
- CMake tutorial
- CMake NSIS
- Absolute Path CPack error fix

--

--