mirror of
https://github.com/reactos/CMake.git
synced 2024-11-24 12:09:48 +00: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:
parent
69050f4d16
commit
82be694c7a
@ -291,6 +291,8 @@ from the input content to produce the output content. The options are:
|
||||
|
||||
``INPUT <input-file>``
|
||||
Use the content from a given file as input.
|
||||
A relative path is treated with respect to the value of
|
||||
:variable:`CMAKE_CURRENT_SOURCE_DIR`. See policy :policy:`CMP0070`.
|
||||
|
||||
``OUTPUT <output-file>``
|
||||
Specify the output file name to generate. Use generator expressions
|
||||
@ -298,6 +300,9 @@ from the input content to produce the output content. The options are:
|
||||
name. Multiple configurations may generate the same output file only
|
||||
if the generated content is identical. Otherwise, the ``<output-file>``
|
||||
must evaluate to an unique name for each configuration.
|
||||
A relative path (after evaluating generator expressions) is treated
|
||||
with respect to the value of :variable:`CMAKE_CURRENT_BINARY_DIR`.
|
||||
See policy :policy:`CMP0070`.
|
||||
|
||||
Exactly one ``CONTENT`` or ``INPUT`` option must be given. A specific
|
||||
``OUTPUT`` file may be named by at most one invocation of ``file(GENERATE)``.
|
||||
|
@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
|
||||
to determine whether to report an error on use of deprecated macros or
|
||||
functions.
|
||||
|
||||
Policies Introduced by CMake 3.10
|
||||
=================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
CMP0070: Define file(GENERATE) behavior for relative paths. </policy/CMP0070>
|
||||
|
||||
Policies Introduced by CMake 3.9
|
||||
================================
|
||||
|
||||
|
25
Help/policy/CMP0070.rst
Normal file
25
Help/policy/CMP0070.rst
Normal file
@ -0,0 +1,25 @@
|
||||
CMP0070
|
||||
-------
|
||||
|
||||
Define :command:`file(GENERATE)` behavior for relative paths.
|
||||
|
||||
CMake 3.10 and newer define that relative paths given to ``INPUT`` and
|
||||
``OUTPUT`` arguments of ``file(GENERATE)`` are interpreted relative to the
|
||||
current source and binary directories, respectively. CMake 3.9 and lower did
|
||||
not define any behavior for relative paths but did not diagnose them either
|
||||
and accidentally treated them relative to the process working directory.
|
||||
Policy ``CMP0070`` provides compatibility with projects that used the old
|
||||
undefined behavior.
|
||||
|
||||
This policy affects behavior of relative paths given to ``file(GENERATE)``.
|
||||
The ``OLD`` behavior for this policy is to treat the paths relative to the
|
||||
working directory of CMake. The ``NEW`` behavior for this policy is to
|
||||
interpret relative paths with respect to the current source or binary
|
||||
directory of the caller.
|
||||
|
||||
This policy was introduced in CMake version 3.10. CMake version
|
||||
|release| warns when the policy is not set and uses ``OLD`` behavior.
|
||||
Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
|
||||
explicitly.
|
||||
|
||||
.. include:: DEPRECATED.txt
|
7
Help/release/dev/file-generate-relative-paths.rst
Normal file
7
Help/release/dev/file-generate-relative-paths.rst
Normal file
@ -0,0 +1,7 @@
|
||||
file-generate-relative-paths
|
||||
----------------------------
|
||||
|
||||
* The :command:`file(GENERATE)` command now interprets relative paths
|
||||
given to its ``OUTPUT`` and ``INPUT`` arguments with respect to the
|
||||
caller's current binary and source directories, respectively.
|
||||
See policy :policy:`CMP0070`.
|
@ -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)
|
||||
|
13
Tests/RunCMake/File_Generate/CMP0070-NEW-check.cmake
Normal file
13
Tests/RunCMake/File_Generate/CMP0070-NEW-check.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
foreach(f
|
||||
"${RunCMake_TEST_SOURCE_DIR}/relative-input-NEW.txt"
|
||||
"${RunCMake_TEST_BINARY_DIR}/relative-output-NEW.txt"
|
||||
)
|
||||
if(EXISTS "${f}")
|
||||
file(READ "${f}" content)
|
||||
if(NOT content MATCHES "^relative-input-NEW[\r\n]*$")
|
||||
string(APPEND RunCMake_TEST_FAILED "File\n ${f}\ndoes not have expected content.\n")
|
||||
endif()
|
||||
else()
|
||||
string(APPEND RunCMake_TEST_FAILED "Missing\n ${f}\n")
|
||||
endif()
|
||||
endforeach()
|
2
Tests/RunCMake/File_Generate/CMP0070-NEW.cmake
Normal file
2
Tests/RunCMake/File_Generate/CMP0070-NEW.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
cmake_policy(SET CMP0070 NEW)
|
||||
file(GENERATE OUTPUT relative-output-NEW.txt INPUT relative-input-NEW.txt)
|
13
Tests/RunCMake/File_Generate/CMP0070-OLD-check.cmake
Normal file
13
Tests/RunCMake/File_Generate/CMP0070-OLD-check.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
foreach(f
|
||||
"${RunCMake_TEST_BINARY_DIR}/relative-input-OLD.txt"
|
||||
"${RunCMake_TEST_BINARY_DIR}/relative-output-OLD.txt"
|
||||
)
|
||||
if(EXISTS "${f}")
|
||||
file(READ "${f}" content)
|
||||
if(NOT content MATCHES "^relative-input-OLD[\r\n]*$")
|
||||
string(APPEND RunCMake_TEST_FAILED "File\n ${f}\ndoes not have expected content.\n")
|
||||
endif()
|
||||
else()
|
||||
string(APPEND RunCMake_TEST_FAILED "Missing\n ${f}\n")
|
||||
endif()
|
||||
endforeach()
|
3
Tests/RunCMake/File_Generate/CMP0070-OLD.cmake
Normal file
3
Tests/RunCMake/File_Generate/CMP0070-OLD.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
cmake_policy(SET CMP0070 OLD)
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/relative-input-OLD.txt "relative-input-OLD\n")
|
||||
file(GENERATE OUTPUT relative-output-OLD.txt INPUT relative-input-OLD.txt)
|
13
Tests/RunCMake/File_Generate/CMP0070-WARN-check.cmake
Normal file
13
Tests/RunCMake/File_Generate/CMP0070-WARN-check.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
foreach(f
|
||||
"${RunCMake_TEST_BINARY_DIR}/relative-input-WARN.txt"
|
||||
"${RunCMake_TEST_BINARY_DIR}/relative-output-WARN.txt"
|
||||
)
|
||||
if(EXISTS "${f}")
|
||||
file(READ "${f}" content)
|
||||
if(NOT content MATCHES "^relative-input-WARN[\r\n]*$")
|
||||
string(APPEND RunCMake_TEST_FAILED "File\n ${f}\ndoes not have expected content.\n")
|
||||
endif()
|
||||
else()
|
||||
string(APPEND RunCMake_TEST_FAILED "Missing\n ${f}\n")
|
||||
endif()
|
||||
endforeach()
|
27
Tests/RunCMake/File_Generate/CMP0070-WARN-stderr.txt
Normal file
27
Tests/RunCMake/File_Generate/CMP0070-WARN-stderr.txt
Normal file
@ -0,0 +1,27 @@
|
||||
^CMake Warning \(dev\) in CMakeLists.txt:
|
||||
Policy CMP0070 is not set: Define file\(GENERATE\) behavior for relative
|
||||
paths. Run "cmake --help-policy CMP0070" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
file\(GENERATE\) given relative INPUT path:
|
||||
|
||||
relative-input-WARN.txt
|
||||
|
||||
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.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.(
|
||||
+
|
||||
CMake Warning \(dev\) in CMakeLists.txt:
|
||||
Policy CMP0070 is not set: Define file\(GENERATE\) behavior for relative
|
||||
paths. Run "cmake --help-policy CMP0070" for policy details. Use the
|
||||
cmake_policy command to set the policy and suppress this warning.
|
||||
|
||||
file\(GENERATE\) given relative OUTPUT path:
|
||||
|
||||
relative-output-WARN.txt
|
||||
|
||||
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.
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.)+$
|
2
Tests/RunCMake/File_Generate/CMP0070-WARN.cmake
Normal file
2
Tests/RunCMake/File_Generate/CMP0070-WARN.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/relative-input-WARN.txt "relative-input-WARN\n")
|
||||
file(GENERATE OUTPUT relative-output-WARN.txt INPUT relative-input-WARN.txt)
|
@ -1,5 +1,9 @@
|
||||
include(RunCMake)
|
||||
|
||||
run_cmake(CMP0070-NEW)
|
||||
run_cmake(CMP0070-OLD)
|
||||
run_cmake(CMP0070-WARN)
|
||||
|
||||
run_cmake(CommandConflict)
|
||||
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
|
||||
run_cmake(OutputConflict)
|
||||
|
1
Tests/RunCMake/File_Generate/relative-input-NEW.txt
Normal file
1
Tests/RunCMake/File_Generate/relative-input-NEW.txt
Normal file
@ -0,0 +1 @@
|
||||
relative-input-NEW
|
Loading…
Reference in New Issue
Block a user