summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2014-11-05 20:37:52 (GMT)
committerBrad King <brad.king@kitware.com>2014-11-14 16:55:09 (GMT)
commitfe5d6e8c0f2e37bac0621a3b976d95c471891f38 (patch)
tree56d2a66bbf625ed8f3274baf3632aab2337dd6f1
parentad6ee426278ebaa9518af4573362a96b0544f4f7 (diff)
downloadCMake-fe5d6e8c0f2e37bac0621a3b976d95c471891f38.zip
CMake-fe5d6e8c0f2e37bac0621a3b976d95c471891f38.tar.gz
CMake-fe5d6e8c0f2e37bac0621a3b976d95c471891f38.tar.bz2
Add USES_TERMINAL option for custom commands
Teach the add_custom_command and add_custom_target commands a new USES_TERMINAL option. Use it to tell the generator to give the command direct access to the terminal if possible.
-rw-r--r--Help/command/add_custom_command.rst11
-rw-r--r--Help/command/add_custom_target.rst8
-rw-r--r--Source/cmAddCustomCommandCommand.cxx14
-rw-r--r--Source/cmAddCustomTargetCommand.cxx16
-rw-r--r--Source/cmCustomCommand.cxx17
-rw-r--r--Source/cmCustomCommand.h6
-rw-r--r--Source/cmMakefile.cxx19
-rw-r--r--Source/cmMakefile.h12
-rw-r--r--Tests/CustomCommand/CMakeLists.txt23
-rw-r--r--Tests/RunCMake/add_custom_command/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake1
-rw-r--r--Tests/RunCMake/add_custom_target/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt1
-rw-r--r--Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt4
-rw-r--r--Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake1
17 files changed, 123 insertions, 17 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 2d67b98..cb0746b 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -18,7 +18,8 @@ The first signature is for adding a custom command to produce an output::
[IMPLICIT_DEPENDS <lang1> depend1
[<lang2> depend2] ...]
[WORKING_DIRECTORY dir]
- [COMMENT comment] [VERBATIM] [APPEND])
+ [COMMENT comment]
+ [VERBATIM] [APPEND] [USES_TERMINAL])
This defines a command to generate specified ``OUTPUT`` file(s).
A target created in the same directory (``CMakeLists.txt`` file)
@@ -120,6 +121,11 @@ The options are:
as a file on disk it should be marked with the :prop_sf:`SYMBOLIC`
source file property.
+``USES_TERMINAL``
+ The command will be given direct access to the terminal if possible.
+ With the :generator:`Ninja` generator, this places the command in
+ the ``console`` pool.
+
``VERBATIM``
All arguments to the commands will be escaped properly for the
build tool so that the invoked command receives each argument
@@ -151,7 +157,8 @@ target is already built, the command will not execute.
COMMAND command1 [ARGS] [args1...]
[COMMAND command2 [ARGS] [args2...] ...]
[WORKING_DIRECTORY dir]
- [COMMENT comment] [VERBATIM])
+ [COMMENT comment]
+ [VERBATIM] [USES_TERMINAL])
This defines a new command that will be associated with building the
specified target. When the command will happen is determined by which
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
index 4f8e190..8b7472d 100644
--- a/Help/command/add_custom_target.rst
+++ b/Help/command/add_custom_target.rst
@@ -9,7 +9,8 @@ Add a target with no output so it will always be built.
[COMMAND command2 [args2...] ...]
[DEPENDS depend depend depend ... ]
[WORKING_DIRECTORY dir]
- [COMMENT comment] [VERBATIM]
+ [COMMENT comment]
+ [VERBATIM] [USES_TERMINAL]
[SOURCES src1 [src2...]])
Adds a target with the given name that executes the given commands.
@@ -74,6 +75,11 @@ The options are:
is platform specific because there is no protection of
tool-specific special characters.
+``USES_TERMINAL``
+ The command will be given direct access to the terminal if possible.
+ With the :generator:`Ninja` generator, this places the command in
+ the ``console`` pool.
+
``WORKING_DIRECTORY``
Execute the command with the given current working directory.
If it is a relative path it will be interpreted relative to the
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 2d19610..410f978 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -35,6 +35,7 @@ bool cmAddCustomCommandCommand
std::vector<std::string> depends, outputs, output;
bool verbatim = false;
bool append = false;
+ bool uses_terminal = false;
std::string implicit_depends_lang;
cmCustomCommand::ImplicitDependsList implicit_depends;
@@ -102,6 +103,10 @@ bool cmAddCustomCommandCommand
{
append = true;
}
+ else if(copy == "USES_TERMINAL")
+ {
+ uses_terminal = true;
+ }
else if(copy == "TARGET")
{
doing = doing_target;
@@ -312,7 +317,7 @@ bool cmAddCustomCommandCommand
this->Makefile->AddCustomCommandToTarget(target, no_depends,
commandLines, cctype,
comment, working.c_str(),
- escapeOldStyle);
+ escapeOldStyle, uses_terminal);
}
else if(target.empty())
{
@@ -321,7 +326,7 @@ bool cmAddCustomCommandCommand
main_dependency,
commandLines, comment,
working.c_str(), false,
- escapeOldStyle);
+ escapeOldStyle, uses_terminal);
// Add implicit dependency scanning requests if any were given.
if(!implicit_depends.empty())
@@ -346,6 +351,11 @@ bool cmAddCustomCommandCommand
}
}
}
+ else if (uses_terminal)
+ {
+ this->SetError("USES_TERMINAL may not be used with SOURCE signatures");
+ return false;
+ }
else
{
bool issueMessage = true;
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 64e76f3..fc4f8f1 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -48,6 +48,7 @@ bool cmAddCustomTargetCommand
std::vector<std::string> depends;
std::string working_directory;
bool verbatim = false;
+ bool uses_terminal = false;
std::string comment_buffer;
const char* comment = 0;
std::vector<std::string> sources;
@@ -93,6 +94,11 @@ bool cmAddCustomTargetCommand
doing = doing_nothing;
verbatim = true;
}
+ else if(copy == "USES_TERMINAL")
+ {
+ doing = doing_nothing;
+ uses_terminal = true;
+ }
else if (copy == "COMMENT")
{
doing = doing_comment;
@@ -221,12 +227,20 @@ bool cmAddCustomTargetCommand
cmSystemTools::CollapseFullPath(working_directory, build_dir);
}
+ if (commandLines.empty() && uses_terminal)
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "USES_TERMINAL may not be specified without any COMMAND");
+ return true;
+ }
+
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
cmTarget* target =
this->Makefile->AddUtilityCommand(targetName, excludeFromAll,
working_directory.c_str(), depends,
- commandLines, escapeOldStyle, comment);
+ commandLines, escapeOldStyle, comment,
+ uses_terminal);
// Add additional user-specified source files to the target.
target->AddSources(sources);
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index c161eb6..45369cc 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -22,6 +22,7 @@ cmCustomCommand::cmCustomCommand()
this->HaveComment = false;
this->EscapeOldStyle = true;
this->EscapeAllowMakeVars = false;
+ this->UsesTerminal = false;
}
//----------------------------------------------------------------------------
@@ -34,7 +35,8 @@ cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
WorkingDirectory(r.WorkingDirectory),
EscapeAllowMakeVars(r.EscapeAllowMakeVars),
EscapeOldStyle(r.EscapeOldStyle),
- Backtrace(r.Backtrace)
+ Backtrace(r.Backtrace),
+ UsesTerminal(r.UsesTerminal)
{
}
@@ -56,6 +58,7 @@ cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r)
this->EscapeOldStyle = r.EscapeOldStyle;
this->ImplicitDepends = r.ImplicitDepends;
this->Backtrace = r.Backtrace;
+ this->UsesTerminal = r.UsesTerminal;
return *this;
}
@@ -184,3 +187,15 @@ void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l)
this->ImplicitDepends.insert(this->ImplicitDepends.end(),
l.begin(), l.end());
}
+
+//----------------------------------------------------------------------------
+bool cmCustomCommand::GetUsesTerminal() const
+{
+ return this->UsesTerminal;
+}
+
+//----------------------------------------------------------------------------
+void cmCustomCommand::SetUsesTerminal(bool b)
+{
+ this->UsesTerminal = b;
+}
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 21dbefb..283a0e4 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -79,6 +79,11 @@ public:
void AppendImplicitDepends(ImplicitDependsList const&);
ImplicitDependsList const& GetImplicitDepends() const;
+ /** Set/Get whether this custom command should be given access to the
+ real console (if possible). */
+ bool GetUsesTerminal() const;
+ void SetUsesTerminal(bool b);
+
private:
std::vector<std::string> Outputs;
std::vector<std::string> Depends;
@@ -90,6 +95,7 @@ private:
bool EscapeOldStyle;
cmListFileBacktrace Backtrace;
ImplicitDependsList ImplicitDepends;
+ bool UsesTerminal;
};
#endif
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 8a8aadc..7e5e4e7 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -885,7 +885,8 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target,
cmTarget::CustomCommandType type,
const char* comment,
const char* workingDir,
- bool escapeOldStyle) const
+ bool escapeOldStyle,
+ bool uses_terminal) const
{
// Find the target to which to add the custom command.
cmTargets::iterator ti = this->Targets.find(target);
@@ -941,6 +942,7 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target,
commandLines, comment, workingDir);
cc.SetEscapeOldStyle(escapeOldStyle);
cc.SetEscapeAllowMakeVars(true);
+ cc.SetUsesTerminal(uses_terminal);
switch(type)
{
case cmTarget::PRE_BUILD:
@@ -964,7 +966,8 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
const char* comment,
const char* workingDir,
bool replace,
- bool escapeOldStyle)
+ bool escapeOldStyle,
+ bool uses_terminal)
{
// Make sure there is at least one output.
if(outputs.empty())
@@ -1071,6 +1074,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
comment, workingDir);
cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true);
+ cc->SetUsesTerminal(uses_terminal);
file->SetCustomCommand(cc);
this->UpdateOutputToSourceMap(outputs, file);
}
@@ -1119,13 +1123,15 @@ cmMakefile::AddCustomCommandToOutput(const std::string& output,
const char* comment,
const char* workingDir,
bool replace,
- bool escapeOldStyle)
+ bool escapeOldStyle,
+ bool uses_terminal)
{
std::vector<std::string> outputs;
outputs.push_back(output);
return this->AddCustomCommandToOutput(outputs, depends, main_dependency,
commandLines, comment, workingDir,
- replace, escapeOldStyle);
+ replace, escapeOldStyle,
+ uses_terminal);
}
//----------------------------------------------------------------------------
@@ -1242,7 +1248,8 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
const char* workingDirectory,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
- bool escapeOldStyle, const char* comment)
+ bool escapeOldStyle, const char* comment,
+ bool uses_terminal)
{
// Create a target instance for this utility.
cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
@@ -1269,7 +1276,7 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
no_main_dependency,
commandLines, comment,
workingDirectory, no_replace,
- escapeOldStyle);
+ escapeOldStyle, uses_terminal);
cmSourceFile* sf = target->AddSourceCMP0049(force);
// The output is not actually created so mark it symbolic.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 824513b..73c299e 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -174,7 +174,8 @@ public:
const cmCustomCommandLines& commandLines,
cmTarget::CustomCommandType type,
const char* comment, const char* workingDir,
- bool escapeOldStyle = true) const;
+ bool escapeOldStyle = true,
+ bool uses_terminal = false) const;
cmSourceFile* AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
@@ -182,7 +183,8 @@ public:
const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir,
bool replace = false,
- bool escapeOldStyle = true);
+ bool escapeOldStyle = true,
+ bool uses_terminal = false);
cmSourceFile* AddCustomCommandToOutput(
const std::string& output,
const std::vector<std::string>& depends,
@@ -190,7 +192,8 @@ public:
const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir,
bool replace = false,
- bool escapeOldStyle = true);
+ bool escapeOldStyle = true,
+ bool uses_terminal = false);
void AddCustomCommandOldStyle(const std::string& target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
@@ -237,7 +240,8 @@ public:
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines,
bool escapeOldStyle = true,
- const char* comment = 0);
+ const char* comment = 0,
+ bool uses_terminal = false);
/**
* Add a link library to the build.
diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt
index b97cd16..e260070 100644
--- a/Tests/CustomCommand/CMakeLists.txt
+++ b/Tests/CustomCommand/CMakeLists.txt
@@ -483,3 +483,26 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}")
add_library(NormDepends "${gen_file}")
+
+# Test that USES_TERMINAL is parsed correctly.
+# It seems much more difficult to test that USES_TERMINAL actually gives
+# the subprocess console access, as test output is piped through CTest,
+# and CTest itself might not be connected to the console.
+
+set(gen_file "${gen_path}/bar2.cxx")
+
+add_custom_command(
+ OUTPUT "${gen_file}"
+ DEPENDS "${gen_path}"
+ COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}"
+ VERBATIM
+ USES_TERMINAL
+)
+
+add_library(UseConsole "${gen_file}")
+
+add_custom_target(UseConsoleTarget ALL
+ COMMAND ${CMAKE_COMMAND} -E echo "Custom console target."
+ VERBATIM
+ USES_TERMINAL
+)
diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
index a692600..d0f429a 100644
--- a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake
@@ -6,3 +6,4 @@ run_cmake(BadArgument)
run_cmake(NoArguments)
run_cmake(NoOutputOrTarget)
run_cmake(OutputAndTarget)
+run_cmake(SourceUsesTerminal)
diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt
new file mode 100644
index 0000000..1a76c54
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at SourceUsesTerminal.cmake:1 \(add_custom_command\):
+ add_custom_command USES_TERMINAL may not be used with SOURCE signatures
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake b/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake
new file mode 100644
index 0000000..295fab1
--- /dev/null
+++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake
@@ -0,0 +1 @@
+add_custom_command(SOURCE t TARGET t USES_TERMINAL)
diff --git a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake
index 4e4a8ae..a612da9 100644
--- a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake
@@ -2,3 +2,4 @@ include(RunCMake)
run_cmake(NoArguments)
run_cmake(BadTargetName)
+run_cmake(UsesTerminalNoCommand)
diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt
new file mode 100644
index 0000000..beafa7c
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at UsesTerminalNoCommand.cmake:1 \(add_custom_target\):
+ USES_TERMINAL may not be specified without any COMMAND
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake
new file mode 100644
index 0000000..b0c207b
--- /dev/null
+++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake
@@ -0,0 +1 @@
+add_custom_target(MyTarget USES_TERMINAL)