summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-11-09 13:28:23 (GMT)
committerKitware Robot <kwrobot@kitware.com>2017-11-09 13:28:28 (GMT)
commit05d8892e6113272c9b9ab73ceb9c8319e6690a25 (patch)
tree5ea42b3575d6b24118ffe6d25a3cbc24d3142be6
parent0682e77f3b65850d37d8d91533c62b30a348454b (diff)
parent7e896029cd6bc0a19b7e0ed6fa7b876e0f1764b3 (diff)
downloadCMake-05d8892e6113272c9b9ab73ceb9c8319e6690a25.zip
CMake-05d8892e6113272c9b9ab73ceb9c8319e6690a25.tar.gz
CMake-05d8892e6113272c9b9ab73ceb9c8319e6690a25.tar.bz2
Merge topic 'cmake-default-dir-install-permissions'
7e896029 CPack: enable setting default dir creation permissions a4c82916 CPack test: expand output checking fallback 670ad047 Move file/dir permissions code to common file. deeba85f CMake: enable setting default dir creation permissions Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1433
-rw-r--r--Help/manual/cmake-variables.7.rst2
-rw-r--r--Help/release/dev/cmake-default-dir-install-permissions.rst12
-rw-r--r--Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst29
-rw-r--r--Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst11
-rw-r--r--Modules/CPack.cmake6
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/CPack/cmCPackGenerator.cxx54
-rw-r--r--Source/CPack/cmCPackGenerator.h7
-rw-r--r--Source/cmFSPermissions.cxx34
-rw-r--r--Source/cmFSPermissions.h45
-rw-r--r--Source/cmFileCommand.cxx75
-rw-r--r--Source/cmLocalGenerator.cxx14
-rw-r--r--Tests/RunCMake/CPack/CPackTestHelpers.cmake2
-rw-r--r--Tests/RunCMake/CPack/README.txt1
-rw-r--r--Tests/RunCMake/CPack/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake6
-rw-r--r--Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/VerifyResult.cmake39
-rw-r--r--Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CMAKE_var-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CPACK_var-stderr.txt1
-rw-r--r--Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/test.cmake34
-rwxr-xr-xbootstrap1
21 files changed, 315 insertions, 62 deletions
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 0170da1..1927c37 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -159,6 +159,7 @@ Variables that Change Behavior
/variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
/variable/CMAKE_INCLUDE_PATH
/variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
+ /variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
/variable/CMAKE_INSTALL_MESSAGE
/variable/CMAKE_INSTALL_PREFIX
/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT
@@ -529,6 +530,7 @@ Variables for CPack
/variable/CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY
/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
/variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY
+ /variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
/variable/CPACK_INSTALL_SCRIPT
/variable/CPACK_PACKAGING_INSTALL_PREFIX
/variable/CPACK_SET_DESTDIR
diff --git a/Help/release/dev/cmake-default-dir-install-permissions.rst b/Help/release/dev/cmake-default-dir-install-permissions.rst
new file mode 100644
index 0000000..8325fda
--- /dev/null
+++ b/Help/release/dev/cmake-default-dir-install-permissions.rst
@@ -0,0 +1,12 @@
+cmake-default-dir-install-permissions
+-------------------------------------
+
+* The :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` variable was added
+ to enable setting of default permissions for directories created implicitly
+ during installation of files by :command:`install` and
+ :command:`file(INSTALL)`.
+
+* The :variable:`CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` variable was added
+ which serves the same purpose during packaging as the
+ :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` variable serves during
+ installation (e.g. ``make install``).
diff --git a/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst b/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
new file mode 100644
index 0000000..f994fbe
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
@@ -0,0 +1,29 @@
+CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
+-------------------------------------------
+
+Default permissions for directories created implicitly during installation
+of files by :command:`install` and :command:`file(INSTALL)`.
+
+If ``make install`` is invoked and directories are implicitly created they
+get permissions set by :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS`
+variable or platform specific default permissions if the variable is not set.
+
+Implicitly created directories are created if they are not explicitly installed
+by :command:`install` command but are needed to install a file on a certain
+path. Example of such locations are directories created due to the setting of
+:variable:`CMAKE_INSTALL_PREFIX`.
+
+Expected content of the :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS`
+variable is a list of permissions that can be used by :command:`install` command
+`PERMISSIONS` section.
+
+Example usage:
+
+::
+
+ set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
+ OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ )
diff --git a/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst b/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
new file mode 100644
index 0000000..83d5ce7
--- /dev/null
+++ b/Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst
@@ -0,0 +1,11 @@
+CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
+-------------------------------------------
+
+Default permissions for implicitly created directories during packaging.
+
+This variable serves the same purpose during packaging as the
+:variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS` variable
+serves during installation (e.g. ``make install``).
+
+If `include(CPack)` is used then by default this variable is set to the content
+of :variable:`CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS`.
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 3915943..ea7dc02 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -384,6 +384,12 @@ _cpack_set_default(CPACK_RESOURCE_FILE_WELCOME
_cpack_set_default(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}")
+# Set default directory creation permissions mode
+if(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS)
+ _cpack_set_default(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
+ "${CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS}")
+endif()
+
if(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL)
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
endif()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index a8d77b2..54e5063 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -216,6 +216,8 @@ set(SRCS
cmFileTimeComparison.cxx
cmFileTimeComparison.h
cmFortranParserImpl.cxx
+ cmFSPermissions.cxx
+ cmFSPermissions.h
cmGeneratedFileStream.cxx
cmGeneratorExpressionContext.cxx
cmGeneratorExpressionContext.h
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index ecb5adb..be75a9f 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
+#include "cmFSPermissions.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -201,6 +202,29 @@ int cmCPackGenerator::InstallProject()
cmSystemTools::PutEnv("DESTDIR=");
}
+ // prepare default created directory permissions
+ mode_t default_dir_mode_v = 0;
+ mode_t* default_dir_mode = nullptr;
+ const char* default_dir_install_permissions =
+ this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
+ if (default_dir_install_permissions && *default_dir_install_permissions) {
+ std::vector<std::string> items;
+ cmSystemTools::ExpandListArgument(default_dir_install_permissions, items);
+ for (const auto& arg : items) {
+ if (!cmFSPermissions::stringToModeT(arg, default_dir_mode_v)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Invalid permission value '"
+ << arg
+ << "'."
+ " CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS "
+ "value is invalid."
+ << std::endl);
+ return 0;
+ }
+ }
+
+ default_dir_mode = &default_dir_mode_v;
+ }
+
// If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them
// as listed
if (!this->InstallProjectViaInstallCommands(setDestDir,
@@ -218,15 +242,15 @@ int cmCPackGenerator::InstallProject()
// If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES
// then glob it and copy it to CPACK_TEMPORARY_DIRECTORY
// This is used in Source packaging
- if (!this->InstallProjectViaInstalledDirectories(setDestDir,
- tempInstallDirectory)) {
+ if (!this->InstallProjectViaInstalledDirectories(
+ setDestDir, tempInstallDirectory, default_dir_mode)) {
return 0;
}
// If the project is a CMAKE project then run pre-install
// and then read the cmake_install script to run it
- if (!this->InstallProjectViaInstallCMakeProjects(setDestDir,
- bareTempInstallDirectory)) {
+ if (!this->InstallProjectViaInstallCMakeProjects(
+ setDestDir, bareTempInstallDirectory, default_dir_mode)) {
return 0;
}
@@ -274,7 +298,8 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
}
int cmCPackGenerator::InstallProjectViaInstalledDirectories(
- bool setDestDir, const std::string& tempInstallDirectory)
+ bool setDestDir, const std::string& tempInstallDirectory,
+ const mode_t* default_dir_mode)
{
(void)setDestDir;
(void)tempInstallDirectory;
@@ -385,7 +410,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
// make sure directory exists for symlink
std::string destDir =
cmSystemTools::GetFilenamePath(symlinked.second);
- if (!destDir.empty() && !cmSystemTools::MakeDirectory(destDir)) {
+ if (!destDir.empty() &&
+ !cmSystemTools::MakeDirectory(destDir, default_dir_mode)) {
cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create dir: "
<< destDir << "\nTrying to create symlink: "
<< symlinked.second << "--> " << symlinked.first
@@ -464,7 +490,8 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
}
int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
- bool setDestDir, const std::string& baseTempInstallDirectory)
+ bool setDestDir, const std::string& baseTempInstallDirectory,
+ const mode_t* default_dir_mode)
{
const char* cmakeProjects = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
const char* cmakeGenerator = this->GetOption("CPACK_CMAKE_GENERATOR");
@@ -631,6 +658,13 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
}
}
+ const char* default_dir_inst_permissions =
+ this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
+ if (default_dir_inst_permissions && *default_dir_inst_permissions) {
+ mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS",
+ default_dir_inst_permissions);
+ }
+
if (!setDestDir) {
tempInstallDirectory += this->GetPackagingInstallPrefix();
}
@@ -690,7 +724,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
cmCPackLogger(cmCPackLog::LOG_DEBUG, "- Creating directory: '"
<< dir << "'" << std::endl);
- if (!cmsys::SystemTools::MakeDirectory(dir.c_str())) {
+ if (!cmsys::SystemTools::MakeDirectory(dir, default_dir_mode)) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"Problem creating temporary directory: " << dir << std::endl);
@@ -700,8 +734,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
mf.AddDefinition("CMAKE_INSTALL_PREFIX",
tempInstallDirectory.c_str());
- if (!cmsys::SystemTools::MakeDirectory(
- tempInstallDirectory.c_str())) {
+ if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory,
+ default_dir_mode)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Problem creating temporary directory: "
<< tempInstallDirectory << std::endl);
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
index 4e3a6e0..8100b66 100644
--- a/Source/CPack/cmCPackGenerator.h
+++ b/Source/CPack/cmCPackGenerator.h
@@ -12,6 +12,7 @@
#include "cmCPackComponentGroup.h"
#include "cmSystemTools.h"
+#include "cm_sys_stat.h"
class cmCPackLog;
class cmInstalledFile;
@@ -168,9 +169,11 @@ protected:
virtual int InstallProjectViaInstallScript(
bool setDestDir, const std::string& tempInstallDirectory);
virtual int InstallProjectViaInstalledDirectories(
- bool setDestDir, const std::string& tempInstallDirectory);
+ bool setDestDir, const std::string& tempInstallDirectory,
+ const mode_t* default_dir_mode);
virtual int InstallProjectViaInstallCMakeProjects(
- bool setDestDir, const std::string& tempInstallDirectory);
+ bool setDestDir, const std::string& tempInstallDirectory,
+ const mode_t* default_dir_mode);
/**
* The various level of support of
diff --git a/Source/cmFSPermissions.cxx b/Source/cmFSPermissions.cxx
new file mode 100644
index 0000000..4015a51
--- /dev/null
+++ b/Source/cmFSPermissions.cxx
@@ -0,0 +1,34 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFSPermissions.h"
+
+bool cmFSPermissions::stringToModeT(std::string const& arg,
+ mode_t& permissions)
+{
+ if (arg == "OWNER_READ") {
+ permissions |= mode_owner_read;
+ } else if (arg == "OWNER_WRITE") {
+ permissions |= mode_owner_write;
+ } else if (arg == "OWNER_EXECUTE") {
+ permissions |= mode_owner_execute;
+ } else if (arg == "GROUP_READ") {
+ permissions |= mode_group_read;
+ } else if (arg == "GROUP_WRITE") {
+ permissions |= mode_group_write;
+ } else if (arg == "GROUP_EXECUTE") {
+ permissions |= mode_group_execute;
+ } else if (arg == "WORLD_READ") {
+ permissions |= mode_world_read;
+ } else if (arg == "WORLD_WRITE") {
+ permissions |= mode_world_write;
+ } else if (arg == "WORLD_EXECUTE") {
+ permissions |= mode_world_execute;
+ } else if (arg == "SETUID") {
+ permissions |= mode_setuid;
+ } else if (arg == "SETGID") {
+ permissions |= mode_setgid;
+ } else {
+ return false;
+ }
+ return true;
+}
diff --git a/Source/cmFSPermissions.h b/Source/cmFSPermissions.h
new file mode 100644
index 0000000..7a6e708
--- /dev/null
+++ b/Source/cmFSPermissions.h
@@ -0,0 +1,45 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmFSPermissions_h
+#define cmFSPermissions_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cm_sys_stat.h"
+
+#include <string>
+
+namespace cmFSPermissions {
+
+// Table of permissions flags.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static const mode_t mode_owner_read = S_IREAD;
+static const mode_t mode_owner_write = S_IWRITE;
+static const mode_t mode_owner_execute = S_IEXEC;
+static const mode_t mode_group_read = 040;
+static const mode_t mode_group_write = 020;
+static const mode_t mode_group_execute = 010;
+static const mode_t mode_world_read = 04;
+static const mode_t mode_world_write = 02;
+static const mode_t mode_world_execute = 01;
+static const mode_t mode_setuid = 04000;
+static const mode_t mode_setgid = 02000;
+#else
+static const mode_t mode_owner_read = S_IRUSR;
+static const mode_t mode_owner_write = S_IWUSR;
+static const mode_t mode_owner_execute = S_IXUSR;
+static const mode_t mode_group_read = S_IRGRP;
+static const mode_t mode_group_write = S_IWGRP;
+static const mode_t mode_group_execute = S_IXGRP;
+static const mode_t mode_world_read = S_IROTH;
+static const mode_t mode_world_write = S_IWOTH;
+static const mode_t mode_world_execute = S_IXOTH;
+static const mode_t mode_setuid = S_ISUID;
+static const mode_t mode_setgid = S_ISGID;
+#endif
+
+bool stringToModeT(std::string const& arg, mode_t& permissions);
+
+} // ns
+
+#endif
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 191a666..88185bd 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -20,6 +20,7 @@
#include "cmAlgorithms.h"
#include "cmCommandArgumentsHelper.h"
#include "cmCryptoHash.h"
+#include "cmFSPermissions.h"
#include "cmFileLockPool.h"
#include "cmFileTimeComparison.h"
#include "cmGeneratorExpression.h"
@@ -50,32 +51,7 @@
class cmSystemToolsFileTime;
-// Table of permissions flags.
-#if defined(_WIN32) && !defined(__CYGWIN__)
-static mode_t mode_owner_read = S_IREAD;
-static mode_t mode_owner_write = S_IWRITE;
-static mode_t mode_owner_execute = S_IEXEC;
-static mode_t mode_group_read = 040;
-static mode_t mode_group_write = 020;
-static mode_t mode_group_execute = 010;
-static mode_t mode_world_read = 04;
-static mode_t mode_world_write = 02;
-static mode_t mode_world_execute = 01;
-static mode_t mode_setuid = 04000;
-static mode_t mode_setgid = 02000;
-#else
-static mode_t mode_owner_read = S_IRUSR;
-static mode_t mode_owner_write = S_IWUSR;
-static mode_t mode_owner_execute = S_IXUSR;
-static mode_t mode_group_read = S_IRGRP;
-static mode_t mode_group_write = S_IWGRP;
-static mode_t mode_group_execute = S_IXGRP;
-static mode_t mode_world_read = S_IROTH;
-static mode_t mode_world_write = S_IWOTH;
-static mode_t mode_world_execute = S_IXOTH;
-static mode_t mode_setuid = S_ISUID;
-static mode_t mode_setgid = S_ISGID;
-#endif
+using namespace cmFSPermissions;
#if defined(_WIN32)
// libcurl doesn't support file:// urls for unicode filenames on Windows.
@@ -1099,29 +1075,7 @@ protected:
// Translate an argument to a permissions bit.
bool CheckPermissions(std::string const& arg, mode_t& permissions)
{
- if (arg == "OWNER_READ") {
- permissions |= mode_owner_read;
- } else if (arg == "OWNER_WRITE") {
- permissions |= mode_owner_write;
- } else if (arg == "OWNER_EXECUTE") {
- permissions |= mode_owner_execute;
- } else if (arg == "GROUP_READ") {
- permissions |= mode_group_read;
- } else if (arg == "GROUP_WRITE") {
- permissions |= mode_group_write;
- } else if (arg == "GROUP_EXECUTE") {
- permissions |= mode_group_execute;
- } else if (arg == "WORLD_READ") {
- permissions |= mode_world_read;
- } else if (arg == "WORLD_WRITE") {
- permissions |= mode_world_write;
- } else if (arg == "WORLD_EXECUTE") {
- permissions |= mode_world_execute;
- } else if (arg == "SETUID") {
- permissions |= mode_setuid;
- } else if (arg == "SETGID") {
- permissions |= mode_setgid;
- } else {
+ if (!cmFSPermissions::stringToModeT(arg, permissions)) {
std::ostringstream e;
e << this->Name << " given invalid permission \"" << arg << "\".";
this->FileCommand->SetError(e.str());
@@ -2015,9 +1969,30 @@ bool cmFileInstaller::HandleInstallDestination()
this->DestDirLength = int(sdestdir.size());
}
+ // check if default dir creation permissions were set
+ mode_t default_dir_mode_v = 0;
+ mode_t* default_dir_mode = nullptr;
+ const char* default_dir_install_permissions = this->Makefile->GetDefinition(
+ "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
+ if (default_dir_install_permissions && *default_dir_install_permissions) {
+ std::vector<std::string> items;
+ cmSystemTools::ExpandListArgument(default_dir_install_permissions, items);
+ for (const auto& arg : items) {
+ if (!this->CheckPermissions(arg, default_dir_mode_v)) {
+ std::ostringstream e;
+ e << this->FileCommand->GetError()
+ << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable.";
+ this->FileCommand->SetError(e.str());
+ return false;
+ }
+ }
+
+ default_dir_mode = &default_dir_mode_v;
+ }
+
if (this->InstallType != cmInstallType_DIRECTORY) {
if (!cmSystemTools::FileExists(destination.c_str())) {
- if (!cmSystemTools::MakeDirectory(destination.c_str())) {
+ if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) {
std::string errstring = "cannot create directory: " + destination +
". Maybe need administrative privileges.";
this->FileCommand->SetError(errstring);
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 55952ef..c8d94c0 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -487,6 +487,20 @@ void cmLocalGenerator::GenerateInstallRules()
/* clang-format on */
}
+ // Write default directory permissions.
+ if (const char* defaultDirPermissions = this->Makefile->GetDefinition(
+ "CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS)\n"
+ " set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS \""
+ << defaultDirPermissions << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
// Ask each install generator to write its code.
std::vector<cmInstallGenerator*> const& installers =
this->Makefile->GetInstallGenerators();
diff --git a/Tests/RunCMake/CPack/CPackTestHelpers.cmake b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
index f883c69..5337b2c 100644
--- a/Tests/RunCMake/CPack/CPackTestHelpers.cmake
+++ b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
@@ -68,6 +68,8 @@ function(run_cpack_test_common_ TEST_NAME types build SUBTEST_SUFFIX source PACK
set(RunCMake-std${o}-file "tests/${TEST_NAME}/${TEST_TYPE}-${SUBTEST_SUFFIX}-std${o}.txt")
elseif(EXISTS ${RunCMake_SOURCE_DIR}/tests/${TEST_NAME}/${TEST_TYPE}-std${o}.txt)
set(RunCMake-std${o}-file "tests/${TEST_NAME}/${TEST_TYPE}-std${o}.txt")
+ elseif(SUBTEST_SUFFIX AND EXISTS ${RunCMake_SOURCE_DIR}/tests/${TEST_NAME}/${SUBTEST_SUFFIX}-std${o}.txt)
+ set(RunCMake-std${o}-file "tests/${TEST_NAME}/${SUBTEST_SUFFIX}-std${o}.txt")
elseif(EXISTS ${RunCMake_SOURCE_DIR}/${TEST_TYPE}/default_expected_std${o}.txt)
set(RunCMake-std${o}-file "${TEST_TYPE}/default_expected_std${o}.txt")
endif()
diff --git a/Tests/RunCMake/CPack/README.txt b/Tests/RunCMake/CPack/README.txt
index 5a95927..5877f97 100644
--- a/Tests/RunCMake/CPack/README.txt
+++ b/Tests/RunCMake/CPack/README.txt
@@ -167,6 +167,7 @@ NOTE: For subtests generator name can also be suffixed with subtest name and/or
- generator name + packaging type
- generator name + subtest name
- generator name
+ - subtest name
- default generator
File name format: '<generator_name>-<packaging_type>-<subtest_name>-std<type>.txt'
where <type> can either be 'out' or 'err'.
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index b00e373..4b7f146 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -7,6 +7,7 @@ include("${RunCMake_SOURCE_DIR}/CPackTestHelpers.cmake")
run_cpack_test(CUSTOM_BINARY_SPEC_FILE "RPM" false "MONOLITHIC;COMPONENT")
run_cpack_test(CUSTOM_NAMES "RPM;DEB;TGZ" true "COMPONENT")
run_cpack_test(DEBUGINFO "RPM" true "COMPONENT")
+run_cpack_test_subtests(DEFAULT_PERMISSIONS "CMAKE_var_set;CPACK_var_set;both_set;invalid_CMAKE_var;invalid_CPACK_var" "RPM;DEB" false "MONOLITHIC;COMPONENT")
run_cpack_test(DEPENDENCIES "RPM;DEB" true "COMPONENT")
run_cpack_test(DIST "RPM" false "MONOLITHIC")
run_cpack_test(EMPTY_DIR "RPM;DEB;TGZ" true "MONOLITHIC;COMPONENT")
diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake
new file mode 100644
index 0000000..9b8205b
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake
@@ -0,0 +1,6 @@
+if(${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid_.*_var")
+ set(EXPECTED_FILES_COUNT "0")
+else()
+ set(EXPECTED_FILES_COUNT "1")
+ set(EXPECTED_FILE_CONTENT_1_LIST "/usr;/usr/foo;/usr/foo/CMakeLists.txt")
+endif()
diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/VerifyResult.cmake
new file mode 100644
index 0000000..16ebcdc
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/VerifyResult.cmake
@@ -0,0 +1,39 @@
+if(NOT ${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid_.*_var")
+ if(GENERATOR_TYPE STREQUAL "RPM")
+ function(checkContentPermissions_ FILE REGEX)
+ execute_process(COMMAND ${RPM_EXECUTABLE} -qp --dump ${FILE}
+ WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ OUTPUT_VARIABLE PERMISSIONS_
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(NOT PERMISSIONS_ MATCHES "${REGEX}")
+ message(FATAL_ERROR "Permissions in '${FILE}'. Permissions: '${PERMISSIONS_}'")
+ endif()
+ endfunction()
+
+ if(${RunCMake_SUBTEST_SUFFIX} MATCHES "CMAKE_var_set")
+ checkContentPermissions_("${FOUND_FILE_1}"
+ "/usr/foo .*740 root root.*")
+ else()
+ checkContentPermissions_("${FOUND_FILE_1}"
+ "/usr/foo .*700 root root.*")
+ endif()
+ else() # DEB
+ function(checkContentPermissions_ FILE REGEX)
+ getPackageContent("${FILE}" PERMISSIONS_)
+
+ if(NOT PERMISSIONS_ MATCHES "${REGEX}")
+ message(FATAL_ERROR "Permissions in '${FILE}'. Permissions: '${PERMISSIONS_}'")
+ endif()
+ endfunction()
+
+ if(${RunCMake_SUBTEST_SUFFIX} MATCHES "CMAKE_var_set")
+ checkContentPermissions_("${FOUND_FILE_1}"
+ "drwxr----- root/root .* ./usr/\ndrwxr----- root/root .* ./usr/foo/\n.*")
+ else()
+ checkContentPermissions_("${FOUND_FILE_1}"
+ "drwx------ root/root .* ./usr/\ndrwx------ root/root .* ./usr/foo/\n.*")
+ endif()
+ endif()
+endif()
diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CMAKE_var-stderr.txt b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CMAKE_var-stderr.txt
new file mode 100644
index 0000000..541763a
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CMAKE_var-stderr.txt
@@ -0,0 +1 @@
+.*CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS value is invalid.*
diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CPACK_var-stderr.txt b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CPACK_var-stderr.txt
new file mode 100644
index 0000000..541763a
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CPACK_var-stderr.txt
@@ -0,0 +1 @@
+.*CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS value is invalid.*
diff --git a/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/test.cmake b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/test.cmake
new file mode 100644
index 0000000..afe9390
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/test.cmake
@@ -0,0 +1,34 @@
+if(${RunCMake_SUBTEST_SUFFIX} MATCHES "CMAKE_var_set" OR
+ ${RunCMake_SUBTEST_SUFFIX} MATCHES "both_set")
+
+ set(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
+ OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ GROUP_READ
+ )
+endif()
+
+if(${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid_CMAKE_var")
+ list(APPEND CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS "INVALID")
+endif()
+
+if(${RunCMake_SUBTEST_SUFFIX} MATCHES "CPACK_var_set" OR
+ ${RunCMake_SUBTEST_SUFFIX} MATCHES "both_set")
+
+ set(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
+ OWNER_READ
+ OWNER_WRITE
+ OWNER_EXECUTE
+ )
+endif()
+
+if(${RunCMake_SUBTEST_SUFFIX} MATCHES "invalid_CPACK_var")
+ list(APPEND CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS "INVALID")
+endif()
+
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+ set(CPACK_COMPONENTS_ALL test)
+endif()
diff --git a/bootstrap b/bootstrap
index 47f7e76..d9e243d 100755
--- a/bootstrap
+++ b/bootstrap
@@ -311,6 +311,7 @@ CMAKE_CXX_SOURCES="\
cmFindProgramCommand \
cmForEachCommand \
cmFunctionCommand \
+ cmFSPermissions \
cmGeneratedFileStream \
cmGeneratorExpression \
cmGeneratorExpressionContext \