[CMake] Multiple installer packages from subsets of one large CMake project?
KSpam
keesling_spam at cox.net
Tue Apr 14 13:16:19 EDT 2009
Kerry,
On Tuesday 14 April 2009 06:37:28 Kerry Bonin wrote:
> Short version: Is there a simple way to generate multiple separate
> installers from within one CMake project?
The short answer is that it is possible, but perhaps it is not "simple". This
task does take some digging into CPack, and CPack could benefit from more
documentation. It is a wonderful tool despite the shortcomings though!
I am using CPack for packaging many different kinds of installers for a very
large commercial source base, and my requirements are likely similar to
yours. I will try to explain the general idea.
1) You need to create many components. In my case, I have different
components for source (i.e. .cpp and .hpp files), library (i.e. .lib files
and .hpp files), and runtime (i.e. .so or .dll files and .exe files) variants
of each of my libraries and applications. To create components, you simply
need to specify "COMPONENT" for the "INSTALL" commands.
2) You need to create a custom CPack script. Normally, you will want to name
this CPackConfig.cmake. This file will specify the components that you want
to include in your installer. You will probably want to create a different
CPackConfig.cmake file for each installer configuration you want to build.
3) Run cpack. This will read your CPackConfig.cmake file and generate an
istaller for it.
In my case, I have a Python script that reads a simple configuration file
(i.e. the necessary components) for my desired installer and creates the
appropriate CPackConfig.cmake file. Then, I run cpack to generate the
desired installer from the CPackConfig.cmake file.
So the real magic is what's inside the CPackConfig.cmake file. In my case, I
set a bunch of CMake variables at the top of the file:
CPACK_PACKAGE_NAME
CPACK_PACKAGE_VERSION_MAJOR
CPACK_PACKAGE_VERSION_MINOR
CPACK_PACKAGE_VERSION_PATCH
CPACK_PACKAGE_DESCRIPTION_FILE
CPACK_RESOURCE_FILE_LICENSE
CPACK_RESOURCE_FILE_README
CPACK_RESOURCE_FILE_WELCOME
CPACK_PACKAGE_VENDOR
CPACK_PACKAGE_VERSION
CPACK_PACKAGE_FILE_NAME
CPACK_PACKAGE_INSTALL_DIRECTORY
CPACK_PACKAGE_INSTALL_REGISTRY_KEY
CPACK_GENERATOR
Some of the variables are required, and CPack will error out if you do not set
them. This part will probably take a little trial-and-error. After setting
the variables, I compose a list of components:
# Components that I want to include in my installer
set(myComponentList
libA-rt # "rt" for runtime
libB-lib # "lib" includes headers, libraries, and runtime
exampleApp-src # "src" Source component for an example app
appC-rt # "rt" for runtime ... just the executable
)
I also set a variable for the build directory and install prefix:
# This is used to find the top-level cmake_install.cmake script
set(myBuildDir
"/location/to/the/build/directory
)
# This is where the files are "staged"
set(myInstallPrefix
"_CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}"
)
Finally, the components are installed by appending an appropriate command to
CPACK_INSTALL_COMMANDS:
# Append a command to CPACK_INSTALL_COMMANDS for each component
foreach (component ${myComponentList
set(standardArgs "-D CMAKE_INSTALL_COMPONENT=${component}")
set(standardArgs "${standardArgs} -D CMAKE_INSTALL_DO_STRIP=TRUE")
set(standardArgs "${standardArgs} -D
CMAKE_INSTALL_PREFIX=${myInstallPrefix}")
set(standardArgs "${standardArgs} -P ${myBuildDir}/cmake_install.cmake")
list(APPEND CPACK_INSTALL_COMMANDS
"${CMAKE_COMMAND} -D CMAKE_INSTALL_CONFIG_NAME=Release ${standardArgs}"
)
endforeach (component)
Hopefully, this will give you enough information to start playing with CPack!
Hope This Helps,
Justin
More information about the CMake
mailing list