Merge topic 'add-custom-target-byproduct-checks'

fd3a394614 add_custom_command: Format files in error message in a single line
a1cc6b4447 add_custom_target: Add output checks for custom target byproducts
cbb861ade8 add_custom_command: Add tests for custom command output checks

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3850
This commit is contained in:
Brad King 2019-09-26 13:47:41 +00:00 committed by Kitware Robot
commit df982c4e18
18 changed files with 205 additions and 38 deletions

View File

@ -168,6 +168,8 @@ set(SRCS
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
cmCacheManager.cxx
cmCacheManager.h
cmCheckCustomOutputs.h
cmCheckCustomOutputs.cxx
cmCLocaleEnvironmentScope.h
cmCLocaleEnvironmentScope.cxx
cmCommandArgumentParserHelper.cxx

View File

@ -5,6 +5,7 @@
#include <sstream>
#include <unordered_set>
#include "cmCheckCustomOutputs.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
@ -16,9 +17,6 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
static bool cmAddCustomCommandCommandCheckOutputs(
const std::vector<std::string>& outputs, cmExecutionStatus& status);
bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@ -307,9 +305,9 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
}
// Make sure the output names and locations are safe.
if (!cmAddCustomCommandCommandCheckOutputs(output, status) ||
!cmAddCustomCommandCommandCheckOutputs(outputs, status) ||
!cmAddCustomCommandCommandCheckOutputs(byproducts, status)) {
if (!cmCheckCustomOutputs(output, "OUTPUT", status) ||
!cmCheckCustomOutputs(outputs, "OUTPUTS", status) ||
!cmCheckCustomOutputs(byproducts, "BYPRODUCTS", status)) {
return false;
}
@ -322,8 +320,8 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
// No command for this output exists.
status.SetError(
cmStrCat("given APPEND option with output\n\"", output[0],
"\"\nwhich is not already a custom command output."));
cmStrCat("given APPEND option with output\n ", output[0],
"\nwhich is not already a custom command output."));
return false;
}
@ -387,29 +385,3 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
return true;
}
bool cmAddCustomCommandCommandCheckOutputs(
const std::vector<std::string>& outputs, cmExecutionStatus& status)
{
cmMakefile& mf = status.GetMakefile();
for (std::string const& o : outputs) {
// Make sure the file will not be generated into the source
// directory during an out of source build.
if (!mf.CanIWriteThisFile(o)) {
std::string e = "attempted to have a file \"" + o +
"\" in a source directory as an output of custom command.";
status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
// Make sure the output file name has no invalid characters.
std::string::size_type pos = o.find_first_of("#<>");
if (pos != std::string::npos) {
status.SetError(cmStrCat("called with OUTPUT containing a \"", o[pos],
"\". This character is not allowed."));
return false;
}
}
return true;
}

View File

@ -4,6 +4,7 @@
#include <utility>
#include "cmCheckCustomOutputs.h"
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
@ -205,6 +206,11 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
return false;
}
// Make sure the byproduct names and locations are safe.
if (!cmCheckCustomOutputs(byproducts, "BYPRODUCTS", status)) {
return false;
}
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
cmTarget* target = mf.AddUtilityCommand(

View File

@ -0,0 +1,36 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCheckCustomOutputs.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
bool cmCheckCustomOutputs(const std::vector<std::string>& outputs,
cm::string_view keyword, cmExecutionStatus& status)
{
cmMakefile& mf = status.GetMakefile();
for (std::string const& o : outputs) {
// Make sure the file will not be generated into the source
// directory during an out of source build.
if (!mf.CanIWriteThisFile(o)) {
status.SetError(
cmStrCat("attempted to have a file\n ", o,
"\nin a source directory as an output of custom command."));
cmSystemTools::SetFatalErrorOccured();
return false;
}
// Make sure the output file name has no invalid characters.
std::string::size_type pos = o.find_first_of("#<>");
if (pos != std::string::npos) {
status.SetError(cmStrCat("called with ", keyword, " containing a \"",
o[pos], "\". This character is not allowed."));
return false;
}
}
return true;
}

View File

@ -0,0 +1,18 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cmCheckCustomOutputs_h
#define cmCheckCustomOutputs_h
#include "cmConfigure.h" // IWYU pragma: keep
#include <cm/string_view>
#include <string>
#include <vector>
class cmExecutionStatus;
bool cmCheckCustomOutputs(const std::vector<std::string>& outputs,
cm::string_view keyword, cmExecutionStatus& status);
#endif

View File

@ -1,7 +1,7 @@
CMake Error at AppendNotOutput.cmake:1 \(add_custom_command\):
add_custom_command given APPEND option with output
.*RunCMake/add_custom_command/AppendNotOutput-build/out.*
.*RunCMake/add_custom_command/AppendNotOutput-build/out
which is not already a custom command output.
Call Stack \(most recent call first\):

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,36 @@
CMake Error at BadByproduct.cmake:2 \(add_custom_command\):
add_custom_command called with BYPRODUCTS containing a "#". This character
is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadByproduct.cmake:3 \(add_custom_command\):
add_custom_command called with BYPRODUCTS containing a "<". This character
is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadByproduct.cmake:4 \(add_custom_command\):
add_custom_command called with BYPRODUCTS containing a ">". This character
is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadByproduct.cmake:5 \(add_custom_command\):
add_custom_command called with BYPRODUCTS containing a "<". This character
is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadByproduct.cmake:6 \(add_custom_command\):
add_custom_command attempted to have a file
.*RunCMake/add_custom_command/f
in a source directory as an output of custom command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,6 @@
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
add_custom_command(OUTPUT a BYPRODUCTS "a#")
add_custom_command(OUTPUT b BYPRODUCTS "a<")
add_custom_command(OUTPUT c BYPRODUCTS "a>")
add_custom_command(OUTPUT d BYPRODUCTS "$<CONFIG>/#")
add_custom_command(OUTPUT e BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/f)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,36 @@
CMake Error at BadOutput.cmake:2 \(add_custom_command\):
add_custom_command called with OUTPUT containing a "#". This character is
not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadOutput.cmake:3 \(add_custom_command\):
add_custom_command called with OUTPUT containing a "<". This character is
not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadOutput.cmake:4 \(add_custom_command\):
add_custom_command called with OUTPUT containing a ">". This character is
not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadOutput.cmake:5 \(add_custom_command\):
add_custom_command called with OUTPUT containing a "<". This character is
not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadOutput.cmake:6 \(add_custom_command\):
add_custom_command attempted to have a file
.*RunCMake/add_custom_command/e
in a source directory as an output of custom command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,6 @@
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
add_custom_command(OUTPUT "a#" COMMAND a)
add_custom_command(OUTPUT "a<" COMMAND b)
add_custom_command(OUTPUT "a>" COMMAND c)
add_custom_command(OUTPUT "$<CONFIG>/#" COMMAND d)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/e COMMAND f)

