Discussion:
[CMake] CPack/NSIS installation of specific components
Doug Gregor
2008-04-17 04:53:01 UTC
Permalink
Hello all,

I have a project that consists of several different libraries, each
with its own headers and generated library targets. I use the
COMPONENT option to the install command to put each library's
installed files into a library-specific component.

Now, what I would like to do is have these components translate into
separate installation options within a single NSIS installer created
by CPack. NSIS has options to include a "Components" page in the
installer, which allows users to select/deselect specific components
to install. Is there any way to do this with CPack?
CPACK_INSTALL_CMAKE_PROJECTS doesn't seem flexible enough.

In anticipation that the answer to the above is "no", I hacked up a
quick prototype of this functionality based on the CVS trunk. A patch
is atttached. It's a little ugly, but it's working for my test case.
Mostly, I'd like to see if there's interest in this feature or if
anyone else has already done it.

The basic idea is that for a given project/component pair (as
specified by CPACK_INSTALL_CMAKE_PROJECTS), one can specify a list of
(sub)components that will actually be installed. Each of these
components can be independently selected (or not) by the user. For
example , the command below says that the Boost project's ALL
component has (sub)components names "Core", "Filesystem", and "Graph"

set(CPACK_COMPONENTS_BOOST_ALL "Core" "Filesystem" "Graph")

Those names corresponding, of course, to components in an install
command, e.g., the "Core" component installs its files like this:

install(DIRECTORY boost
DESTINATION ${BOOST_HEADER_DIR}
COMPONENT Core
PATTERN "CVS" EXCLUDE
REGEX ".svn" EXCLUDE)

Now the installer has a "Components" page with three entries on it:

+ Core
+ Filesystem
+ Graph

Users can choose to install any combination of those by
checking/unchecking the boxes. However, we really don't want the
installer to say just "Core", we want it to say "Core Libraries". In
addition, the "Core Libraries" is a required feature, and must always
be installed. So we add a few more variables before including CPack:

set(CPACK_COMPONENT_BOOST_CORE_REQUIRED ON)
set(CPACK_COMPONENT_BOOST_CORE_DISPLAY_NAME "Core libraries")

Now the generated installer shows the Core component as "Core
libraries", which is checked but grayed out (and not modifiable).

There are lots of cool features that *could* be added from here, with
some level of NSIS scripting knowledge:
- Placing components into subgroups (e.g., we could have "headers",
"runtime libraries", and "development libraries" under each component)
- Providing different installation types (runtime, development,
custom) that pre-select sets of components
- Representing dependencies among components, so that selecting a
component selects all of its dependencies (and unselecting a component
unselects all of the components that depend on it)
- Provide add/remove support on a per-component basis.

Comments? Ideas? Rotten tomatoes?

- Doug
David Cole
2008-04-17 15:50:24 UTC
Permalink
Wow. Very ambitious. I like it...

Your patch is not all that ugly... :-) But it does refer to some things that
are not actually in the patch.

How about adding a feature request to the bug tracker for this and attaching
a zip file (or .tar.gz) with the patch and all the new files that it refers
to.

If you could also add a test project with 2 or 3 components in it that
demonstrates how to use the new variables you've invented, I could see it
becoming part of a future CMake release.....


Thanks for getting the ball rolling.
David Cole
Post by Doug Gregor
Hello all,
I have a project that consists of several different libraries, each
with its own headers and generated library targets. I use the
COMPONENT option to the install command to put each library's
installed files into a library-specific component.
Now, what I would like to do is have these components translate into
separate installation options within a single NSIS installer created
by CPack. NSIS has options to include a "Components" page in the
installer, which allows users to select/deselect specific components
to install. Is there any way to do this with CPack?
CPACK_INSTALL_CMAKE_PROJECTS doesn't seem flexible enough.
In anticipation that the answer to the above is "no", I hacked up a
quick prototype of this functionality based on the CVS trunk. A patch
is atttached. It's a little ugly, but it's working for my test case.
Mostly, I'd like to see if there's interest in this feature or if
anyone else has already done it.
The basic idea is that for a given project/component pair (as
specified by CPACK_INSTALL_CMAKE_PROJECTS), one can specify a list of
(sub)components that will actually be installed. Each of these
components can be independently selected (or not) by the user. For
example , the command below says that the Boost project's ALL
component has (sub)components names "Core", "Filesystem", and "Graph"
set(CPACK_COMPONENTS_BOOST_ALL "Core" "Filesystem" "Graph")
Those names corresponding, of course, to components in an install
install(DIRECTORY boost
DESTINATION ${BOOST_HEADER_DIR}
COMPONENT Core
PATTERN "CVS" EXCLUDE
REGEX ".svn" EXCLUDE)
+ Core
+ Filesystem
+ Graph
Users can choose to install any combination of those by
checking/unchecking the boxes. However, we really don't want the
installer to say just "Core", we want it to say "Core Libraries". In
addition, the "Core Libraries" is a required feature, and must always
set(CPACK_COMPONENT_BOOST_CORE_REQUIRED ON)
set(CPACK_COMPONENT_BOOST_CORE_DISPLAY_NAME "Core libraries")
Now the generated installer shows the Core component as "Core
libraries", which is checked but grayed out (and not modifiable).
There are lots of cool features that *could* be added from here, with
- Placing components into subgroups (e.g., we could have "headers",
"runtime libraries", and "development libraries" under each component)
- Providing different installation types (runtime, development,
custom) that pre-select sets of components
- Representing dependencies among components, so that selecting a
component selects all of its dependencies (and unselecting a component
unselects all of the components that depend on it)
- Provide add/remove support on a per-component basis.
Comments? Ideas? Rotten tomatoes?
- Doug
_______________________________________________
CMake mailing list
http://www.cmake.org/mailman/listinfo/cmake
Doug Gregor
2008-04-18 01:33:37 UTC
Permalink
Post by David Cole
Wow. Very ambitious. I like it...
Your patch is not all that ugly... :-) But it does refer to some things that
are not actually in the patch.
D'oh!
Post by David Cole
How about adding a feature request to the bug tracker for this and attaching
a zip file (or .tar.gz) with the patch and all the new files that it refers
to.
If you could also add a test project with 2 or 3 components in it that
demonstrates how to use the new variables you've invented, I could see it
becoming part of a future CMake release.....
Okay, the bug report is here:

