Making DEB packages
Context
- The control file is the most important file in a DEB package; it encodes information about the package and the program it installs.
- A DEB package has a directory structure that shadows the file system. In reality, the installation procedure is better understood as a copy procedure. In this way, when a package is installed the files contained within the DEB archive are copied to the same location on the host computer (e.g. /usr/bin/an_important_file in the DEB archive is copied to /usr/bin/an_important_file on the host computer)
- Organize files like so
/project-name
|-- file1.sh
|-- file2.sh
|-- debian
|-- control
|-- prerm
|-- preinst
/project-name
|-- file1.sh
|-- file2.sh
|-- debian
|-- control
|-- prerm
|-- preinst
Methods to Create a DEB Package
cpack
- Creates a deb file given the contents specified in the CMakeLists.txt
dpkg-deb
- Management tool for DEB archives
-b <name_of_deb_file>
: Packages the specified folder into a DEB archive-c <name_of_deb_file>.deb
: Shows the files contained within the DEB package
dpkg
- Debian package manager
-l
: List installed packages-c/--contents
: Shows the contained files within the .DEB archive.--status <name_of_deb_package>
: Shows details of a package installed on the system--info <name_of_deb_package>.deb
: Shows details of .DEB archive (prior to installation)
The below code is one way to create a deb file from within CMake
include(InstallRequiredSystemLibraries)
set(CPACK_GENERATOR "DEB")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Description")
set(CPACK_PACKAGE_VENDOR "Your Vendor Name")
set(CPACK_PACKAGE_HOMEPAGE_URL "Homepage URL")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Your Name")
set(CPACK_PACKAGE_CONTACT "[email protected]")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CMake ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")
if( DEVELOP )
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME}-dev)
else()
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
endif()
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
if( DEVELOP )
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libtest-dev, libattempt-dev")
else()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libtest, libattempt")
endif()
execute_process(
COMMAND dpkg --print-architecture
RESULT_VARIABLE RESULT_VAR
OUTPUT_VARIABLE SYS_ARCH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_ VERSION_PATCH}-${SYS_ARCH})
include(CPack)
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES ENABLE_EXPORTS 1)
include(InstallRequiredSystemLibraries)
set(CPACK_GENERATOR "DEB")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Description")
set(CPACK_PACKAGE_VENDOR "Your Vendor Name")
set(CPACK_PACKAGE_HOMEPAGE_URL "Homepage URL")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Your Name")
set(CPACK_PACKAGE_CONTACT "[email protected]")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CMake ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")
if( DEVELOP )
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME}-dev)
else()
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
endif()
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
if( DEVELOP )
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libtest-dev, libattempt-dev")
else()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libtest, libattempt")
endif()
execute_process(
COMMAND dpkg --print-architecture
RESULT_VARIABLE RESULT_VAR
OUTPUT_VARIABLE SYS_ARCH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_ VERSION_PATCH}-${SYS_ARCH})
include(CPack)
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES ENABLE_EXPORTS 1)
The sources.list file and sources.list.d directory
The /etc/apt/sources.list file is the file that outlines to repositoires that apt searches for updates and packages.
By placing other list files in the /etc/apt/sources.list.d/ directory then chagnes to the available repos on your system can be made without touching the central /etc /apt/sources.list file. If you're on Ubuntu 22 and need your packages seached in the Ubuntu 20 repo, change the places where is says jammy to bionic.
ADDITIONAL RESOURCES
- https://schneide.blog/2017/12/29/advanced-deb-packaging-with-cmake/
- https://www.debian.org/doc/manuals/debian-faq/pkg-basics.en.html
- https://ivanitlearning.wordpress.com/2019/10/27/writing-your-own-deb-package/
- https://www.internalpointers.com/post/build-binary-deb-package-practical-guide
- https://askubuntu.com/questions/18192/how-to-fake-a-package-version-installed/656153#656153
- https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
- https://wiki.debian.org/Packaging