From deeba85f81bb031384c1c014d7adcb733da491b4 Mon Sep 17 00:00:00 2001 From: Domen Vrankar Date: Mon, 30 Oct 2017 23:26:20 +0100 Subject: CMake: enable setting default dir creation permissions Introduces CMAKE_DEFAULT_DIRECTORY_INSTALL_PERMISSIONS variable which enables the user to specify the default permissions for directory creation. This setting is then used to auto set the permissions on directories which are implicitly created by install() and file(INSTALL) commands such as CMAKE_INSTALL_PREFIX directories. --- Help/manual/cmake-variables.7.rst | 1 + .../dev/cmake-default-dir-install-permissions.rst | 7 ++++++ ...CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst | 29 ++++++++++++++++++++++ Source/cmFileCommand.cxx | 23 ++++++++++++++++- Source/cmLocalGenerator.cxx | 14 +++++++++++ 5 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 Help/release/dev/cmake-default-dir-install-permissions.rst create mode 100644 Help/variable/CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 0170da1..7f13046 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 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..06f89e3 --- /dev/null +++ b/Help/release/dev/cmake-default-dir-install-permissions.rst @@ -0,0 +1,7 @@ +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)`. 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/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 191a666..a9824d7 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2015,9 +2015,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 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 const& installers = this->Makefile->GetInstallGenerators(); -- cgit v0.12 From 670ad047b34d983daf1f17f8b32c4abe2b7f22b1 Mon Sep 17 00:00:00 2001 From: Domen Vrankar Date: Thu, 2 Nov 2017 21:42:18 +0100 Subject: Move file/dir permissions code to common file. --- Source/CMakeLists.txt | 2 ++ Source/cmFSPermissions.cxx | 34 ++++++++++++++++++++++++++++++ Source/cmFSPermissions.h | 45 +++++++++++++++++++++++++++++++++++++++ Source/cmFileCommand.cxx | 52 +++------------------------------------------- bootstrap | 1 + 5 files changed, 85 insertions(+), 49 deletions(-) create mode 100644 Source/cmFSPermissions.cxx create mode 100644 Source/cmFSPermissions.h 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/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 + +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 a9824d7..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()); 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 \ -- cgit v0.12 From a4c829167dc8fa24e151d2afde7896b4588b24ad Mon Sep 17 00:00:00 2001 From: Domen Vrankar Date: Tue, 31 Oct 2017 12:19:10 +0100 Subject: CPack test: expand output checking fallback Some tests can have the same output for a certain subtest no matter which packaging generator is used. --- Tests/RunCMake/CPack/CPackTestHelpers.cmake | 2 ++ Tests/RunCMake/CPack/README.txt | 1 + 2 files changed, 3 insertions(+) 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: '---std.txt' where can either be 'out' or 'err'. -- cgit v0.12 From 7e896029cd6bc0a19b7e0ed6fa7b876e0f1764b3 Mon Sep 17 00:00:00 2001 From: Domen Vrankar Date: Wed, 8 Nov 2017 20:25:29 +0100 Subject: CPack: enable setting default dir creation permissions Introduces CPACK_DEFAULT_DIRECTORY_INSTALL_PERMISSIONS variable which adds support for functionality introduced by CMAKE_DEFAULT_DIRECTORY_INSTALL_PERMISSIONS variable. Fixes #17333 # Conflicts: # Help/release/dev/cmake-default-dir-install-permissions.rst --- Help/manual/cmake-variables.7.rst | 1 + .../dev/cmake-default-dir-install-permissions.rst | 5 ++ ...CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst | 11 +++++ Modules/CPack.cmake | 6 +++ Source/CPack/cmCPackGenerator.cxx | 54 ++++++++++++++++++---- Source/CPack/cmCPackGenerator.h | 7 ++- Tests/RunCMake/CPack/RunCMakeTest.cmake | 1 + .../tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake | 6 +++ .../tests/DEFAULT_PERMISSIONS/VerifyResult.cmake | 39 ++++++++++++++++ .../invalid_CMAKE_var-stderr.txt | 1 + .../invalid_CPACK_var-stderr.txt | 1 + .../CPack/tests/DEFAULT_PERMISSIONS/test.cmake | 34 ++++++++++++++ 12 files changed, 154 insertions(+), 12 deletions(-) create mode 100644 Help/variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS.rst create mode 100644 Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/ExpectedFiles.cmake create mode 100644 Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/VerifyResult.cmake create mode 100644 Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CMAKE_var-stderr.txt create mode 100644 Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/invalid_CPACK_var-stderr.txt create mode 100644 Tests/RunCMake/CPack/tests/DEFAULT_PERMISSIONS/test.cmake diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 7f13046..1927c37 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -530,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 index 06f89e3..8325fda 100644 --- a/Help/release/dev/cmake-default-dir-install-permissions.rst +++ b/Help/release/dev/cmake-default-dir-install-permissions.rst @@ -5,3 +5,8 @@ cmake-default-dir-install-permissions 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/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/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 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/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() -- cgit v0.12