mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-03 21:00:01 -05:00
file(GENERATE): Add policy CMP0070 to define relative path behavior
Previously `file(GENERATE)` did not define any behavior for relative paths given to the `OUTPUT` or `INPUT` arguments. Define behavior consistent with CMake conventions and add a policy to provide compatibility for projects that relied on the old accidental behavior. Fixes: #16786
This commit is contained in:
@@ -20,11 +20,13 @@
|
||||
cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile(
|
||||
const std::string& input,
|
||||
CM_AUTO_PTR<cmCompiledGeneratorExpression> outputFileExpr,
|
||||
CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent)
|
||||
CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent,
|
||||
cmPolicies::PolicyStatus policyStatusCMP0070)
|
||||
: Input(input)
|
||||
, OutputFileExpr(outputFileExpr)
|
||||
, Condition(condition)
|
||||
, InputIsContent(inputIsContent)
|
||||
, PolicyStatusCMP0070(policyStatusCMP0070)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,6 +60,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(
|
||||
|
||||
if (cmSystemTools::FileIsFullPath(outputFileName)) {
|
||||
outputFileName = cmSystemTools::CollapseFullPath(outputFileName);
|
||||
} else {
|
||||
outputFileName = this->FixRelativePath(outputFileName, PathForOutput, lg);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string>::iterator it =
|
||||
@@ -118,6 +122,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
|
||||
std::string inputFileName = this->Input;
|
||||
if (cmSystemTools::FileIsFullPath(inputFileName)) {
|
||||
inputFileName = cmSystemTools::CollapseFullPath(inputFileName);
|
||||
} else {
|
||||
inputFileName = this->FixRelativePath(inputFileName, PathForInput, lg);
|
||||
}
|
||||
lg->GetMakefile()->AddCMakeDependFile(inputFileName);
|
||||
cmSystemTools::GetPermissions(inputFileName.c_str(), perm);
|
||||
@@ -167,3 +173,57 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmGeneratorExpressionEvaluationFile::FixRelativePath(
|
||||
std::string const& relativePath, PathRole role, cmLocalGenerator* lg)
|
||||
{
|
||||
std::string resultPath;
|
||||
switch (this->PolicyStatusCMP0070) {
|
||||
case cmPolicies::WARN: {
|
||||
std::string arg;
|
||||
switch (role) {
|
||||
case PathForInput:
|
||||
arg = "INPUT";
|
||||
break;
|
||||
case PathForOutput:
|
||||
arg = "OUTPUT";
|
||||
break;
|
||||
}
|
||||
std::ostringstream w;
|
||||
/* clang-format off */
|
||||
w <<
|
||||
cmPolicies::GetPolicyWarning(cmPolicies::CMP0070) << "\n"
|
||||
"file(GENERATE) given relative " << arg << " path:\n"
|
||||
" " << relativePath << "\n"
|
||||
"This is not defined behavior unless CMP0070 is set to NEW. "
|
||||
"For compatibility with older versions of CMake, the previous "
|
||||
"undefined behavior will be used."
|
||||
;
|
||||
/* clang-format on */
|
||||
lg->IssueMessage(cmake::AUTHOR_WARNING, w.str());
|
||||
}
|
||||
CM_FALLTHROUGH;
|
||||
case cmPolicies::OLD:
|
||||
// OLD behavior is to use the relative path unchanged,
|
||||
// which ends up being used relative to the working dir.
|
||||
resultPath = relativePath;
|
||||
break;
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
// NEW behavior is to interpret the relative path with respect
|
||||
// to the current source or binary directory.
|
||||
switch (role) {
|
||||
case PathForInput:
|
||||
resultPath = cmSystemTools::CollapseFullPath(
|
||||
relativePath, lg->GetCurrentSourceDirectory());
|
||||
break;
|
||||
case PathForOutput:
|
||||
resultPath = cmSystemTools::CollapseFullPath(
|
||||
relativePath, lg->GetCurrentBinaryDirectory());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return resultPath;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmPolicies.h"
|
||||
#include "cm_auto_ptr.hxx"
|
||||
#include "cm_sys_stat.h"
|
||||
|
||||
@@ -21,7 +22,8 @@ public:
|
||||
cmGeneratorExpressionEvaluationFile(
|
||||
const std::string& input,
|
||||
CM_AUTO_PTR<cmCompiledGeneratorExpression> outputFileExpr,
|
||||
CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent);
|
||||
CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent,
|
||||
cmPolicies::PolicyStatus policyStatusCMP0070);
|
||||
|
||||
void Generate(cmLocalGenerator* lg);
|
||||
|
||||
@@ -35,12 +37,21 @@ private:
|
||||
cmCompiledGeneratorExpression* inputExpression,
|
||||
std::map<std::string, std::string>& outputFiles, mode_t perm);
|
||||
|
||||
enum PathRole
|
||||
{
|
||||
PathForInput,
|
||||
PathForOutput
|
||||
};
|
||||
std::string FixRelativePath(std::string const& filePath, PathRole role,
|
||||
cmLocalGenerator* lg);
|
||||
|
||||
private:
|
||||
const std::string Input;
|
||||
const CM_AUTO_PTR<cmCompiledGeneratorExpression> OutputFileExpr;
|
||||
const CM_AUTO_PTR<cmCompiledGeneratorExpression> Condition;
|
||||
std::vector<std::string> Files;
|
||||
const bool InputIsContent;
|
||||
cmPolicies::PolicyStatus PolicyStatusCMP0070;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -592,7 +592,8 @@ void cmMakefile::AddEvaluationFile(
|
||||
CM_AUTO_PTR<cmCompiledGeneratorExpression> condition, bool inputIsContent)
|
||||
{
|
||||
this->EvaluationFiles.push_back(new cmGeneratorExpressionEvaluationFile(
|
||||
inputFile, outputName, condition, inputIsContent));
|
||||
inputFile, outputName, condition, inputIsContent,
|
||||
this->GetPolicyStatus(cmPolicies::CMP0070)));
|
||||
}
|
||||
|
||||
std::vector<cmGeneratorExpressionEvaluationFile*>
|
||||
|
||||
@@ -206,6 +206,9 @@ class cmMakefile;
|
||||
cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0069, \
|
||||
"INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.", 3, 9, 0, \
|
||||
cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0070, \
|
||||
"Define file(GENERATE) behavior for relative paths.", 3, 10, 0, \
|
||||
cmPolicies::WARN)
|
||||
|
||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||
|
||||
Reference in New Issue
Block a user