View File

@ -4,6 +4,8 @@ run_cmake(AppendLiteralQuotes)
run_cmake(AppendNoOutput)
run_cmake(AppendNotOutput)
run_cmake(BadArgument)
run_cmake(BadByproduct)
run_cmake(BadOutput)
run_cmake(GeneratedProperty)
run_cmake(LiteralQuotes)
run_cmake(NoArguments)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,36 @@
CMake Error at BadByproduct.cmake:2 \(add_custom_target\):
add_custom_target called with BYPRODUCTS containing a "#". This character
is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadByproduct.cmake:3 \(add_custom_target\):
add_custom_target called with BYPRODUCTS containing a "<". This character
is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadByproduct.cmake:4 \(add_custom_target\):
add_custom_target called with BYPRODUCTS containing a ">". This character
is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadByproduct.cmake:5 \(add_custom_target\):
add_custom_target called with BYPRODUCTS containing a "<". This character
is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadByproduct.cmake:6 \(add_custom_target\):
add_custom_target attempted to have a file
.*RunCMake/add_custom_target/j
in a source directory as an output of custom command.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,6 @@
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
add_custom_target(a BYPRODUCTS "a#" COMMAND b)
add_custom_target(c BYPRODUCTS "a<" COMMAND d)
add_custom_target(e BYPRODUCTS "a>" COMMAND f)
add_custom_target(g BYPRODUCTS "$<CONFIG>/#" COMMAND h)
add_custom_target(i BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/j COMMAND k)

View File

@ -1,11 +1,12 @@
include(RunCMake)
run_cmake(CommandExpandsEmpty)
run_cmake(GeneratedProperty)
run_cmake(NoArguments)
run_cmake(BadByproduct)
run_cmake(BadTargetName)
run_cmake(ByproductsNoCommand)
run_cmake(CommandExpandsEmpty)
run_cmake(GeneratedProperty)
run_cmake(LiteralQuotes)
run_cmake(NoArguments)
run_cmake(UsesTerminalNoCommand)
function(run_TargetOrder)

View File

@ -278,6 +278,7 @@ CMAKE_CXX_SOURCES="\
cmCMakePolicyCommand \
cmCPackPropertiesGenerator \
cmCacheManager \
cmCheckCustomOutputs \
cmCommand \
cmCommandArgumentParserHelper \
cmCommands \