summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2006-09-28 15:30:49 (GMT)
committerBrad King <brad.king@kitware.com>2006-09-28 15:30:49 (GMT)
commitd01b6f12819c4d8aec189ae3eebfd1779565bbf2 (patch)
tree90a04b304477a20c1adbc46b5ee2d892e4aae64b
parent16f8da8b1443b7ebb315f40aa1ae199d87f211de (diff)
downloadCMake-d01b6f12819c4d8aec189ae3eebfd1779565bbf2.zip
CMake-d01b6f12819c4d8aec189ae3eebfd1779565bbf2.tar.gz
CMake-d01b6f12819c4d8aec189ae3eebfd1779565bbf2.tar.bz2
ENH: Added VERBATIM option to ADD_CUSTOM_COMMAND and ADD_CUSTOM_TARGET commands. This option enables full escaping of custom command arguments on all platforms. See bug#3786.
-rw-r--r--Source/cmAddCustomCommandCommand.cxx22
-rw-r--r--Source/cmAddCustomCommandCommand.h14
-rw-r--r--Source/cmAddCustomTargetCommand.cxx12
-rw-r--r--Source/cmAddCustomTargetCommand.h14
-rw-r--r--Source/cmMakefile.cxx17
-rw-r--r--Source/cmMakefile.h12
-rw-r--r--Tests/CustomCommand/CMakeLists.txt34
-rw-r--r--Tests/CustomCommand/check_command_line.c.in3
8 files changed, 102 insertions, 26 deletions
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 4f6df9e..3c37d4b 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -35,6 +35,7 @@ bool cmAddCustomCommandCommand::InitialPass(
std::string source, target, comment, main_dependency,
working;
std::vector<std::string> depends, outputs, output;
+ bool verbatim = false;
// Accumulate one command line at a time.
cmCustomCommandLine currentLine;
@@ -90,6 +91,10 @@ bool cmAddCustomCommandCommand::InitialPass(
{
cctype = cmTarget::POST_BUILD;
}
+ else if(copy == "VERBATIM")
+ {
+ verbatim = true;
+ }
else if(copy == "TARGET")
{
doing = doing_target;
@@ -211,28 +216,31 @@ bool cmAddCustomCommandCommand::InitialPass(
}
// Choose which mode of the command to use.
+ bool escapeOldStyle = !verbatim;
if(source.empty() && output.empty())
{
// Source is empty, use the target.
std::vector<std::string> no_depends;
this->Makefile->AddCustomCommandToTarget(target.c_str(), no_depends,
- commandLines, cctype,
- comment.c_str(), working.c_str());
+ commandLines, cctype,
+ comment.c_str(), working.c_str(),
+ escapeOldStyle);
}
else if(target.empty())
{
// Target is empty, use the output.
this->Makefile->AddCustomCommandToOutput(output, depends,
- main_dependency.c_str(),
- commandLines, comment.c_str(),
- working.c_str());
+ main_dependency.c_str(),
+ commandLines, comment.c_str(),
+ working.c_str(), false,
+ escapeOldStyle);
}
else
{
// Use the old-style mode for backward compatibility.
this->Makefile->AddCustomCommandOldStyle(target.c_str(), outputs, depends,
- source.c_str(), commandLines,
- comment.c_str());
+ source.c_str(), commandLines,
+ comment.c_str());
}
return true;
}
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
index bacce8f..73bd881 100644
--- a/Source/cmAddCustomCommandCommand.h
+++ b/Source/cmAddCustomCommandCommand.h
@@ -72,7 +72,7 @@ public:
" [MAIN_DEPENDENCY depend]\n"
" [DEPENDS [depends...]]\n"
" [WORKING_DIRECTORY dir]\n"
- " [COMMENT comment])\n"
+ " [COMMENT comment] [VERBATIM])\n"
"This defines a new command that can be executed during the build "
"process. The outputs named should be listed as source files in the "
"target for which they are to be generated. "
@@ -93,7 +93,7 @@ public:
" COMMAND command1 [ARGS] [args1...]\n"
" [COMMAND command2 [ARGS] [args2...] ...]\n"
" [WORKING_DIRECTORY dir]\n"
- " [COMMENT comment])\n"
+ " [COMMENT comment] [VERBATIM])\n"
"This defines a new command that will be associated with "
"building the specified target. When the command will "
"happen is determined by which of the following is specified:\n"
@@ -104,7 +104,15 @@ public:
"Studio 7 or later. For all other generators PRE_BUILD "
"will be treated as PRE_LINK. "
"If WORKING_DIRECTORY is specified the command will be executed "
- "in the directory given.";
+ "in the directory given.\n"
+ "If VERBATIM is given then all the arguments to the commands will be "
+ "passed exactly as specified no matter the build tool used. "
+ "Note that one level of escapes is still used by the CMake language "
+ "processor before ADD_CUSTOM_TARGET even sees the arguments. "
+ "Use of VERBATIM is recommended as it enables correct behavior. "
+ "When VERBATIM is not given the behavior is platform specific. "
+ "In the future VERBATIM may be enabled by default. The only reason "
+ "it is an option is to preserve compatibility with older CMake code.";
}
cmTypeMacro(cmAddCustomCommandCommand, cmCommand);
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index ccdc8a9..d9879cf 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -58,12 +58,14 @@ bool cmAddCustomTargetCommand::InitialPass(
// Accumulate dependencies.
std::vector<std::string> depends;
std::string working_directory;
+ bool verbatim = false;
// Keep track of parser state.
enum tdoing {
doing_command,
doing_depends,
- doing_working_directory
+ doing_working_directory,
+ doing_verbatim
};
tdoing doing = doing_command;
@@ -92,6 +94,11 @@ bool cmAddCustomTargetCommand::InitialPass(
{
doing = doing_working_directory;
}
+ else if(copy == "VERBATIM")
+ {
+ doing = doing_verbatim;
+ verbatim = true;
+ }
else if(copy == "COMMAND")
{
doing = doing_command;
@@ -141,10 +148,11 @@ bool cmAddCustomTargetCommand::InitialPass(
}
// Add the utility target to the makefile.
+ bool escapeOldStyle = !verbatim;
const char* no_output = 0;
this->Makefile->AddUtilityCommand(args[0].c_str(), all, no_output,
working_directory.c_str(), depends,
- commandLines);
+ commandLines, escapeOldStyle);
return true;
}
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
index d6b38e3..a8ed7c4 100644
--- a/Source/cmAddCustomTargetCommand.h
+++ b/Source/cmAddCustomTargetCommand.h
@@ -65,8 +65,8 @@ public:
return
" ADD_CUSTOM_TARGET(Name [ALL] [command1 [args1...]]\n"
" [COMMAND command2 [args2...] ...]\n"
- " [DEPENDS depend depend depend ... ])\n"
- " [WORKING_DIRECTORY dir]\n"
+ " [DEPENDS depend depend depend ... ]\n"
+ " [WORKING_DIRECTORY dir] [VERBATIM])\n"
"Adds a target with the given name that executes the given commands. "
"The target has no output file and is ALWAYS CONSIDERED OUT OF DATE "
"even if the commands try to create a file with the name of the "
@@ -82,7 +82,15 @@ public:
"If WORKING_DIRECTORY is set, then the command will be run in that "
"directory. "
"Dependencies listed with the DEPENDS argument may reference files "
- "and outputs of custom commands created with ADD_CUSTOM_COMMAND.";
+ "and outputs of custom commands created with ADD_CUSTOM_COMMAND.\n"
+ "If VERBATIM is given then all the arguments to the commands will be "
+ "passed exactly as specified no matter the build tool used. "
+ "Note that one level of escapes is still used by the CMake language "
+ "processor before ADD_CUSTOM_TARGET even sees the arguments. "
+ "Use of VERBATIM is recommended as it enables correct behavior. "
+ "When VERBATIM is not given the behavior is platform specific. "
+ "In the future VERBATIM may be enabled by default. The only reason "
+ "it is an option is to preserve compatibility with older CMake code.";
}
cmTypeMacro(cmAddCustomTargetCommand, cmCommand);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 1e1b15f..38be4ca 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -554,7 +554,8 @@ cmMakefile::AddCustomCommandToTarget(const char* target,
const cmCustomCommandLines& commandLines,
cmTarget::CustomCommandType type,
const char* comment,
- const char* workingDir)
+ const char* workingDir,
+ bool escapeOldStyle)
{
// Find the target to which to add the custom command.
cmTargets::iterator ti = this->Targets.find(target);
@@ -563,6 +564,7 @@ cmMakefile::AddCustomCommandToTarget(const char* target,
// Add the command to the appropriate build step for the target.
std::vector<std::string> no_output;
cmCustomCommand cc(no_output, depends, commandLines, comment, workingDir);
+ cc.SetEscapeOldStyle(escapeOldStyle);
switch(type)
{
case cmTarget::PRE_BUILD:
@@ -598,7 +600,8 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
const cmCustomCommandLines& commandLines,
const char* comment,
const char* workingDir,
- bool replace)
+ bool replace,
+ bool escapeOldStyle)
{
// Make sure there is at least one output.
if(outputs.empty())
@@ -686,6 +689,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
cmCustomCommand* cc =
new cmCustomCommand(outputs, depends2, commandLines,
comment, workingDir);
+ cc->SetEscapeOldStyle(escapeOldStyle);
file->SetCustomCommand(cc);
}
}
@@ -698,13 +702,14 @@ cmMakefile::AddCustomCommandToOutput(const char* output,
const cmCustomCommandLines& commandLines,
const char* comment,
const char* workingDir,
- bool replace)
+ bool replace,
+ bool escapeOldStyle)
{
std::vector<std::string> outputs;
outputs.push_back(output);
this->AddCustomCommandToOutput(outputs, depends, main_dependency,
commandLines, comment, workingDir,
- replace);
+ replace, escapeOldStyle);
}
//----------------------------------------------------------------------------
@@ -819,7 +824,8 @@ void cmMakefile::AddUtilityCommand(const char* utilityName, bool all,
const char* output,
const char* workingDirectory,
const std::vector<std::string>& depends,
- const cmCustomCommandLines& commandLines)
+ const cmCustomCommandLines& commandLines,
+ bool escapeOldStyle)
{
// Create a target instance for this utility.
cmTarget target;
@@ -833,6 +839,7 @@ void cmMakefile::AddUtilityCommand(const char* utilityName, bool all,
outputs.push_back(output);
}
cmCustomCommand cc(outputs, depends, commandLines, 0, workingDirectory);
+ cc.SetEscapeOldStyle(escapeOldStyle);
target.GetPostBuildCommands().push_back(cc);
// Add the target to the set of targets.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 2cb8f8f..e4eae42 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -143,19 +143,22 @@ public:
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
cmTarget::CustomCommandType type,
- const char* comment, const char* workingDir);
+ const char* comment, const char* workingDir,
+ bool escapeOldStyle = true);
void AddCustomCommandToOutput(const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
const char* main_dependency,
const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir,
- bool replace = false);
+ bool replace = false,
+ bool escapeOldStyle = true);
void AddCustomCommandToOutput(const char* output,
const std::vector<std::string>& depends,
const char* main_dependency,
const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir,
- bool replace = false);
+ bool replace = false,
+ bool escapeOldStyle = true);
void AddCustomCommandOldStyle(const char* target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
@@ -192,7 +195,8 @@ public:
const char* output,
const char* workingDirectory,
const std::vector<std::string>& depends,
- const cmCustomCommandLines& commandLines);
+ const cmCustomCommandLines& commandLines,
+ bool escapeOldStyle = true);
/**
* Add a link library to the build.
diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt
index 3af8540..f50de52 100644
--- a/Tests/CustomCommand/CMakeLists.txt
+++ b/Tests/CustomCommand/CMakeLists.txt
@@ -176,6 +176,17 @@ SET(CHECK_ARGS
double\"quote
"\\;semi-colons\\;"
"semi\\;colon"
+ `back-ticks`
+ back`tick
+ "(parens)"
+ "(lparen"
+ "rparen)"
+ $dollar-signs$
+ dollar$sign
+ &ampersands&
+ amper&sand
+ \@two-ats\@
+ one@at
"c:/posix/path/with space"
"c:\\windows\\path\\with space"
"'single quotes with space'"
@@ -184,6 +195,17 @@ SET(CHECK_ARGS
"double\"quote with space"
"\\;semi-colons with space\\;"
"semi\\;colon with space"
+ "`back-ticks` with space"
+ "back`tick with space"
+ "(parens) with space"
+ "(lparen with space"
+ "rparen) with space"
+ "$dollar-signs$ with space"
+ "dollar$sign with space"
+ "&ampersands& with space"
+ "amper&sand with space"
+ "\@two-ats\@ with space"
+ "one@at with space"
)
FOREACH(arg ${CHECK_ARGS})
SET(ARG "${arg}")
@@ -199,8 +221,18 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/check_command_line.c.in
@ONLY IMMEDIATE)
ADD_EXECUTABLE(check_command_line
${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c)
-ADD_CUSTOM_TARGET(do_check_command_line #ALL
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
+ COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/check_command_line
+ ${CHECK_ARGS}
+ VERBATIM
+ COMMENT "Checking custom command line escapes"
+ )
+ADD_CUSTOM_TARGET(do_check_command_line ALL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
+ COMMAND ${CMAKE_COMMAND} -E echo "Checking custom target command escapes"
COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/check_command_line
${CHECK_ARGS}
+ VERBATIM
)
ADD_DEPENDENCIES(do_check_command_line check_command_line)
diff --git a/Tests/CustomCommand/check_command_line.c.in b/Tests/CustomCommand/check_command_line.c.in
index a4dbe22..71d5278 100644
--- a/Tests/CustomCommand/check_command_line.c.in
+++ b/Tests/CustomCommand/check_command_line.c.in
@@ -20,7 +20,7 @@ int main(int argc, const char* argv[])
}
else
{
- printf("[%s]\n", *a);
+ /*printf("[%s]\n", *a);*/
}
}
if(*a || *e)
@@ -28,5 +28,6 @@ int main(int argc, const char* argv[])
fprintf(stderr, "Number of arguments does not match expected.\n");
return 1;
}
+ printf("Command line escapes work!\n");
return 0;
}