From 302a645d73f8dfcc73788d925e54102efe7ea328 Mon Sep 17 00:00:00 2001 From: Alex Turbov Date: Thu, 5 Mar 2026 23:14:10 +0400 Subject: [PATCH] CPack/DEB: use `triggers` instead of legacy postXXX scripts for `ldconfig` --- Modules/Internal/CPack/CPackDeb.cmake | 39 +++++++++++++++++- Source/CPack/cmCPackDebGenerator.cxx | 38 +++++++++++++++--- .../VerifyResult.cmake | 40 ++++++++++++++++--- 3 files changed, 104 insertions(+), 13 deletions(-) diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake index a5e6521e60..1ebcaaa2d3 100644 --- a/Modules/Internal/CPack/CPackDeb.cmake +++ b/Modules/Internal/CPack/CPackDeb.cmake @@ -870,8 +870,37 @@ function(cpack_deb_prepare_package_vars) endforeach() if(_PACKAGE_HAS_SHARED_LIBS) - set(CPACK_DEBIAN_GENERATE_POSTINST 1) - set(CPACK_DEBIAN_GENERATE_POSTRM 1) + # Expecting a modern distro to generate `debian/triggers` instead + # of legacy `ldconfig` calls from postinst/postrm + set(_dpkg_is_old FALSE) + if(DPKG_EXECUTABLE) + execute_process( + COMMAND "${DPKG_EXECUTABLE}" --version + OUTPUT_VARIABLE DPKG_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(_dpkg_version_re "Debian 'dpkg' package management program version ([0-9]+\.[0-9]+\.[0-9]+).*") + if(DPKG_VERSION MATCHES "${_dpkg_version_re}") + set(DPKG_VERSION "${CMAKE_MATCH_1}") + if(DPKG_VERSION VERSION_LESS 1.18.3) + set(_dpkg_is_old TRUE) + endif() + else() + set(_dpkg_is_old TRUE) + endif() + else() + set(_dpkg_is_old TRUE) + endif() + if(_dpkg_is_old) + set(CPACK_DEBIAN_GENERATE_LDCONFIG_TRIGGERS 0) + set(CPACK_DEBIAN_GENERATE_POSTINST 1) + set(CPACK_DEBIAN_GENERATE_POSTRM 1) + message(STATUS "CPackDeb: Providing legacy postinst/postrm.") + else() + set(CPACK_DEBIAN_GENERATE_LDCONFIG_TRIGGERS 1) + set(CPACK_DEBIAN_GENERATE_POSTINST 0) + set(CPACK_DEBIAN_GENERATE_POSTRM 0) + endif() foreach(control_file IN LISTS CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA) cmake_path(GET control_file FILENAME name) if(name STREQUAL "postinst") @@ -880,8 +909,12 @@ function(cpack_deb_prepare_package_vars) if(name STREQUAL "postrm") set(CPACK_DEBIAN_GENERATE_POSTRM 0) endif() + if(name STREQUAL "triggers") + set(CPACK_DEBIAN_GENERATE_LDCONFIG_TRIGGERS 0) + endif() endforeach() else() + set(CPACK_DEBIAN_GENERATE_LDCONFIG_TRIGGERS 0) set(CPACK_DEBIAN_GENERATE_POSTINST 0) set(CPACK_DEBIAN_GENERATE_POSTRM 0) endif() @@ -991,6 +1024,8 @@ function(cpack_deb_prepare_package_vars) "${CPACK_DEBIAN_PACKAGE_SOURCE}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_GENERATE_POSTINST "${CPACK_DEBIAN_GENERATE_POSTINST}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_GENERATE_POSTRM "${CPACK_DEBIAN_GENERATE_POSTRM}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_GENERATE_LDCONFIG_TRIGGERS + "${CPACK_DEBIAN_GENERATE_LDCONFIG_TRIGGERS}" PARENT_SCOPE) set(GEN_WDIR "${WDIR}" PARENT_SCOPE) set(GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE "${CPACK_DEBIAN_DEBUGINFO_PACKAGE}" PARENT_SCOPE) diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 523a293cb6..0be2ec49b3 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -37,7 +37,8 @@ public: std::map controlValues, bool genShLibs, std::string shLibsFilename, bool genPostInst, std::string postInst, bool genPostRm, std::string postRm, - cmValue controlExtra, bool permissionStrctPolicy, + bool genTriggers, std::string triggers, cmValue controlExtra, + bool permissionStrctPolicy, std::vector packageFiles); bool generate() const; @@ -65,6 +66,8 @@ private: std::string const PostInst; bool const GenPostRm; std::string const PostRm; + bool const GenTriggers; + std::string const Triggers; cmValue ControlExtra; bool const PermissionStrictPolicy; std::vector const PackageFiles; @@ -78,8 +81,8 @@ DebGenerator::DebGenerator( cmValue debCompressionType, cmValue debCompressionLevel, cmValue numThreads, cmValue debianArchiveType, std::map controlValues, bool genShLibs, std::string shLibsFilename, bool genPostInst, - std::string postInst, bool genPostRm, std::string postRm, - cmValue controlExtra, bool permissionStrictPolicy, + std::string postInst, bool genPostRm, std::string postRm, bool genTriggers, + std::string triggers, cmValue controlExtra, bool permissionStrictPolicy, std::vector packageFiles) : Logger(logger) , OutputName(std::move(outputName)) @@ -94,6 +97,8 @@ DebGenerator::DebGenerator( , PostInst(std::move(postInst)) , GenPostRm(genPostRm) , PostRm(std::move(postRm)) + , GenTriggers(genTriggers) + , Triggers(std::move(triggers)) , ControlExtra(controlExtra) , PermissionStrictPolicy(permissionStrictPolicy) , PackageFiles(std::move(packageFiles)) @@ -429,14 +434,28 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const control_tar.SetPermissions(permission644); } + if (this->GenTriggers) { + if (!control_tar.Add(this->Triggers, this->WorkDir.length(), ".")) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error adding file to tar:\n" + "#top level directory: " + << this->WorkDir + << "\n" + "#file: \"triggers\"\n" + "#error:" + << control_tar.GetError() << std::endl); + return false; + } + } + // for the other files, we use // -either the original permission on the files // -either a permission strictly defined by the Debian policies if (this->ControlExtra) { // permissions are now controlled by the original file permissions - static char const* strictFiles[] = { "config", "postinst", "postrm", - "preinst", "prerm" }; + static char const* strictFiles[] = { "config", "postinst", "postrm", + "preinst", "prerm", "triggers" }; std::set setStrictFiles( strictFiles, strictFiles + sizeof(strictFiles) / sizeof(strictFiles[0])); @@ -837,6 +856,7 @@ bool cmCPackDebGenerator::createDeb() std::string const postinst = strGenWDIR + "/postinst"; std::string const postrm = strGenWDIR + "/postrm"; + std::string const triggers = strGenWDIR + "/triggers"; if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) { cmGeneratedFileStream out; out.Open(postinst, false, true); @@ -855,6 +875,11 @@ bool cmCPackDebGenerator::createDeb() "\tldconfig\n" "fi\n"; } + if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_LDCONFIG_TRIGGERS")) { + cmGeneratedFileStream out; + out.Open(triggers, false, true); + out << "activate-noawait ldconfig\n"; + } DebGenerator gen( this->Logger, this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"), strGenWDIR, @@ -866,6 +891,7 @@ bool cmCPackDebGenerator::createDeb() this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"), controlValues, gen_shibs, shlibsfilename, this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST"), postinst, this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM"), postrm, + this->IsOn("GEN_CPACK_DEBIAN_GENERATE_LDCONFIG_TRIGGERS"), triggers, this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"), this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"), this->packageFiles); @@ -920,7 +946,7 @@ bool cmCPackDebGenerator::createDbgsymDDeb() this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_LEVEL"), this->GetOption("CPACK_THREADS"), this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"), controlValues, false, "", - false, "", false, "", nullptr, + false, "", false, "", false, "", nullptr, this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"), this->packageFiles); diff --git a/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/VerifyResult.cmake index 422cfbe42c..ff9ef1d769 100644 --- a/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/VerifyResult.cmake +++ b/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/VerifyResult.cmake @@ -1,8 +1,38 @@ +find_program(DPKG_EXECUTABLE dpkg) +set(_dpkg_is_old FALSE) +if(DPKG_EXECUTABLE) + execute_process( + COMMAND "${DPKG_EXECUTABLE}" --version + OUTPUT_VARIABLE DPKG_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(_dpkg_version_re "Debian 'dpkg' package management program version ([0-9]+\.[0-9]+\.[0-9]+).*") + if(DPKG_VERSION MATCHES "${_dpkg_version_re}") + set(DPKG_VERSION "${CMAKE_MATCH_1}") + if(DPKG_VERSION VERSION_LESS 1.18.3) + set(_dpkg_is_old TRUE) + endif() + else() + set(_dpkg_is_old TRUE) + endif() +else() + set(_dpkg_is_old TRUE) +endif() + +set(expected_files shlibs) set(shlibs_shlibs "^libtest_lib 0\\.8 generate_shlibs_ldconfig \\(>\\= 0\\.1\\.1\\)\n$") # NOTE: optional dot at the end of permissions regex is for SELinux enabled systems set(shlibs_shlibs_permissions_regex "-rw-r--r--\.? .*") -set(shlibs_postinst ".*ldconfig.*") -set(shlibs_postinst_permissions_regex "-rwxr-xr-x\.? .*") -set(shlibs_postrm ".*ldconfig.*") -set(shlibs_postrm_permissions_regex "-rwxr-xr-x\.? .*") -verifyDebControl("${FOUND_FILE_1}" "shlibs" "shlibs;postinst;postrm") +if(_dpkg_is_old) + list(APPEND expected_files postinst postrm) + set(shlibs_postinst ".*ldconfig.*") + set(shlibs_postinst_permissions_regex "-rwxr-xr-x\.? .*") + + set(shlibs_postrm ".*ldconfig.*") + set(shlibs_postrm_permissions_regex "-rwxr-xr-x\.? .*") +else() + list(APPEND expected_files triggers) + set(triggers_postrm ".*ldconfig.*") + set(triggers_postrm_permissions_regex "-rw-r--r--\.? .*") +endif() +verifyDebControl("${FOUND_FILE_1}" "shlibs" "${expected_files}")