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
pathDESTINATION
. 99.999% of the time this is an error on the Windows platform.
Normally you should be installing files to a
RELATIVE
pathDESTINATION
.
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