http://public.kitware.com/Bug/view.php?id=6847

The archive attached to it contains the patch (*with* the additional
header) and an example with a few components. I also went ahead and
implemented the "component groups" feature.

- Doug
Doug Gregor
2008-04-18 15:06:13 UTC
Permalink
Post by Doug Gregor
http://public.kitware.com/Bug/view.php?id=6847
The archive attached to it contains the patch (*with* the additional
header) and an example with a few components. I also went ahead and
implemented the "component groups" feature.
... and now there's a "v2" patch on there, which contains the first
patch plus add/remove functionality. If you run the installer again
(after already installing the app, or parts of it), the components
selected will be exactly those components you installed the first time
around. You can select/deselect components and your installation will
be updated to reflect your choices.

- Doug
Doug Gregor
2008-04-19 18:32:46 UTC
Permalink
Post by Doug Gregor
Post by Doug Gregor
http://public.kitware.com/Bug/view.php?id=6847
The archive attached to it contains the patch (*with* the additional
header) and an example with a few components. I also went ahead and
implemented the "component groups" feature.
... and now there's a "v2" patch on there, which contains the first
patch plus add/remove functionality. If you run the installer again
(after already installing the app, or parts of it), the components
selected will be exactly those components you installed the first time
around. You can select/deselect components and your installation will
be updated to reflect your choices.
I've almost implemented every part of this feature that I like... the
new "v3" patch in the bug tracker adds two new features:

- Component descriptions: if provided, these will show up when the
user hovers the mouse pointer over the component in the installer.
Just set the _DESCRIPTION variable for each component to enable this
feature.

- Component dependencies: if provided, the installer will make sure
that all of the inter-component dependencies are satisfied. For
example, if you select a component "D" that depends on "B" and "C"
(directly), and where "B" also depends on "A", then the installer will
go ahead and select "A", and "B", and "C" if they weren't already.
Then, if you then deselect "B", the installer will also deselect "D"
(since "D" can no longer be used). This was a pain to implement :)

The patch is getting large, but it is backward-compatible and degrades
gracefully when some information is missing. If you don't provide a
list of components, the "Components" page won't even show up. If you
don't provide any component descriptions, the "description" box will
be removed from the resulting installer, etc. Of course, it's okay to
not specify dependencies when you don't have any.

Only one feature to go before I call this patch done: I'd like to
support installation types, which preselects sets of components. NSIS
can do this; we just need CPack syntax and support in the NSIS
generator.

Comments welcome :)

- Doug
Doug Gregor
2008-04-19 23:00:32 UTC
Permalink
Post by Doug Gregor
Post by Doug Gregor
Post by Doug Gregor
http://public.kitware.com/Bug/view.php?id=6847
The archive attached to it contains the patch (*with* the additional
header) and an example with a few components. I also went ahead and
implemented the "component groups" feature.
... and now there's a "v2" patch on there, which contains the first
patch plus add/remove functionality. If you run the installer again
(after already installing the app, or parts of it), the components
selected will be exactly those components you installed the first time
around. You can select/deselect components and your installation will
be updated to reflect your choices.
I've almost implemented every part of this feature that I like... the
Only one feature to go before I call this patch done: I'd like to
support installation types, which preselects sets of components. NSIS
can do this; we just need CPack syntax and support in the NSIS
generator.
*Now* I call this patch done, modulo any problems or necessary
changes. The bug tracker now has the "v4" patch, which adds support
for installation types. Each component states which installation types
it is a part of ("Full" install, "Developer" install, etc.). In NSIS,
the installation types show up as a combo box above the component
selection box.

- Doug

Alexander Neundorf
2008-04-17 20:21:08 UTC
Permalink
Post by Doug Gregor
Hello all,
...
Post by Doug Gregor
Comments? Ideas? Rotten tomatoes?
- Doug
Could this in some way be related with this one ?
http://www.cmake.org/pipermail/cmake/2008-April/021142.html
I think the component support could use some enhancements in cpack :-)

Alex
Doug Gregor
2008-04-17 20:24:47 UTC
Permalink
On Thu, Apr 17, 2008 at 4:21 PM, Alexander Neundorf
Post by Alexander Neundorf
Post by Doug Gregor
Hello all,
...
Post by Doug Gregor
Comments? Ideas? Rotten tomatoes?
- Doug
Could this in some way be related with this one ?
http://www.cmake.org/pipermail/cmake/2008-April/021142.html
I think the component support could use some enhancements in cpack :-)
I think the big difference here is that the other poster was creating
a single installer with components determined by CMake when CMake is
generating the build files. With my approach, the user determines at
binary installation time which components to install.

If you use my scheme and mark every component as "required", the two
approaches would produce roughly the same installer.

- Doug
Loading...