I have a single project with several subdirectories. Each subdirectory must generate a deb package. One of these packages must contain a post-installation script.
I just can't manage to find a way to set the post-installation script for a single component. I've tried quite a lot of variables combinations, but I'm obviously missing something.
Following is a MWE.
The project is structured as follows:
tst_deb_components/
├── build.sh
├── c1
│ ├── CMakeLists.txt
│ ├── main.c
│ └── postinst
├── c2
│ ├── CMakeLists.txt
│ └── main.c
└── CMakeLists.txt
Note that both main.c
are simply "hello world". could have been just files.
build.sh
#!/bin/bash
DIR_BUILD="_build"
set -e
if [[ -d "${DIR_BUILD}" ]]
then
rm -rvf ${DIR_BUILD}
fi
if [[ -d "_packages" ]]
then
rm -rvf _packages
fi
mkdir ${DIR_BUILD}
pushd ${DIR_BUILD}
cmake ..
cmake --build .
cpack
popd
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(
tst_deb_components
VERSION 0.1.2
)
set(COMPANY_NAME "MyCompany")
set(
CPACK_PACKAGE_NAME
"${COMPANY_NAME}-${PROJECT_NAME}"
CACHE STRING "The resulting package name"
)
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_PACKAGE_CONTACT "contact@example.com")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "NOOOO OOOOOOOOONNNNNEEEEEE")
set(
CPACK_PACKAGE_DESCRIPTION_SUMMARY
"Dummy package to test postinst."
CACHE STRING "Package description for the package metadata"
)
# Enable generating DEB packages
set(CPACK_GENERATOR "DEB")
set(CPACK_PACKAGE_VENDOR "NoVendor")
set(CPACK_VERBATIM_VARIABLES YES)
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
SET(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_SOURCE_DIR}/_packages")
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_COMPONENTS_GROUPING ONE_PER_GROUP)
# without this you won't be able to pack only specified component
set(CPACK_DEB_COMPONENT_INSTALL YES)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS YES)
set(
CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
)
add_subdirectory( c1/ )
add_subdirectory( c2/ )
include(CPack)
c1/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
#project(
# tst_deb_components
# VERSION 0.1.2
#)
set(
COMPONENT_NAME
"c1"
)
add_executable(${COMPONENT_NAME} main.c)
install(TARGETS ${COMPONENT_NAME}
COMPONENT
${COMPONENT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/postinst" PARENT_SCOPE)
set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE PARENT_SCOPE)
c1/postinst
#!/bin/bash
echo "########################################"
echo "# Hello from 'postinst' !"
echo "########################################"
c2/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
set(
COMPONENT_NAME
"c2"
)
add_executable(${COMPONENT_NAME} main.c)
install(TARGETS ${COMPONENT_NAME}
COMPONENT
${COMPONENT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
I'll only list tests that seems to be relevant.
To get a description of what's inside the package, I'm using dpkg-deb --info ./<package>
.
As-is, when I build using build.sh
, I get two packages with the postinst script in both, where I'd expect it to only be in the package for c1
.
If I remove the PARENT_SCOPE
directive from the set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA [...])
command, then the postinst
script is gone from both packages.
Any help greatly appreciated! After struggleing for two days, I've started to loose my mind.
Answering my own question thanks to a friend:
What I was missing :
CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
needed to be declared as CPACK_DEBIAN_<component name>_PACKAGE_CONTROL_EXTRA
CMakeLists.txt
and the component one (CMakeListsthat add subdirectories), hence I had to use CACHE
rather than PARENT_SCOPE
. I added FORCE
to be sure cached variables aren't modified by users.If someone needs it, my final c1/CMakeLists.txt
file for the MWE looks like this:
cmake_minimum_required(VERSION 3.5)
set(
COMPONENT_NAME
"c1"
)
string(
TOUPPER
${COMPONENT_NAME}
COMPONENT_NAME_UPPERCASE
)
add_executable(${COMPONENT_NAME} main.c)
install(TARGETS ${COMPONENT_NAME}
COMPONENT
${COMPONENT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
set(
CPACK_DEBIAN_${COMPONENT_NAME_UPPERCASE}_PACKAGE_CONTROL_EXTRA
"${CMAKE_CURRENT_SOURCE_DIR}/postinst"
CACHE
STRING
"Component ${COMPONENT_NAME} - CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"
FORCE
)
set(
CPACK_DEBIAN_${COMPONENT_NAME_UPPERCASE}_PACKAGE_CONTROL_STRICT_PERMISSION
TRUE
CACHE
STRING
"Component ${COMPONENT_NAME} - CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"
FORCE
)