CPack/Archive: Add support for setting UID/GID in archive

Add `CPACK_ARCHIVE_UID` and `CPACK_ARCHIVE_GID` options.

Add a policy to change the default to 0/0 to enable ownership
by root if unpacking as root.

Fixes: #12901
This commit is contained in:
Clinton Stimpson
2025-11-07 09:01:15 -07:00
committed by Brad King
parent 1a8390f768
commit 5a18728cec
17 changed files with 124 additions and 1 deletions

View File

@@ -100,6 +100,24 @@ Variables specific to CPack Archive generator
If enabled (``ON``) multiple packages are generated. By default a single package
containing files of all components is generated.
.. variable:: CPACK_ARCHIVE_UID
.. versionadded: 4.3
Set the UID of entries contained in the archive.
Specify ``-1`` to use the UID of the current user.
:Default: ``0`` (see policy :policy:`CMP0206`)
.. variable:: CPACK_ARCHIVE_GID
.. versionadded: 4.3
Set the GID of entries contained in the archive.
Specify ``-1`` to use the GID of the current user.
:Default: ``0`` (see policy :policy:`CMP0206`)
Variables used by CPack Archive generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -98,6 +98,7 @@ Policies Introduced by CMake 4.3
.. toctree::
:maxdepth: 1
CMP0206: The CPack Archive Generator defaults to UID 0 and GID 0. </policy/CMP0206>
CMP0205: file(CREATE_LINK) with COPY_ON_ERROR copies directory content. </policy/CMP0205>
Policies Introduced by CMake 4.2

30
Help/policy/CMP0206.rst Normal file
View File

@@ -0,0 +1,30 @@
CMP0206
-------
.. versionadded:: 4.3
The :cpack_gen:`CPack Archive Generator` defaults to UID 0 and GID 0.
In CMake 4.2 and below, the :cpack_gen:`CPack Archive Generator` always used
the current user's UID/GID in archive entries. CMake 4.3 added the
:variable:`CPACK_ARCHIVE_UID` and :variable:`CPACK_ARCHIVE_GID` variables
to control them. If either is set, the default for the other is ``0``.
If neither is set, CMake 4.3 and above prefer to default both UID and GID
to ``0`` so that unpacking by ``root`` produces paths owned by ``root``.
This policy provides compatibility with projects that have not been updated
to expect the new behavior.
The ``OLD`` behavior for this policy is to produce archive entries with
the current user's UID/GID by default.
The ``NEW`` behavior for this policy is to produce archive entries with
the UID/GID set to 0/0 by default.
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.3
.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
.. include:: include/STANDARD_ADVICE.rst
See documentation of the
:variable:`CMAKE_POLICY_WARNING_CMP0206 <CMAKE_POLICY_WARNING_CMP<NNNN>>`
variable to control the warning.
.. include:: include/DEPRECATED.rst

View File

@@ -0,0 +1,7 @@
cpack-archive-ownership
-----------------------
* The :cpack_gen:`CPack Archive Generator` generator gained new
:variable:`CPACK_ARCHIVE_UID` and :variable:`CPACK_ARCHIVE_GID`
options to specify the UID and GID of archive entries.
The default now UID 0 and GID 0. See policy :policy:`CMP0206`.

View File

@@ -40,6 +40,8 @@ only for the policies that do not warn by default:
policy :policy:`CMP0133`.
* ``CMAKE_POLICY_WARNING_CMP0172`` controls the warning for
policy :policy:`CMP0172`.
* ``CMAKE_POLICY_WARNING_CMP0206`` controls the warning for
policy :policy:`CMP0206`.
This variable should not be set by a project in CMake code. Project
developers running CMake may set this variable in their cache to

View File

