[CMake] Multi-component packaging support

Timenkov Yuri ytimenkov at parallels.com
Tue Apr 15 13:08:36 EDT 2008


On Tuesday 25 March 2008 19:54:08 Alexander Neundorf wrote:
> On Tuesday 25 March 2008, Timenkov Yuri wrote:
> > Can anyone point me in right direction?
>
> Please file a feature request on the cmake bug tracker for cpack. We don't
> have too much feedback for cpack so this is very valuable.
I played with CPack a bit and felt its power :)

The solution which almost suited me is following: write custom CPack script 
which operates on CMake-generated build tree, and contains following:

set(MYPACKAGE_COMPONENTS
	component1
	component2
	)

set(CPACK_INSTALL_CMAKE_PROJECTS)
foreach(component ${MYPACKAGE_COMPONENTS})
	list(APPEND CPACK_INSTALL_CMAKE_PROJECTS ".;MyProject;${component};/")
endforeach(component)

And the rest from wiki example.
And to build package I run "cpack --config myconf.cmake"

This approach does everything I need: Allows create custom packages, every 
package may have intersecting components (I can handle it by using multiple 
configs) and package contents is described in single file (which I can use on 
all platforms for all generators).

The only drawback is that I have many components (at least 2 components for 
each library, and my project counts hundred of libraries), so "make 
preinstall" and "make install" are called too many times which results in 
significant performance degradation.

I suppose quick fix of this problem may be separating multiple components with 
commas in single quadruplet and calling install project in cycle. Or may be I 
don't understand something in design yet?

>
> Alex
>
> > On Friday 21 March 2008 13:08:02 Timenkov Yuri wrote:
> > > I have following requirement: I have big source tree (~100 projects -
> > > libraries or binaries), and want to package them in different ways. And
> > > encapsulate packaging knowledge in single place.
> > >
> > > That is I want that some libraries may enter into different packages.
> > > That is pakcageA contains libA and libB, packageA-devel contains
> > > libA-static and libB-static and libA-headers, packageB contains libB
> > > and libX, and so on.
> > >
> > > Obviously, I can't specify it in install command, because when I write
> > > CMakeLists.txt for some library, I don't know which package it will
> > > belong to.
> > >
> > > Other words, I want somewhere in top-level makefile to write something
> > > like add_install_package(packageA libA libB)
> > > add_install_package(packageA-devel libA-static libB-static
> > > libA-headers) add_install_package(packageB libB libX)
> > >
> > > and later, to install particular package, I should call something like
> > > make install_package_packageA
> > >
> > > Also, it will be very helpfull to have some kind of install manifest
> > > for whole package. It will simplify packaging on different platforms
> > > (wither with or without CPack). For example, you can tell rpmbuild to
> > > get file list form text file rather than specifying them in .spec. Same
> > > way I can wrap other packaging tools on windows.
> > >
> > > Now, I came to following solution: put every library into separate
> > > component with same name: install(TARGETS libA COMPONENT libA)
> > > Next, add custom target:
> > >         add_custom_target(install_packageA
> > >                 COMMAND ${CMAKE_COMMAND}
> > >                 -DINSTALL_PACKAGE_NAME:STRING="packageA"
> > >                 -DINSTALL_COMPONENTS:STRING="libA libB"
> > >                 -H${CMAKE_SOURCE_DIR}
> > >                 -B${CMAKE_BINARY_DIR}
> > >                 -P ${CMAKE_SOURCE_DIR}/build/InstallHelper.cmake
> > >                 COMMENT "Installing package packageA"
> > >                 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
> > >         )
> > > where InstallHelper.cmake is:
> > >
> > > # Convert space-separated string into list.
> > > separate_arguments(INSTALL_COMPONENTS)
> > >
> > > # Install components
> > > foreach(component ${INSTALL_COMPONENTS})
> > >         # Set component
> > >         set(CMAKE_INSTALL_COMPONENT ${component})
> > >
> > >         message(STATUS "Processing component
> > > ${CMAKE_INSTALL_COMPONENT}")
> > >
> > >         # Run install script with active component
> > >         include(${CMAKE_BINARY_DIR}/cmake_install.cmake)
> > > endforeach(component)
> > >
> > > set(_manifest_file
> > > ${CMAKE_BINARY_DIR}/install_manifest_${INSTALL_PACKAGE_NAME}.txt)
> > >
> > > # Truncate output manifest file.
> > > file(WRITE ${_manifest_file} "")
> > >
> > > # Append installed files to manifest.
> > > foreach(file ${CMAKE_INSTALL_MANIFEST_FILES})
> > >         file(APPEND ${_manifest_file} "${file}\n")
> > > endforeach(file)
> > >
> > > Is there more straight-forward way to do same things? Possibly, with
> > > CPack, but I don't completely understand one's architecture yet.
> > > _______________________________________________
> > > CMake mailing list
> > > CMake at cmake.org
> > > http://www.cmake.org/mailman/listinfo/cmake
> >
> > _______________________________________________
> > CMake mailing list
> > CMake at cmake.org
> > http://www.cmake.org/mailman/listinfo/cmake
>
> _______________________________________________
> CMake mailing list
> CMake at cmake.org
> http://www.cmake.org/mailman/listinfo/cmake




More information about the CMake mailing list