Package: debhelper
Version: 11.2.1
Severity: wishlist

CMake provides a mechanism for installing separate "components" into
separate installation directories - for example, headers, libraries, and
executables can all go into different installation prefixes. This is how
CPack generates separate .debs for these components in its .deb
generator. It would be nice if there was a way for Debhelper to take
advantage of this same mechanism so that binary packages can simply list
their respective CMake install components instead of listing files and
directories in debian/*.install.

I have implemented a rough sketch of this functionality as a Python
script, which you can find at
https://gitlab.kitware.com/debian/dh-cmake, but I would rather get this
into Debhelper proper if we can. I would write it myself, but I don't
know very much about Perl, and I'm not sure how I would write tests for
this new functionality.

Here is a detailed specification of how it should work:

Debian::Debhelper::Buildsystem::cmake should override the install
method. First it should call the parent method (to do the standard make
install/ninja install), and then look for files called
debian/<package-name>.cpack-components (or debian/cpack-components for
the "main" package.) Each line in this file should be the name of a
CPack component which should be installed into the binary package. For
each of these components, the cmake buildsystem should run the following
command:

$ cd <build-directory> && DESTDIR=<top-dir>/debian/<package-name> \
  cmake -DCOMPONENT=<component> -P cmake_install.cmake

cmake_install.cmake is a file generated by CMake itself in the build
directory. It is used internally for make install/ninja install, and by
CPack for creating packages, but it can also be used by external
packaging software, such as Debhelper.

With this functionality, there should be no need to create
debian/*.install files, as the cpack-components functionality takes care
of all the installation.

Here is an example CMakeLists.txt file which demonstrates the component
functionality:

CMakeLists.txt
--------------
cmake_minimum_required(VERSION 3.5)
project(mypkg C)

include(GNUInstallDirs)

add_library(mypkg SHARED mypkg.c)
set_property(TARGET mypkg PROPERTY PUBLIC_HEADER mypkg.h)
target_include_directories(mypkg
  PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
)

install(TARGETS mypkg
  LIBRARY
    # CMAKE_INSTALL_LIBDIR is declared by GNUInstallDirs
    DESTINATION "${CMAKE_INSTALL_LIBDIR}"
    COMPONENT Libraries
  PUBLIC_HEADER
    # Ditto for CMAKE_INSTALL_INCLUDEDIR
    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
    COMPONENT Development
)
------------------
end CMakeLists.txt

In the install() command, you can see that the target's LIBRARY is part
of the Libraries component, and its PUBLIC_HEADER is part of the
Development component. A CMake project can have as many install
components as you like, and they can have arbitrary names. For example,
a CMake project which produces multiple libraries could have components
called lib1-Libraries, lib1-Development, lib2-Libraries, and
lib2-Development. Components can also be grouped into component groups,
so lib1-Libraries and lib2-Libraries could be part of the Libraries
group.

Running DESTDIR=... cmake -DCOMPONENT=Development -P cmake_install.cmake
will only install the header files into DESTDIR. Likewise for
"Libraries" and the shared library. Then, the Debian packaging can have
the following files:

debian/libmypkg.cpack-components
--------------------------------
Libraries
------------------------------------
end debian/libmypkg.cpack-components

debian/libmypkg-dev.cpack-components
------------------------------------
Development
----------------------------------------
end debian/libmypkg-dev.cpack-components

And everything will be installed into the proper binary package, even
though there are no debian/*.install files, because cmake_install.cmake
took care of all the installation.

Thank you for considering implementing this feature. Should you choose
to implement it, I would be happy to answer any CMake-related questions
you have which would help you.

Kyle

-- System Information:
Debian Release: buster/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 4.15.0-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages debhelper depends on:
ii  autotools-dev            20180224.1
ii  dh-autoreconf            17
ii  dh-strip-nondeterminism  0.041-1
ii  dpkg                     1.19.0.5
ii  dpkg-dev                 1.19.0.5
ii  file                     1:5.32-2
ii  libdpkg-perl             1.19.0.5
ii  man-db                   2.8.3-2
ii  perl                     5.26.1-6
ii  po-debconf               1.0.20

debhelper recommends no packages.

Versions of packages debhelper suggests:
pn  dh-make  <none>
pn  dwz      <none>

-- no debconf information

Reply via email to