@@ -936,6 +936,24 @@ elseif(APPLE AND CPACK_BINARY_PRODUCTBUILD AND
endif()
unset(_CPack_CMP0161)
# Archive specific variables
if(NOT DEFINED CPACK_ARCHIVE_UID AND NOT DEFINED CPACK_ARCHIVE_GID)
cmake_policy(GET CMP0206 _CPack_CMP0206)
if(NOT "x${_CPack_CMP0206}x" STREQUAL "xNEWx")
if(NOT "x${_CPack_CMP0206}x" STREQUAL "xOLDx" AND CMAKE_POLICY_WARNING_CMP0206)
cmake_policy(GET_WARNING CMP0206 _CMP0206_warning)
message(AUTHOR_WARNING
"${_CMP0206_warning}\n"
"For compatibility, CMake will set archive UID/GID to -1/-1."
)
unset(_CMP0206_warning)
endif()
_cpack_set_default(CPACK_ARCHIVE_UID "-1")
_cpack_set_default(CPACK_ARCHIVE_GID "-1")
endif()
unset(_CPack_CMP0206)
endif()
# set sysroot so SDK tools can be used
if(CMAKE_OSX_SYSROOT)
_cpack_set_default(CPACK_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")

View File

@@ -318,6 +318,9 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
} \
cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat, 0, \
this->GetThreadCount()); \
if (this->UID >= 0 && this->GID >= 0) { \
archive.SetUIDAndGID(this->UID, this->GID); \
} \
do { \
if (!archive.Open()) { \
cmCPackLogger(cmCPackLog::LOG_ERROR, \
@@ -436,6 +439,19 @@ int cmCPackArchiveGenerator::PackageFiles()
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Toplevel: " << this->toplevel << std::endl);
if (cmValue UIDoption = this->GetOptionIfSet("CPACK_ARCHIVE_UID")) {
long u;
if (cmStrToLong(*UIDoption, &u)) {
this->UID = static_cast<int>(u);
}
}
if (cmValue GIDoption = this->GetOptionIfSet("CPACK_ARCHIVE_GID")) {
long g;
if (cmStrToLong(*GIDoption, &g)) {
this->GID = static_cast<int>(g);
}
}
if (this->WantsComponentInstallation()) {
// CASE 1 : COMPONENT ALL-IN-ONE package
// If ALL COMPONENTS in ONE package has been requested

View File

@@ -97,4 +97,6 @@ private:
cmArchiveWrite::Compress Compress;
std::string ArchiveFormat;
std::string OutputExtension;
int UID = 0;
int GID = 0;
};

View File

@@ -615,7 +615,10 @@ class cmMakefile;
2, 0, WARN) \
SELECT(POLICY, CMP0205, \
"file(CREATE_LINK) with COPY_ON_ERROR copies directory content.", 4, \
3, 0, WARN)
3, 0, WARN) \
SELECT(POLICY, CMP0206, \
"The CPack Archive Generator defaults to UID 0 and GID 0.", 4, 3, 0, \
WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \

View File

@@ -0,0 +1,3 @@
include(${RunCMake_SOURCE_DIR}/check.cmake)
test_variable(CPACK_ARCHIVE_UID "")
test_variable(CPACK_ARCHIVE_GID "")

View File

@@ -0,0 +1 @@
cmake_policy(SET CMP0206 NEW)

View File

@@ -0,0 +1,3 @@
include(${RunCMake_SOURCE_DIR}/check.cmake)
test_variable(CPACK_ARCHIVE_UID "-1")
test_variable(CPACK_ARCHIVE_GID "-1")

View File

@@ -0,0 +1,2 @@
set(CMAKE_POLICY_WARNING_CMP0206 1)
cmake_policy(SET CMP0206 OLD)

View File

@@ -0,0 +1,3 @@
include(${RunCMake_SOURCE_DIR}/check.cmake)
test_variable(CPACK_ARCHIVE_UID "-1")
test_variable(CPACK_ARCHIVE_GID "-1")

View File

@@ -0,0 +1,10 @@
^CMake Warning \(dev\) at [^
]*/Modules/CPack\.cmake:[0-9]+ \(message\):
Policy CMP0206 is not set: The CPack Archive Generator defaults to UID 0
and GID 0\. Run "cmake --help-policy CMP0206" for policy details\. Use the
cmake_policy command to set the policy and suppress this warning\.
For compatibility, CMake will set archive UID/GID to -1/-1\.
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)
This warning is for project developers\. Use -Wno-dev to suppress it\.$

View File

@@ -0,0 +1 @@
set(CMAKE_POLICY_WARNING_CMP0206 1)

View File

@@ -8,6 +8,9 @@ run_cmake(CMP0161-WARN)
run_cmake(CMP0172-NEW)
run_cmake(CMP0172-OLD)
run_cmake(CMP0172-WARN)
run_cmake(CMP0206-NEW)
run_cmake(CMP0206-OLD)
run_cmake(CMP0206-WARN)
run_cmake(Simple)
run_cmake(Default)
run_cmake(Special)