mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 13:20:47 -06:00
file(GENERATE): Support options to manipulate file permissions
Fixes: #15653
This commit is contained in:
@@ -479,7 +479,9 @@ modified.
|
|||||||
|
|
||||||
file(GENERATE OUTPUT output-file
|
file(GENERATE OUTPUT output-file
|
||||||
<INPUT input-file|CONTENT content>
|
<INPUT input-file|CONTENT content>
|
||||||
[CONDITION expression] [TARGET target])
|
[CONDITION expression] [TARGET target]
|
||||||
|
[FILE_PERMISSIONS <permissions>...]
|
||||||
|
[NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS])
|
||||||
|
|
||||||
Generate an output file for each build configuration supported by the current
|
Generate an output file for each build configuration supported by the current
|
||||||
:manual:`CMake Generator <cmake-generators(7)>`. Evaluate
|
:manual:`CMake Generator <cmake-generators(7)>`. Evaluate
|
||||||
@@ -520,6 +522,17 @@ from the input content to produce the output content. The options are:
|
|||||||
require a target for evaluation (e.g. ``$<COMPILE_FEATURES:...>``,
|
require a target for evaluation (e.g. ``$<COMPILE_FEATURES:...>``,
|
||||||
``$<TARGET_PROPERTY:prop>``).
|
``$<TARGET_PROPERTY:prop>``).
|
||||||
|
|
||||||
|
``FILE_PERMISSIONS <permissions>...``
|
||||||
|
Use user provided permissions for the generated file.
|
||||||
|
|
||||||
|
``NO_SOURCE_PERMISSIONS``
|
||||||
|
The generated file permissions default to the standard 644 value
|
||||||
|
(-rw-r--r--).
|
||||||
|
|
||||||
|
``USE_SOURCE_PERMISSIONS``
|
||||||
|
Transfer the file permissions of the original file to the generated file.
|
||||||
|
This option expects INPUT option.
|
||||||
|
|
||||||
Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific
|
Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific
|
||||||
``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``.
|
``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``.
|
||||||
Generated files are modified and their timestamp updated on subsequent cmake
|
Generated files are modified and their timestamp updated on subsequent cmake
|
||||||
|
|||||||
6
Help/release/dev/file-generate-permissions.rst
Normal file
6
Help/release/dev/file-generate-permissions.rst
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
file-generate-permissions
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
* The :command:`file(GENERATE)` command gained ``NO_SOURCE_PERMISSIONS``,
|
||||||
|
``USE_SOURCE_PERMISSIONS``, and ``FILE_PERMISSIONS`` options to support
|
||||||
|
permissions of the generated file.
|
||||||
@@ -2291,7 +2291,7 @@ void AddEvaluationFile(const std::string& inputName,
|
|||||||
const std::string& targetName,
|
const std::string& targetName,
|
||||||
const std::string& outputExpr,
|
const std::string& outputExpr,
|
||||||
const std::string& condition, bool inputIsContent,
|
const std::string& condition, bool inputIsContent,
|
||||||
cmExecutionStatus& status)
|
mode_t permissions, cmExecutionStatus& status)
|
||||||
{
|
{
|
||||||
cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();
|
cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();
|
||||||
|
|
||||||
@@ -2305,7 +2305,7 @@ void AddEvaluationFile(const std::string& inputName,
|
|||||||
|
|
||||||
status.GetMakefile().AddEvaluationFile(
|
status.GetMakefile().AddEvaluationFile(
|
||||||
inputName, targetName, std::move(outputCge), std::move(conditionCge),
|
inputName, targetName, std::move(outputCge), std::move(conditionCge),
|
||||||
inputIsContent);
|
permissions, inputIsContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandleGenerateCommand(std::vector<std::string> const& args,
|
bool HandleGenerateCommand(std::vector<std::string> const& args,
|
||||||
@@ -2323,14 +2323,21 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
|
|||||||
std::string Content;
|
std::string Content;
|
||||||
std::string Condition;
|
std::string Condition;
|
||||||
std::string Target;
|
std::string Target;
|
||||||
|
bool NoSourcePermissions = false;
|
||||||
|
bool UseSourcePermissions = false;
|
||||||
|
std::vector<std::string> FilePermissions;
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto const parser = cmArgumentParser<Arguments>{}
|
static auto const parser =
|
||||||
.Bind("OUTPUT"_s, &Arguments::Output)
|
cmArgumentParser<Arguments>{}
|
||||||
.Bind("INPUT"_s, &Arguments::Input)
|
.Bind("OUTPUT"_s, &Arguments::Output)
|
||||||
.Bind("CONTENT"_s, &Arguments::Content)
|
.Bind("INPUT"_s, &Arguments::Input)
|
||||||
.Bind("CONDITION"_s, &Arguments::Condition)
|
.Bind("CONTENT"_s, &Arguments::Content)
|
||||||
.Bind("TARGET"_s, &Arguments::Target);
|
.Bind("CONDITION"_s, &Arguments::Condition)
|
||||||
|
.Bind("TARGET"_s, &Arguments::Target)
|
||||||
|
.Bind("NO_SOURCE_PERMISSIONS"_s, &Arguments::NoSourcePermissions)
|
||||||
|
.Bind("USE_SOURCE_PERMISSIONS"_s, &Arguments::UseSourcePermissions)
|
||||||
|
.Bind("FILE_PERMISSIONS"_s, &Arguments::FilePermissions);
|
||||||
|
|
||||||
std::vector<std::string> unparsedArguments;
|
std::vector<std::string> unparsedArguments;
|
||||||
std::vector<std::string> keywordsMissingValues;
|
std::vector<std::string> keywordsMissingValues;
|
||||||
@@ -2399,8 +2406,65 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
|
|||||||
input = arguments.Content;
|
input = arguments.Content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arguments.NoSourcePermissions && arguments.UseSourcePermissions) {
|
||||||
|
status.SetError("given both NO_SOURCE_PERMISSIONS and "
|
||||||
|
"USE_SOURCE_PERMISSIONS. Only one option allowed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arguments.FilePermissions.empty()) {
|
||||||
|
if (arguments.NoSourcePermissions) {
|
||||||
|
status.SetError("given both NO_SOURCE_PERMISSIONS and "
|
||||||
|
"FILE_PERMISSIONS. Only one option allowed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (arguments.UseSourcePermissions) {
|
||||||
|
status.SetError("given both USE_SOURCE_PERMISSIONS and "
|
||||||
|
"FILE_PERMISSIONS. Only one option allowed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.UseSourcePermissions) {
|
||||||
|
if (inputIsContent) {
|
||||||
|
status.SetError("given USE_SOURCE_PERMISSIONS without a file INPUT.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mode_t permisiions = 0;
|
||||||
|
if (arguments.NoSourcePermissions) {
|
||||||
|
permisiions |= cmFSPermissions::mode_owner_read;
|
||||||
|
permisiions |= cmFSPermissions::mode_owner_write;
|
||||||
|
permisiions |= cmFSPermissions::mode_group_read;
|
||||||
|
permisiions |= cmFSPermissions::mode_world_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arguments.FilePermissions.empty()) {
|
||||||
|
std::vector<std::string> invalidOptions;
|
||||||
|
for (auto const& e : arguments.FilePermissions) {
|
||||||
|
if (!cmFSPermissions::stringToModeT(e, permisiions)) {
|
||||||
|
invalidOptions.push_back(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!invalidOptions.empty()) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "given invalid permission ";
|
||||||
|
for (auto i = 0u; i < invalidOptions.size(); i++) {
|
||||||
|
if (i == 0u) {
|
||||||
|
oss << "\"" << invalidOptions[i] << "\"";
|
||||||
|
} else {
|
||||||
|
oss << ",\"" << invalidOptions[i] << "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oss << ".";
|
||||||
|
status.SetError(oss.str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AddEvaluationFile(input, arguments.Target, arguments.Output,
|
AddEvaluationFile(input, arguments.Target, arguments.Output,
|
||||||
arguments.Condition, inputIsContent, status);
|
arguments.Condition, inputIsContent, permisiions, status);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,13 +21,15 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
|
|||||||
std::string input, std::string target,
|
std::string input, std::string target,
|
||||||
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
|
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
|
||||||
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
||||||
bool inputIsContent, cmPolicies::PolicyStatus policyStatusCMP0070)
|
bool inputIsContent, mode_t permissions,
|
||||||
|
cmPolicies::PolicyStatus policyStatusCMP0070)
|
||||||
: Input(std::move(input))
|
: Input(std::move(input))
|
||||||
, Target(std::move(target))
|
, Target(std::move(target))
|
||||||
, OutputFileExpr(std::move(outputFileExpr))
|
, OutputFileExpr(std::move(outputFileExpr))
|
||||||
, Condition(std::move(condition))
|
, Condition(std::move(condition))
|
||||||
, InputIsContent(inputIsContent)
|
, InputIsContent(inputIsContent)
|
||||||
, PolicyStatusCMP0070(policyStatusCMP0070)
|
, PolicyStatusCMP0070(policyStatusCMP0070)
|
||||||
|
, Permissions(permissions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,14 +113,15 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
|
|||||||
|
|
||||||
void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
|
void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
|
||||||
{
|
{
|
||||||
mode_t perm = 0;
|
|
||||||
std::string inputContent;
|
std::string inputContent;
|
||||||
if (this->InputIsContent) {
|
if (this->InputIsContent) {
|
||||||
inputContent = this->Input;
|
inputContent = this->Input;
|
||||||
} else {
|
} else {
|
||||||
const std::string inputFileName = this->GetInputFileName(lg);
|
const std::string inputFileName = this->GetInputFileName(lg);
|
||||||
lg->GetMakefile()->AddCMakeDependFile(inputFileName);
|
lg->GetMakefile()->AddCMakeDependFile(inputFileName);
|
||||||
cmSystemTools::GetPermissions(inputFileName.c_str(), perm);
|
if (!this->Permissions) {
|
||||||
|
cmSystemTools::GetPermissions(inputFileName.c_str(), this->Permissions);
|
||||||
|
}
|
||||||
cmsys::ifstream fin(inputFileName.c_str());
|
cmsys::ifstream fin(inputFileName.c_str());
|
||||||
if (!fin) {
|
if (!fin) {
|
||||||
std::ostringstream e;
|
std::ostringstream e;
|
||||||
@@ -152,7 +155,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
|
|||||||
|
|
||||||
for (std::string const& le : enabledLanguages) {
|
for (std::string const& le : enabledLanguages) {
|
||||||
for (std::string const& li : allConfigs) {
|
for (std::string const& li : allConfigs) {
|
||||||
this->Generate(lg, li, le, inputExpression.get(), outputFiles, perm);
|
this->Generate(lg, li, le, inputExpression.get(), outputFiles,
|
||||||
|
this->Permissions);
|
||||||
if (cmSystemTools::GetFatalErrorOccured()) {
|
if (cmSystemTools::GetFatalErrorOccured()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ public:
|
|||||||
std::string input, std::string target,
|
std::string input, std::string target,
|
||||||
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
|
std::unique_ptr<cmCompiledGeneratorExpression> outputFileExpr,
|
||||||
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
||||||
bool inputIsContent, cmPolicies::PolicyStatus policyStatusCMP0070);
|
bool inputIsContent, mode_t permissions,
|
||||||
|
cmPolicies::PolicyStatus policyStatusCMP0070);
|
||||||
|
|
||||||
void Generate(cmLocalGenerator* lg);
|
void Generate(cmLocalGenerator* lg);
|
||||||
|
|
||||||
@@ -59,4 +60,5 @@ private:
|
|||||||
std::vector<std::string> Files;
|
std::vector<std::string> Files;
|
||||||
const bool InputIsContent;
|
const bool InputIsContent;
|
||||||
cmPolicies::PolicyStatus PolicyStatusCMP0070;
|
cmPolicies::PolicyStatus PolicyStatusCMP0070;
|
||||||
|
mode_t Permissions;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -865,13 +865,14 @@ void cmMakefile::EnforceDirectoryLevelRules() const
|
|||||||
void cmMakefile::AddEvaluationFile(
|
void cmMakefile::AddEvaluationFile(
|
||||||
const std::string& inputFile, const std::string& targetName,
|
const std::string& inputFile, const std::string& targetName,
|
||||||
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
|
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
|
||||||
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
std::unique_ptr<cmCompiledGeneratorExpression> condition, mode_t permissions,
|
||||||
bool inputIsContent)
|
bool inputIsContent)
|
||||||
{
|
{
|
||||||
this->EvaluationFiles.push_back(
|
this->EvaluationFiles.push_back(
|
||||||
cm::make_unique<cmGeneratorExpressionEvaluationFile>(
|
cm::make_unique<cmGeneratorExpressionEvaluationFile>(
|
||||||
inputFile, targetName, std::move(outputName), std::move(condition),
|
inputFile, targetName, std::move(outputName), std::move(condition),
|
||||||
inputIsContent, this->GetPolicyStatus(cmPolicies::CMP0070)));
|
inputIsContent, permissions,
|
||||||
|
this->GetPolicyStatus(cmPolicies::CMP0070)));
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
|
const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
|
||||||
|
|||||||
@@ -899,7 +899,7 @@ public:
|
|||||||
const std::string& inputFile, const std::string& targetName,
|
const std::string& inputFile, const std::string& targetName,
|
||||||
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
|
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
|
||||||
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
std::unique_ptr<cmCompiledGeneratorExpression> condition,
|
||||||
bool inputIsContent);
|
mode_t permissions, bool inputIsContent);
|
||||||
const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
|
const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
|
||||||
GetEvaluationFiles() const;
|
GetEvaluationFiles() const;
|
||||||
|
|
||||||
|
|||||||
15
Tests/RunCMake/File_Generate/CustomFilePermissions.cmake
Normal file
15
Tests/RunCMake/File_Generate/CustomFilePermissions.cmake
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/customfilepermissions.txt")
|
||||||
|
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/customfilepermissions.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
FILE_PERMISSIONS
|
||||||
|
OWNER_READ OWNER_WRITE OWNER_EXECUTE
|
||||||
|
GROUP_EXECUTE
|
||||||
|
WORLD_EXECUTE
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(checkCustomFilePermissions ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
-DgeneratedFile=${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/customfilepermissions.txt
|
||||||
|
-P "${CMAKE_CURRENT_SOURCE_DIR}/CustomFilePermissionsVerify.cmake"
|
||||||
|
)
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
if(NOT EXISTS "${generatedFile}")
|
||||||
|
message(SEND_ERROR "Missing file:\n ${generatedFile}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
find_program(STAT_EXECUTABLE NAMES stat)
|
||||||
|
if(NOT STAT_EXECUTABLE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_HOST_SYSTEM_NAME MATCHES "FreeBSD")
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
elseif (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT output EQUAL "711")
|
||||||
|
message(SEND_ERROR "file generate has different permissions source "
|
||||||
|
"permissions: \"${output}\" desired permissions: \"711\"")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
10
Tests/RunCMake/File_Generate/NoSourcePermissions.cmake
Normal file
10
Tests/RunCMake/File_Generate/NoSourcePermissions.cmake
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/nosourcepermissions.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
NO_SOURCE_PERMISSIONS
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(checkNoSourcePermission ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
-DgeneratedFile=${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/nosourcepermissions.txt
|
||||||
|
-P "${CMAKE_CURRENT_SOURCE_DIR}/NoSourcePermissionsVerify.cmake"
|
||||||
|
)
|
||||||
36
Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake
Normal file
36
Tests/RunCMake/File_Generate/NoSourcePermissionsVerify.cmake
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
if(NOT EXISTS "${generatedFile}")
|
||||||
|
message(SEND_ERROR "Missing generated file:\n ${generatedFile}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
find_program(STAT_EXECUTABLE NAMES stat)
|
||||||
|
if(NOT STAT_EXECUTABLE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_HOST_SYSTEM_NAME MATCHES "FreeBSD")
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT output EQUAL "644")
|
||||||
|
message(SEND_ERROR "generated file has different permissions than "
|
||||||
|
"desired, generated permissions: \"${output}\"")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
@@ -123,3 +123,24 @@ set(RunCMake_TEST_NO_CLEAN 1)
|
|||||||
run_cmake_command(AdjacentInOut-nowork ${CMAKE_COMMAND} --build .)
|
run_cmake_command(AdjacentInOut-nowork ${CMAKE_COMMAND} --build .)
|
||||||
unset(RunCMake_TEST_BINARY_DIR)
|
unset(RunCMake_TEST_BINARY_DIR)
|
||||||
unset(RunCMake_TEST_NO_CLEAN)
|
unset(RunCMake_TEST_NO_CLEAN)
|
||||||
|
|
||||||
|
run_cmake(SourcePermissions1)
|
||||||
|
run_cmake(SourcePermissions2)
|
||||||
|
run_cmake(SourcePermissions3)
|
||||||
|
run_cmake(SourcePermissions4)
|
||||||
|
run_cmake(SourcePermissions5)
|
||||||
|
|
||||||
|
function(run_cmake_and_verify_after_build case)
|
||||||
|
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${case}-build")
|
||||||
|
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||||
|
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||||
|
set(RunCMake_TEST_NO_CLEAN 1)
|
||||||
|
run_cmake(${case})
|
||||||
|
run_cmake_command("${case}-build" ${CMAKE_COMMAND} --build .)
|
||||||
|
unset(RunCMake_TEST_NO_CLEAN)
|
||||||
|
unset(RunCMake_TEST_BINARY_DIR)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
run_cmake_and_verify_after_build(NoSourcePermissions)
|
||||||
|
run_cmake_and_verify_after_build(UseSourcePermissions)
|
||||||
|
run_cmake_and_verify_after_build(CustomFilePermissions)
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
CMake Error at SourcePermissions1.cmake:[0-9]+ \(file\):
|
||||||
|
file given both NO_SOURCE_PERMISSIONS and USE_SOURCE_PERMISSIONS. Only one
|
||||||
|
option allowed.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:[0-9]+ \(include\)
|
||||||
5
Tests/RunCMake/File_Generate/SourcePermissions1.cmake
Normal file
5
Tests/RunCMake/File_Generate/SourcePermissions1.cmake
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission1.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
NO_SOURCE_PERMISSIONS
|
||||||
|
USE_SOURCE_PERMISSIONS
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
CMake Error at SourcePermissions2.cmake:[0-9]+ \(file\):
|
||||||
|
file given both NO_SOURCE_PERMISSIONS and FILE_PERMISSIONS. Only one
|
||||||
|
option allowed.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:[0-9]+ \(include\)
|
||||||
5
Tests/RunCMake/File_Generate/SourcePermissions2.cmake
Normal file
5
Tests/RunCMake/File_Generate/SourcePermissions2.cmake
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission2.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
NO_SOURCE_PERMISSIONS
|
||||||
|
FILE_PERMISSIONS OWNER_READ
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
CMake Error at SourcePermissions3.cmake:[0-9]+ \(file\):
|
||||||
|
file given both USE_SOURCE_PERMISSIONS and FILE_PERMISSIONS. Only one
|
||||||
|
option allowed.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:[0-9]+ \(include\)
|
||||||
5
Tests/RunCMake/File_Generate/SourcePermissions3.cmake
Normal file
5
Tests/RunCMake/File_Generate/SourcePermissions3.cmake
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission3.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
USE_SOURCE_PERMISSIONS
|
||||||
|
FILE_PERMISSIONS OWNER_READ
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
CMake Error at SourcePermissions4.cmake:[0-9]+ \(file\):
|
||||||
|
file given USE_SOURCE_PERMISSIONS without a file INPUT.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:[0-9]+ \(include\)
|
||||||
4
Tests/RunCMake/File_Generate/SourcePermissions4.cmake
Normal file
4
Tests/RunCMake/File_Generate/SourcePermissions4.cmake
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission4.txt"
|
||||||
|
CONTENT "Input is content"
|
||||||
|
USE_SOURCE_PERMISSIONS
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
CMake Error at SourcePermissions5.cmake:[0-9]+ \(file\):
|
||||||
|
file given invalid permission "GROUP_RWX","USER_ALL".
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:[0-9]+ \(include\)
|
||||||
4
Tests/RunCMake/File_Generate/SourcePermissions5.cmake
Normal file
4
Tests/RunCMake/File_Generate/SourcePermissions5.cmake
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-sourcepermission5.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
FILE_PERMISSIONS OWNER_READ GROUP_RWX USER_ALL
|
||||||
|
)
|
||||||
11
Tests/RunCMake/File_Generate/UseSourcePermissions.cmake
Normal file
11
Tests/RunCMake/File_Generate/UseSourcePermissions.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/usesourcepermissions.txt"
|
||||||
|
INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt"
|
||||||
|
USE_SOURCE_PERMISSIONS
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(checkUseSourcePermissions ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
-DsourceFile=${CMAKE_CURRENT_SOURCE_DIR}/input.txt
|
||||||
|
-DgeneratedFile=${CMAKE_CURRENT_BINARY_DIR}/$<LOWER_CASE:$<CONFIG>>/usesourcepermissions.txt
|
||||||
|
-P "${CMAKE_CURRENT_SOURCE_DIR}/UseSourcePermissionsVerify.cmake"
|
||||||
|
)
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
if(NOT EXISTS "${generatedFile}")
|
||||||
|
message(SEND_ERROR "Missing generated file:\n ${generatedFile}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
find_program(STAT_EXECUTABLE NAMES stat)
|
||||||
|
if(NOT STAT_EXECUTABLE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_HOST_SYSTEM_NAME MATCHES "FreeBSD")
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${sourceFile}"
|
||||||
|
OUTPUT_VARIABLE output1
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -f %Lp "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output2
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
elseif (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${sourceFile}"
|
||||||
|
OUTPUT_VARIABLE output1
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -f %A "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output2
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${sourceFile}"
|
||||||
|
OUTPUT_VARIABLE output1
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
execute_process(COMMAND "${STAT_EXECUTABLE}" -c %a "${generatedFile}"
|
||||||
|
OUTPUT_VARIABLE output2
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT output1 EQUAL output2)
|
||||||
|
message(SEND_ERROR "generated file has a different permissions source "
|
||||||
|
"permissions: \"${output1}\" generated permissions: \"${output2}\"")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
Reference in New Issue
Block a user