|
|
(16 intermediate revisions by 7 users not shown) |
Line 1: |
Line 1: |
| = Component-Based Installers with CPack =
| | {{CMake/Template/Moved}} |
|
| |
|
| CPack builds binary installers for a variety of platforms using
| | This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/Component-Install-With-CPack here]. |
| CMake's existing installation infrastructure (see the list of supported [http://www.cmake.org/Wiki/CMake:CPackPackageGenerators CPack generators]). Augmented by a set of
| |
| CPack-specific macros, a program built with CMake can easily be
| |
| distributed via a user-friendly installer.
| |
| | |
| By default, CPack's installers consider all of the files installed by
| |
| a project as a single, monolithic unit: either the whole set of files
| |
| is installed, or none of the files are installed. However, with many
| |
| projects it makes sense for the installation to be subdivided into
| |
| distinct, user-selectable components: some users may want to install
| |
| only the comand-line tools for a project, while other users might want
| |
| the GUI or the header files.
| |
| | |
| This document describes how to configure CPack to generate
| |
| component-based installers that allow users to select the set of
| |
| project components that they wish to install.
| |
| | |
| == Principles of CPack Component Packaging ==
| |
| | |
| The principles of CPack component packaging is based on differents
| |
| ways to ''group'' things together in order to define component content.
| |
| | |
| === Rules ===
| |
| There are some basic rules about components:
| |
| # An object cannot belong to several COMPONENT
| |
| # Each component may only belong to a single component GROUP
| |
| # The name of each COMPONENT should be unique (and different from ''Unspecified'' which is a reserved component name)
| |
| # The name of a component GROUP should be unique and cannot be the same as the name of a COMPONENT
| |
| # A component GROUP may have a PARENT_GROUP which is a component GROUP
| |
| # A component does not have to belong to any component GROUP
| |
| # There may be no component GROUP at all (using component grouping is '''not mandatory''')
| |
| # There may be no component at all (using component install is '''not mandatory''')
| |
| # Not all CPack generators honor component packaging some of them just '''ignore''' the component specification
| |
| | |
| === Specificying components and groups ===
| |
| First for each install rule like this one:
| |
| INSTALL(...
| |
| [COMPONENT component]
| |
| ...)
| |
| | |
| the COMPONENT option should be specified with the name of the chosen component.
| |
| This means that all objects (TARGETS, FILES, ...) concerned by this install rule
| |
| will belong to the specified component.
| |
| | |
| If some INSTALL rule does not specify the COMPONENT CMake will create a
| |
| COMPONENT named ''Unspecified'' which contains the target of every such rules.
| |
| | |
| After that grouping and depencies may be specified by two ways:
| |
| | |
| ''FIXME TO BE CONTINUED'' (see CPack.cmake embedded documentation)
| |
| | |
| == CPack Generator specific behavior ==
| |
| | |
| CPack comes with several binary Generators: NSIS, PackageMaker, TGZ, ZIP, RPM, DEB...
| |
| Depending on the capacity of the [http://www.cmake.org/Wiki/CMake:CPackPackageGenerators specific generator] the component packaging
| |
| will produce:
| |
| | |
| * For component-aware generators:
| |
| ** a single "component-aware" package file : NSIS, PackageMaker
| |
| ** possibly multiple package files: ArchiveGenerator (TBZ2, TGZ, STGZ, TZ, ZIP), RPM
| |
| * For non-component-aware generators:
| |
| ** a single MONOLITHIC package file just as if no component were specified: DEB
| |
| | |
| === Controlling packaging of component-aware generators ===
| |
| | |
| ==== Forcing MONOLITHIC installers ====
| |
| The component aware generators may be forced to ignore component if one set:
| |
| set(CPACK_MONOLITHIC_INSTALL 1)
| |
| If this variable is set at CMake time (inside a CMakeLists.txt) then all generators will be producing a single a.k.a. MONOLITHIC package file.
| |
| Since CMake/CPack 2.8.4 the CPACK_MONOLITHIC_INSTALL var may be handled at CPack time if set inside CPACK_PROJECT_CONFIG_FILE.
| |
| | |
| ==== Enabling Component Packaging ====
| |
| Some component-aware generators have backward-compatible behavior
| |
| which makes them NOT to generate component install.
| |
| In fact, this is currently the case for ArchiveGenerator and RPM.
| |
| In that particular case if you want to change this default non-component-aware behavior
| |
| you may set the specific variable CPACK_<GENNAME>_COMPONENT_INSTALL to ON.
| |
| For example for enabling component for the RPM generator you'll have to:
| |
| | |
| set(CPACK_RPM_COMPONENT_INSTALL ON)
| |
| | |
| ==== Controlling Differents Ways of packaging components ====
| |
| For CPack generators which generates several packages the default behavior is to generate one package per COMPONENT GROUP.
| |
| However, one can modify this default behavior by using:
| |
| | |
| * Single package file containing all COMPONENT GROUPS:
| |
| | |
| set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE 1)
| |
| | |
| * Single package file containing all COMPONENTS (ignore COMPONENT GROUP and single file):
| |
| | |
| set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
| |
| | |
| * One package per COMPONENT (ignore COMPONENT GROUP but several files):
| |
| | |
| set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
| |
| | |
| = Step-by-step example Component-Based Installers =
| |
| In this document, we
| |
| will develop a simple installer for a simple library that has three
| |
| components: a library binary, a sample application, and a C++ header
| |
| file. When we have finished, these resulting installers will looks
| |
| like the customizable installers below, shown for Mac OS X and
| |
| Windows:
| |
| | |
| [[Image:CPackComponentsFinalWindows.JPG]] [[Image:CPackComponentsFinalMac.jpg]]
| |
| | |
| == Prerequisites ==
| |
| | |
| To begin, you should be able to build graphical installers using CPack
| |
| either on Windows (using the NullSoft Installation System, NSIS) or
| |
| Mac OS X (using PackageMaker). Also, as of the time of this writing,
| |
| the extensions to CPack required to build component-based installers
| |
| are only available since CMake 2.6.1 (NSIS and PackageMaker)
| |
| or CMake 2.8.3 (Archive Generator). Component support for other
| |
| CPack generator should come sooner or later, check the release notes.
| |
| | |
| As our primary example, we will use a simple library called "MyLib"
| |
| that builds a single library (`mylib`) and an application based on
| |
| that library (`mylibapp`). The file [[Image:ComponentExampleStart.zip]] contains
| |
| the skeleton of such a library, with the following build and
| |
| installation commands in `CMakeLists.txt`:
| |
| | |
| cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
| |
| project(MyLib)
| |
| | |
| add_library(mylib mylib.cpp)
| |
| | |
| add_executable(mylibapp mylibapp.cpp)
| |
| target_link_libraries(mylibapp mylib)
| |
| | |
| install(TARGETS mylib
| |
| ARCHIVE
| |
| DESTINATION lib)
| |
| install(TARGETS mylibapp
| |
| RUNTIME
| |
| DESTINATION bin)
| |
| install(FILES mylib.h
| |
| DESTINATION include)
| |
| | |
| You should be able to configure, build, and (optionally) install this
| |
| project using CMake with its library, application, and header file.
| |
| | |
| == Building Binary Installers with CPack ==
| |
| | |
| To build binary installers with CPack, first add the following to the
| |
| end of `CMakeLists.txt`:
| |
| | |
| set(CPACK_PACKAGE_NAME "MyLib")
| |
| set(CPACK_PACKAGE_VENDOR "CMake.org")
| |
| set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyLib - CPack Component Installation Example")
| |
| set(CPACK_PACKAGE_VERSION "1.0.0")
| |
| set(CPACK_PACKAGE_VERSION_MAJOR "1")
| |
| set(CPACK_PACKAGE_VERSION_MINOR "0")
| |
| set(CPACK_PACKAGE_VERSION_PATCH "0")
| |
| set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
| |
| | |
| # This must always be last!
| |
| include(CPack)
| |
| | |
| More information about CPack and its configuration macros can be found
| |
| [[CMake:CPackConfiguration|here]], but this boilerplate suffices to enable the packaging target
| |
| in a CMake build. From here, makefile users can invove `make package`
| |
| to build a binary installer (e.g., on Mac OS X) and Visual Studio
| |
| users can build the PACKAGE target.
| |
| | |
| Throughout this tutorial, we will be setting more `CPACK_` macros in
| |
| `CMakeLists.txt` to communicate with CPack. It is very important that
| |
| the SET commands for these macros come before the include of the
| |
| `CPack` module!
| |
| | |
| == Identifying Components ==
| |
| | |
| The first step in building a component-based installation is to
| |
| identify the set of installable components. In our example library, we
| |
| have decided on three components: the library binary, the application,
| |
| and the header file. This decision is arbitrary and project-specific,
| |
| but be sure to identify the components that correspond to units of
| |
| functionality important to your user rather than basing the components
| |
| on the internal structure of your program.
| |
| | |
| For each of these components, we need to identify which installed
| |
| files are part of the component. For each INSTALL command in
| |
| `CMakeLists.txt`, add an appropriate COMPONENT argument stating which
| |
| component the installed files will be associated with:
| |
| | |
| install(TARGETS mylib
| |
| ARCHIVE
| |
| DESTINATION lib
| |
| COMPONENT libraries)
| |
| install(TARGETS mylibapp
| |
| RUNTIME
| |
| DESTINATION bin
| |
| COMPONENT applications)
| |
| install(FILES mylib.h
| |
| DESTINATION include
| |
| COMPONENT headers)
| |
| | |
| Note that the COMPONENT argument to the INSTALL command is not new; it
| |
| has been a part of CMake's INSTALL command to allow installation of
| |
| only part of a project. If you are using any of the older installation
| |
| commands (INSTALL_TARGETS, INSTALL_FILES , etc.), you will need to
| |
| convert them to INSTALL commands to add the COMPONENT argument.
| |
| | |
| Finally, notify CPack of the names of all of the components in your
| |
| project by setting the CPACK_COMPONENTS_ALL variables:
| |
| | |
| set(CPACK_COMPONENTS_ALL applications libraries headers)
| |
| | |
| At this point, you can build a component-based installer with CPack
| |
| that will allow one to independently install the applications,
| |
| libraries, and headers of MyLib.
| |
| | |
| [[Image:CPackComponentBasicWindows.JPG]][[Image:CPackComponentBasicMac.jpg]]
| |
| | |
| == Component Descriptions ==
| |
| | |
| If you have built a binary installer at this point, you may have noted
| |
| that the names of the actual components in the installer are not very
| |
| descriptive: they just say "applications", "libraries", or "headers",
| |
| as in the component names. We can improve on these names by setting
| |
| several additional CPack variables:
| |
| | |
| set(CPACK_COMPONENT_APPLICATIONS_DISPLAY_NAME "MyLib Application")
| |
| set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
| |
| set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers")
| |
| | |
| Any macro prefixed with CPACK_COMPONENT_${COMPNAME}, where ${COMPNAME}
| |
| is the uppercase name of a component, is used to set a particular
| |
| property of that component in the installer. Here, we set the
| |
| DISPLAY_NAME property of each of our components, so that we get
| |
| human-readable names. These names will be listed in the selection box
| |
| rather than the internal component names "applications", "libraries",
| |
| "headers".
| |
| | |
| [[Image:CPackComponentNamesWindows.JPG]] [[Image:CPackComponentNamesMac.jpg]]
| |
| | |
| There are several other properties associated with components,
| |
| including the ability to make a component hidden, required, or
| |
| disabled by default, to provide additional descriptive information,
| |
| etc. We will encounter some of these other properties later; see the
| |
| macro reference for a complete list.
| |
| | |
| Of particular note is the DESCRIPTION property, which provides some
| |
| descriptive text for the component. This descriptive text will show up
| |
| in a separate "description" box in the installer, and will be updated
| |
| either when the user's mouse hovers over the name of the corresponding
| |
| component (Windows) or when the user clicks on a component (Mac OS
| |
| X). Here, we add a description for each of our components:
| |
| | |
| set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION
| |
| "An extremely useful application that makes use of MyLib")
| |
| set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
| |
| "Static libraries used to build programs with MyLib")
| |
| set(CPACK_COMPONENT_HEADERS_DESCRIPTION
| |
| "C/C++ header files for use with MyLib")
| |
| | |
| Generally, descriptions should provide enough information for the user
| |
| to make a decision whether to include the component, but should not
| |
| themselves be more than a few lines long (because the "Description"
| |
| box in the installers tends to be small).
| |
| | |
| [[Image:CPackComponentDescWindows.JPG]][[Image:CPackComponentDescMac.jpg]]
| |
| | |
| == Intercomponent Dependencies ==
| |
| | |
| With most projects, the various components are not completely | |
| independent. For example, an application component may depend on the
| |
| shared libraries in another component to execute properly, such that
| |
| installing the application component without the corresponding shared
| |
| libraries would result in an unusable installation. CPack allows you
| |
| to express the dependencies between components, so that a component
| |
| will only be installed if all of the other components it depends on
| |
| are also installed.
| |
| | |
| To illustrate component dependencies, we will place a simple
| |
| restriction on our component-based installer. Since we do not provide
| |
| source code in our installer, the C++ header files we distribute can
| |
| only actually be used if the user also installs the library binary to
| |
| link her program against. Thus, the "headers" component depends on the
| |
| availability of the "libraries" component. We can express this notion
| |
| by setting the DEPENDS property for the HEADERS component as such:
| |
| | |
| set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
| |
| | |
| The DEPENDS property for a component is actually at list, and as such a
| |
| component can depend on several other components. By expressing all of
| |
| the component dependencies in this manner, you can ensure that users
| |
| will not be able to select an incomplete set of components at
| |
| installation time.
| |
| | |
| == Grouping Components ==
| |
| | |
| When the number of components in your project grows large, you may
| |
| need to provide additional organization for the list of components. To
| |
| help with this organization, CPack includes the notion of component
| |
| groups. A component group is, simply, a way to provide a name for a
| |
| group of related components. Within the user interface, a component
| |
| group has its own name, and underneath that group come all of the
| |
| names of the components within the group. Users will have the option
| |
| to (de-)select installation of all components in the group with a
| |
| single click, or expand the group to select individual components.
| |
| | |
| We will expand our example by categorizing its three components,
| |
| "applications", "libraries", and "headers", into "Runtime" and
| |
| "Development" groups. We place a component into a group by setting the
| |
| GROUP property of the component to the name of the group as follows:
| |
| | |
| set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime")
| |
| set(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
| |
| set(CPACK_COMPONENT_HEADERS_GROUP "Development")
| |
| | |
| Like components, component groups have various properties that can be
| |
| customized, including the DISPLAY_NAME and DESCRIPTION. To customization
| |
| a component group, set the appropriate CPack macro with the prefix
| |
| CPACK_COMPONENT_GROUP_${GROUPNAME}, where ${GROUPNAME} is the
| |
| uppercase name of the group to modify. For example, the following code
| |
| adds a description to the "Development" group:
| |
| | |
| set(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
| |
| "All of the tools you'll ever need to develop software")
| |
| | |
| Once you have customized the component groups to your liking, rebuild
| |
| the binary installer to see the new organization: the MyLib
| |
| application will show up under the new "Runtime" group, while the
| |
| MyLib library and C++ header will show up under the new "Development"
| |
| group. One can easily turn on/off all of the components within a group
| |
| using the installer GUI. Some additional customizations of component
| |
| groups are possible; please see the macro reference for a complete
| |
| list.
| |
| | |
| [[Image:CPackComponentGroupsWindows.JPG]][[Image:CPackComponentGroupsMac.jpg]]
| |
| | |
| == Installation Types (NSIS Only) ==
| |
| | |
| When a project contains a large number of components, it is common for
| |
| a Windows installer to provide pre-selected sets of components based
| |
| on specific user needs. For example, a user wanting to develop
| |
| software against a library will want one set of components, while an
| |
| end user might use an entirely different set. CPack supports this
| |
| notion of pre-selected component sets via installation types. An
| |
| installation type is, simply, a set of components. When the user
| |
| selects an installation type, exactly that set of components is
| |
| selected---then the user is permitted to further customize the
| |
| installation as desired.
| |
| | |
| For our simple example, we will create only two installation types: a
| |
| "Full" installation type, which contains all of the components, and a
| |
| "Developer" installation type, which includes only the libraries and
| |
| headers. To do so, we first tell CPack which installation types we're
| |
| using:
| |
| | |
| set(CPACK_ALL_INSTALL_TYPES Full Developer)
| |
| | |
| Like components and component groups, installation types have some
| |
| properties (e.g., DISPLAY_NAME), which can be set via variables with
| |
| prefix CPACK_INSTALL_TYPE_${INSTNAME}, where ${INSTNAME} is the
| |
| uppercase name of the installation type. See the macro reference for
| |
| additional information.
| |
| | |
| Next, we set the INSTALL_TYPES property of each component to state
| |
| which installation types will include that component:
| |
| | |
| set(CPACK_COMPONENT_LIBRARIES_INSTALL_TYPES Developer Full)
| |
| set(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
| |
| set(CPACK_COMPONENT_APPLICATIONS_INSTALL_TYPES Full)
| |
| | |
| Components can be in any number of installation types. If you now
| |
| rebuild the Windows installer, the components page will contain a
| |
| combo box that allows you to select the installation type and
| |
| therefore its corresponding set of components.
| |
| | |
| [[Image:CPackComponentsFinalWindows.JPG]]
| |
| | |
| == Next Steps ==
| |
| | |
| From here, you should be able to turn your existing CPack-generated
| |
| binary installers into component-based installers to provide your
| |
| users with more-flexible installation options. The complete example
| |
| constructed by this tutorial is available as [[Image:ComponentExample.zip]]. For
| |
| a more advanced example of a component-based installer build with
| |
| CPack, please visit the Boost-CMake project.
| |
| | |
| = Macro Reference =
| |
| | |
| In this reference, ${COMPNAME} refers to a component, ${GROUPNAME}
| |
| refers to a component group, and ${INSTNAME} refers to an installation
| |
| type, all of which are uppercase.
| |
| | |
| {|
| |
| |- bgcolor="#abcdef"
| |
| ! Variable Name || Description
| |
| |-
| |
| | CPACK_COMPONENTS_ALL || A list containing the names of all components that should be installed. The presence of this macro indicates that CPack should build a component-based installer. Files associated with any components not listed here or any installation commands not associated with any component will not be installed.
| |
| |-
| |
| |CPACK_COMPONENT_${COMPNAME}_DISPLAY_NAME || The displayed name of the component ${COMPNAME}, used in graphical installers to display the component name. This value can be any string.
| |
| |-
| |
| |CPACK_COMPONENT_${COMPNAME}_DESCRIPTION || An extended description of the component ${COMPNAME}, used in graphical installers to give the user additional information about the component. Descriptions can span multiple lines using "\n" as the line separator.
| |
| |-
| |
| |CPACK_COMPONENT_${COMPNAME}_HIDDEN || Flag that indicates that this component will be hidden in the graphical installer, and therefore cannot be selected or installed. Only available with NSIS.
| |
| |-
| |
| |CPACK_COMPONENT_${COMPNAME}_REQUIRED || Flag that indicates that this component is required, and therefore will always be installed. It will be visible in the graphical installer, but it cannot be unselected.
| |
| |-
| |
| |CPACK_COMPONENT_${COMPNAME}_DISABLED || Flag that indicates that this component should be disabled (unselected) by default. The user is free to select this component for installation.
| |
| |-
| |
| | CPACK_COMPONENT_${COMPNAME}_DEPENDS || Lists the components on which this component depends. If this component is selected, then each of the components listed must also be selected.
| |
| |-
| |
| | CPACK_COMPONENT_${COMPNAME}_GROUP || Names the component group of which this component is a part. If not provided, the component will be a standalone component, not part of any component group.
| |
| |-
| |
| | CPACK_COMPONENT_${COMPNAME}_INSTALL_TYPES || Lists the installation types of which this component is a part. When one of these installations types is selected, this component will automatically be selected. Only available with NSIS.
| |
| |-
| |
| |CPACK_COMPONENT_GROUP_${GROUPNAME}_DISPLAY_NAME || The displayed name of the component group ${GROUPNAME}, used in graphical installers to display the component group name. This value can be any string.
| |
| |-
| |
| | CPACK_COMPONENT_GROUP_${GROUPNAME}_DESCRIPTION || An extended description of the component group ${GROUPNAME}, used in graphical installers to give the user additional information about the components contained within this group. Descriptions can span multiple lines using "\n" as the line separator.
| |
| |-
| |
| | CPACK_COMPONENT_GROUP_${GROUPNAME}_BOLD_TITLE || Flag indicating whether the group title should be in bold. Only available with NSIS.
| |
| |-
| |
| | CPACK_COMPONENT_GROUP_${GROUPNAME}_EXPANDED || Flag indicating whether the group should start out "expanded", showing its components. Otherwise only the group name itself will be shown until the user clicks on the group. Only available with NSIS.
| |
| |-
| |
| | CPACK_INSTALL_TYPE_${INSTNAME}_DISPLAY_NAME || The displayed name of the installation type. This value can be any string.
| |
| |}
| |
| | |
| | |
| | |
| = Ideas for Future Development =
| |
| * Add support for other binary installer generators, such as RPM and Deb. The installer will then create a set of RPM or Deb files, with appropriate dependencies. A key question here is granularity: RPMs and Debs tend to have a coarser granularity than graphical installers.
| |
| * CPack RPM generator component support: This is true that RPM has coarser granularity, however one may build 1 RPM by component and embbed appropriate dependencies between each generated RPM. For building several RPM at once you may either generate a spec file for each component or generate a single spec file which may contain sub-packages [[http://www.rpm.org/max-rpm/s1-rpm-subpack-spec-file-changes.html]]. --[[User:Erk|Erk]] 04:36, 28 August 2008 (EDT)
| |
| | |
| * Graphviz output of components and their dependencies?
| |
| | |
| {{CMake/Template/Footer}}
| |