Merge topic 'console-pool'

2d75d7e5 Help: Add notes for topic 'console-pool'
f42d86f0 Ninja: Implement USES_TERMINAL using the console pool if available
f281ae01 Ninja: Remove unused declaration
d5eae556 Ninja: factor out the test for console pool support
4d1fedf4 Give the interactive cache editor the USES_TERMINAL property
fe5d6e8c Add USES_TERMINAL option for custom commands
ad6ee426 Rename doing_verbatim to doing_nothing
This commit is contained in:
Brad King 2014-11-17 09:40:56 -05:00 committed by CMake Topic Stage
commit 444f61e044
25 changed files with 172 additions and 36 deletions

View File

@ -18,7 +18,8 @@ The first signature is for adding a custom command to produce an output::
[IMPLICIT_DEPENDS <lang1> depend1 [IMPLICIT_DEPENDS <lang1> depend1
[<lang2> depend2] ...] [<lang2> depend2] ...]
[WORKING_DIRECTORY dir] [WORKING_DIRECTORY dir]
[COMMENT comment] [VERBATIM] [APPEND]) [COMMENT comment]
[VERBATIM] [APPEND] [USES_TERMINAL])
This defines a command to generate specified ``OUTPUT`` file(s). This defines a command to generate specified ``OUTPUT`` file(s).
A target created in the same directory (``CMakeLists.txt`` file) 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` as a file on disk it should be marked with the :prop_sf:`SYMBOLIC`
source file property. 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`` ``VERBATIM``
All arguments to the commands will be escaped properly for the All arguments to the commands will be escaped properly for the
build tool so that the invoked command receives each argument 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 command1 [ARGS] [args1...]
[COMMAND command2 [ARGS] [args2...] ...] [COMMAND command2 [ARGS] [args2...] ...]
[WORKING_DIRECTORY dir] [WORKING_DIRECTORY dir]
[COMMENT comment] [VERBATIM]) [COMMENT comment]
[VERBATIM] [USES_TERMINAL])
This defines a new command that will be associated with building the This defines a new command that will be associated with building the
specified target. When the command will happen is determined by which specified target. When the command will happen is determined by which

View File

@ -9,7 +9,8 @@ Add a target with no output so it will always be built.
[COMMAND command2 [args2...] ...] [COMMAND command2 [args2...] ...]
[DEPENDS depend depend depend ... ] [DEPENDS depend depend depend ... ]
[WORKING_DIRECTORY dir] [WORKING_DIRECTORY dir]
[COMMENT comment] [VERBATIM] [COMMENT comment]
[VERBATIM] [USES_TERMINAL]
[SOURCES src1 [src2...]]) [SOURCES src1 [src2...]])
Adds a target with the given name that executes the given commands. 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 is platform specific because there is no protection of
tool-specific special characters. 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`` ``WORKING_DIRECTORY``
Execute the command with the given current working directory. Execute the command with the given current working directory.
If it is a relative path it will be interpreted relative to the If it is a relative path it will be interpreted relative to the

View File

@ -0,0 +1,8 @@
console-pool
------------
* The :command:`add_custom_command` and :command:`add_custom_target`
commands learned a new ``USES_TERMINAL`` option to request that
the command be given direct access to the terminal if possible.
The :generator:`Ninja` generator will places such commands in the
``console`` pool.

View File

@ -35,6 +35,7 @@ bool cmAddCustomCommandCommand
std::vector<std::string> depends, outputs, output; std::vector<std::string> depends, outputs, output;
bool verbatim = false; bool verbatim = false;
bool append = false; bool append = false;
bool uses_terminal = false;
std::string implicit_depends_lang; std::string implicit_depends_lang;
cmCustomCommand::ImplicitDependsList implicit_depends; cmCustomCommand::ImplicitDependsList implicit_depends;
@ -102,6 +103,10 @@ bool cmAddCustomCommandCommand
{ {
append = true; append = true;
} }
else if(copy == "USES_TERMINAL")
{
uses_terminal = true;
}
else if(copy == "TARGET") else if(copy == "TARGET")
{ {
doing = doing_target; doing = doing_target;
@ -312,7 +317,7 @@ bool cmAddCustomCommandCommand
this->Makefile->AddCustomCommandToTarget(target, no_depends, this->Makefile->AddCustomCommandToTarget(target, no_depends,
commandLines, cctype, commandLines, cctype,
comment, working.c_str(), comment, working.c_str(),
escapeOldStyle); escapeOldStyle, uses_terminal);
} }
else if(target.empty()) else if(target.empty())
{ {
@ -321,7 +326,7 @@ bool cmAddCustomCommandCommand
main_dependency, main_dependency,
commandLines, comment, commandLines, comment,
working.c_str(), false, working.c_str(), false,
escapeOldStyle); escapeOldStyle, uses_terminal);
// Add implicit dependency scanning requests if any were given. // Add implicit dependency scanning requests if any were given.
if(!implicit_depends.empty()) 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 else
{ {
bool issueMessage = true; bool issueMessage = true;

View File

@ -48,6 +48,7 @@ bool cmAddCustomTargetCommand
std::vector<std::string> depends; std::vector<std::string> depends;
std::string working_directory; std::string working_directory;
bool verbatim = false; bool verbatim = false;
bool uses_terminal = false;
std::string comment_buffer; std::string comment_buffer;
const char* comment = 0; const char* comment = 0;
std::vector<std::string> sources; std::vector<std::string> sources;
@ -59,7 +60,7 @@ bool cmAddCustomTargetCommand
doing_working_directory, doing_working_directory,
doing_comment, doing_comment,
doing_source, doing_source,
doing_verbatim doing_nothing
}; };
tdoing doing = doing_command; tdoing doing = doing_command;
@ -90,9 +91,14 @@ bool cmAddCustomTargetCommand
} }
else if(copy == "VERBATIM") else if(copy == "VERBATIM")
{ {
doing = doing_verbatim; doing = doing_nothing;
verbatim = true; verbatim = true;
} }
else if(copy == "USES_TERMINAL")
{
doing = doing_nothing;
uses_terminal = true;
}
else if (copy == "COMMENT") else if (copy == "COMMENT")
{ {
doing = doing_comment; doing = doing_comment;
@ -221,12 +227,20 @@ bool cmAddCustomTargetCommand
cmSystemTools::CollapseFullPath(working_directory, build_dir); 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. // Add the utility target to the makefile.
bool escapeOldStyle = !verbatim; bool escapeOldStyle = !verbatim;
cmTarget* target = cmTarget* target =
this->Makefile->AddUtilityCommand(targetName, excludeFromAll, this->Makefile->AddUtilityCommand(targetName, excludeFromAll,
working_directory.c_str(), depends, working_directory.c_str(), depends,
commandLines, escapeOldStyle, comment); commandLines, escapeOldStyle, comment,
uses_terminal);
// Add additional user-specified source files to the target. // Add additional user-specified source files to the target.
target->AddSources(sources); target->AddSources(sources);

View File

@ -22,6 +22,7 @@ cmCustomCommand::cmCustomCommand()
this->HaveComment = false; this->HaveComment = false;
this->EscapeOldStyle = true; this->EscapeOldStyle = true;
this->EscapeAllowMakeVars = false; this->EscapeAllowMakeVars = false;
this->UsesTerminal = false;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -34,7 +35,8 @@ cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
WorkingDirectory(r.WorkingDirectory), WorkingDirectory(r.WorkingDirectory),
EscapeAllowMakeVars(r.EscapeAllowMakeVars), EscapeAllowMakeVars(r.EscapeAllowMakeVars),
EscapeOldStyle(r.EscapeOldStyle), 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->EscapeOldStyle = r.EscapeOldStyle;
this->ImplicitDepends = r.ImplicitDepends; this->ImplicitDepends = r.ImplicitDepends;
this->Backtrace = r.Backtrace; this->Backtrace = r.Backtrace;
this->UsesTerminal = r.UsesTerminal;
return *this; return *this;
} }
@ -184,3 +187,15 @@ void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l)
this->ImplicitDepends.insert(this->ImplicitDepends.end(), this->ImplicitDepends.insert(this->ImplicitDepends.end(),
l.begin(), l.end()); l.begin(), l.end());
} }
//----------------------------------------------------------------------------
bool cmCustomCommand::GetUsesTerminal() const
{
return this->UsesTerminal;
}
//----------------------------------------------------------------------------
void cmCustomCommand::SetUsesTerminal(bool b)
{
this->UsesTerminal = b;
}

View File

@ -79,6 +79,11 @@ public:
void AppendImplicitDepends(ImplicitDependsList const&); void AppendImplicitDepends(ImplicitDependsList const&);
ImplicitDependsList const& GetImplicitDepends() 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: private:
std::vector<std::string> Outputs; std::vector<std::string> Outputs;
std::vector<std::string> Depends; std::vector<std::string> Depends;
@ -90,6 +95,7 @@ private:
bool EscapeOldStyle; bool EscapeOldStyle;
cmListFileBacktrace Backtrace; cmListFileBacktrace Backtrace;
ImplicitDependsList ImplicitDepends; ImplicitDependsList ImplicitDepends;
bool UsesTerminal;
}; };
#endif #endif

View File

@ -2207,7 +2207,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
= this->CreateGlobalTarget(this->GetPackageTargetName(), = this->CreateGlobalTarget(this->GetPackageTargetName(),
"Run CPack packaging tool...", "Run CPack packaging tool...",
&cpackCommandLines, depends, &cpackCommandLines, depends,
workingDir.c_str()); workingDir.c_str(), /*uses_terminal*/false);
} }
// CPack source // CPack source
const char* packageSourceTargetName = this->GetPackageSourceTargetName(); const char* packageSourceTargetName = this->GetPackageSourceTargetName();
@ -2231,8 +2231,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
= this->CreateGlobalTarget(packageSourceTargetName, = this->CreateGlobalTarget(packageSourceTargetName,
"Run CPack packaging tool for source...", "Run CPack packaging tool for source...",
&cpackCommandLines, depends, &cpackCommandLines, depends,
workingDir.c_str() workingDir.c_str(), /*uses_terminal*/false);
);
} }
} }
@ -2257,7 +2256,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
cpackCommandLines.push_back(singleLine); cpackCommandLines.push_back(singleLine);
(*targets)[this->GetTestTargetName()] (*targets)[this->GetTestTargetName()]
= this->CreateGlobalTarget(this->GetTestTargetName(), = this->CreateGlobalTarget(this->GetTestTargetName(),
"Running tests...", &cpackCommandLines, depends, 0); "Running tests...", &cpackCommandLines, depends, 0,
/*uses_terminal*/false);
} }
//Edit Cache //Edit Cache
@ -2280,7 +2280,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)[editCacheTargetName] = (*targets)[editCacheTargetName] =
this->CreateGlobalTarget( this->CreateGlobalTarget(
editCacheTargetName, "Running CMake cache editor...", editCacheTargetName, "Running CMake cache editor...",
&cpackCommandLines, depends, 0); &cpackCommandLines, depends, 0, /*uses_terminal*/true);
} }
else else
{ {
@ -2293,7 +2293,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
this->CreateGlobalTarget( this->CreateGlobalTarget(
editCacheTargetName, editCacheTargetName,
"No interactive CMake dialog available...", "No interactive CMake dialog available...",
&cpackCommandLines, depends, 0); &cpackCommandLines, depends, 0, /*uses_terminal*/false);
} }
} }
@ -2312,7 +2312,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)[rebuildCacheTargetName] = (*targets)[rebuildCacheTargetName] =
this->CreateGlobalTarget( this->CreateGlobalTarget(
rebuildCacheTargetName, "Running CMake to regenerate build system...", rebuildCacheTargetName, "Running CMake to regenerate build system...",
&cpackCommandLines, depends, 0); &cpackCommandLines, depends, 0, /*uses_terminal*/false);
} }
//Install //Install
@ -2352,7 +2352,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)["list_install_components"] (*targets)["list_install_components"]
= this->CreateGlobalTarget("list_install_components", = this->CreateGlobalTarget("list_install_components",
ostr.str().c_str(), ostr.str().c_str(),
&cpackCommandLines, depends, 0); &cpackCommandLines, depends, 0, /*uses_terminal*/false);
} }
std::string cmd = cmakeCommand; std::string cmd = cmakeCommand;
cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.erase(cpackCommandLines.begin(),
@ -2393,7 +2393,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)[this->GetInstallTargetName()] = (*targets)[this->GetInstallTargetName()] =
this->CreateGlobalTarget( this->CreateGlobalTarget(
this->GetInstallTargetName(), "Install the project...", this->GetInstallTargetName(), "Install the project...",
&cpackCommandLines, depends, 0); &cpackCommandLines, depends, 0, /*uses_terminal*/false);
// install_local // install_local
if(const char* install_local = this->GetInstallLocalTargetName()) if(const char* install_local = this->GetInstallLocalTargetName())
@ -2409,7 +2409,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)[install_local] = (*targets)[install_local] =
this->CreateGlobalTarget( this->CreateGlobalTarget(
install_local, "Installing only the local directory...", install_local, "Installing only the local directory...",
&cpackCommandLines, depends, 0); &cpackCommandLines, depends, 0, /*uses_terminal*/false);
} }
// install_strip // install_strip
@ -2426,7 +2426,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
(*targets)[install_strip] = (*targets)[install_strip] =
this->CreateGlobalTarget( this->CreateGlobalTarget(
install_strip, "Installing the project stripped...", install_strip, "Installing the project stripped...",
&cpackCommandLines, depends, 0); &cpackCommandLines, depends, 0, /*uses_terminal*/false);
} }
} }
} }
@ -2500,7 +2500,8 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
const std::string& name, const char* message, const std::string& name, const char* message,
const cmCustomCommandLines* commandLines, const cmCustomCommandLines* commandLines,
std::vector<std::string> depends, std::vector<std::string> depends,
const char* workingDirectory) const char* workingDirectory,
bool uses_terminal)
{ {
// Package // Package
cmTarget target; cmTarget target;
@ -2513,6 +2514,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
// Store the custom command in the target. // Store the custom command in the target.
cmCustomCommand cc(0, no_outputs, no_depends, *commandLines, 0, cmCustomCommand cc(0, no_outputs, no_depends, *commandLines, 0,
workingDirectory); workingDirectory);
cc.SetUsesTerminal(uses_terminal);
target.AddPostBuildCommand(cc); target.AddPostBuildCommand(cc);
target.SetProperty("EchoString", message); target.SetProperty("EchoString", message);
std::vector<std::string>::iterator dit; std::vector<std::string>::iterator dit;

View File

@ -385,7 +385,8 @@ protected:
void CreateDefaultGlobalTargets(cmTargets* targets); void CreateDefaultGlobalTargets(cmTargets* targets);
cmTarget CreateGlobalTarget(const std::string& name, const char* message, cmTarget CreateGlobalTarget(const std::string& name, const char* message,
const cmCustomCommandLines* commandLines, const cmCustomCommandLines* commandLines,
std::vector<std::string> depends, const char* workingDir); std::vector<std::string> depends, const char* workingDir,
bool uses_terminal);
bool NeedSymbolicMark; bool NeedSymbolicMark;
bool UseLinkScript; bool UseLinkScript;

View File

@ -250,6 +250,7 @@ void
cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
const std::string& description, const std::string& description,
const std::string& comment, const std::string& comment,
bool uses_terminal,
const cmNinjaDeps& outputs, const cmNinjaDeps& outputs,
const cmNinjaDeps& deps, const cmNinjaDeps& deps,
const cmNinjaDeps& orderOnly) const cmNinjaDeps& orderOnly)
@ -266,6 +267,10 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
cmNinjaVars vars; cmNinjaVars vars;
vars["COMMAND"] = cmd; vars["COMMAND"] = cmd;
vars["DESC"] = EncodeLiteral(description); vars["DESC"] = EncodeLiteral(description);
if (uses_terminal && SupportsConsolePool())
{
vars["pool"] = "console";
}
this->WriteBuild(*this->BuildFileStream, this->WriteBuild(*this->BuildFileStream,
comment, comment,
@ -826,6 +831,7 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
std::copy(i->second.begin(), i->second.end(), std::back_inserter(deps)); std::copy(i->second.begin(), i->second.end(), std::back_inserter(deps));
WriteCustomCommandBuild(/*command=*/"", /*description=*/"", WriteCustomCommandBuild(/*command=*/"", /*description=*/"",
"Assume dependencies for generated source file.", "Assume dependencies for generated source file.",
/*uses_terminal*/false,
cmNinjaDeps(1, i->first), deps); cmNinjaDeps(1, i->first), deps);
} }
} }
@ -1141,9 +1147,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
cmNinjaVars variables; cmNinjaVars variables;
// Use 'console' pool to get non buffered output of the CMake re-run call // Use 'console' pool to get non buffered output of the CMake re-run call
// Available since Ninja 1.5 // Available since Ninja 1.5
if(cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, if(SupportsConsolePool())
ninjaVersion().c_str(),
"1.5") == false)
{ {
variables["pool"] = "console"; variables["pool"] = "console";
} }
@ -1185,6 +1189,12 @@ std::string cmGlobalNinjaGenerator::ninjaVersion() const
return version; return version;
} }
bool cmGlobalNinjaGenerator::SupportsConsolePool() const
{
return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
ninjaVersion().c_str(), "1.5") == false;
}
void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
{ {
WriteRule(*this->RulesFileStream, WriteRule(*this->RulesFileStream,

View File

@ -103,6 +103,7 @@ public:
void WriteCustomCommandBuild(const std::string& command, void WriteCustomCommandBuild(const std::string& command,
const std::string& description, const std::string& description,
const std::string& comment, const std::string& comment,
bool uses_terminal,
const cmNinjaDeps& outputs, const cmNinjaDeps& outputs,
const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& deps = cmNinjaDeps(),
const cmNinjaDeps& orderOnly = cmNinjaDeps()); const cmNinjaDeps& orderOnly = cmNinjaDeps());
@ -299,6 +300,9 @@ public:
virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
std::string ninjaVersion() const; std::string ninjaVersion() const;
bool SupportsConsolePool() const;
protected: protected:
/// Overloaded methods. @see cmGlobalGenerator::Generate() /// Overloaded methods. @see cmGlobalGenerator::Generate()

View File

@ -468,6 +468,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
this->BuildCommandLine(cmdLines), this->BuildCommandLine(cmdLines),
this->ConstructComment(ccg), this->ConstructComment(ccg),
"Custom command for " + ninjaOutputs[0], "Custom command for " + ninjaOutputs[0],
cc->GetUsesTerminal(),
ninjaOutputs, ninjaOutputs,
ninjaDeps, ninjaDeps,
orderOnlyDeps); orderOnlyDeps);

View File

@ -885,7 +885,8 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target,
cmTarget::CustomCommandType type, cmTarget::CustomCommandType type,
const char* comment, const char* comment,
const char* workingDir, const char* workingDir,
bool escapeOldStyle) const bool escapeOldStyle,
bool uses_terminal) const
{ {
// Find the target to which to add the custom command. // Find the target to which to add the custom command.
cmTargets::iterator ti = this->Targets.find(target); cmTargets::iterator ti = this->Targets.find(target);
@ -941,6 +942,7 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target,
commandLines, comment, workingDir); commandLines, comment, workingDir);
cc.SetEscapeOldStyle(escapeOldStyle); cc.SetEscapeOldStyle(escapeOldStyle);
cc.SetEscapeAllowMakeVars(true); cc.SetEscapeAllowMakeVars(true);
cc.SetUsesTerminal(uses_terminal);
switch(type) switch(type)
{ {
case cmTarget::PRE_BUILD: case cmTarget::PRE_BUILD:
@ -964,7 +966,8 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
const char* comment, const char* comment,
const char* workingDir, const char* workingDir,
bool replace, bool replace,
bool escapeOldStyle) bool escapeOldStyle,
bool uses_terminal)
{ {
// Make sure there is at least one output. // Make sure there is at least one output.
if(outputs.empty()) if(outputs.empty())
@ -1071,6 +1074,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
comment, workingDir); comment, workingDir);
cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true); cc->SetEscapeAllowMakeVars(true);
cc->SetUsesTerminal(uses_terminal);
file->SetCustomCommand(cc); file->SetCustomCommand(cc);
this->UpdateOutputToSourceMap(outputs, file); this->UpdateOutputToSourceMap(outputs, file);
} }
@ -1119,13 +1123,15 @@ cmMakefile::AddCustomCommandToOutput(const std::string& output,
const char* comment, const char* comment,
const char* workingDir, const char* workingDir,
bool replace, bool replace,
bool escapeOldStyle) bool escapeOldStyle,
bool uses_terminal)
{ {
std::vector<std::string> outputs; std::vector<std::string> outputs;
outputs.push_back(output); outputs.push_back(output);
return this->AddCustomCommandToOutput(outputs, depends, main_dependency, return this->AddCustomCommandToOutput(outputs, depends, main_dependency,
commandLines, comment, workingDir, commandLines, comment, workingDir,
replace, escapeOldStyle); replace, escapeOldStyle,
uses_terminal);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1242,7 +1248,8 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
const char* workingDirectory, const char* workingDirectory,
const std::vector<std::string>& depends, const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, const cmCustomCommandLines& commandLines,
bool escapeOldStyle, const char* comment) bool escapeOldStyle, const char* comment,
bool uses_terminal)
{ {
// Create a target instance for this utility. // Create a target instance for this utility.
cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName); cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
@ -1269,7 +1276,7 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
no_main_dependency, no_main_dependency,
commandLines, comment, commandLines, comment,
workingDirectory, no_replace, workingDirectory, no_replace,
escapeOldStyle); escapeOldStyle, uses_terminal);
cmSourceFile* sf = target->AddSourceCMP0049(force); cmSourceFile* sf = target->AddSourceCMP0049(force);
// The output is not actually created so mark it symbolic. // The output is not actually created so mark it symbolic.

View File

@ -174,7 +174,8 @@ public:
const cmCustomCommandLines& commandLines, const cmCustomCommandLines& commandLines,
cmTarget::CustomCommandType type, cmTarget::CustomCommandType type,
const char* comment, const char* workingDir, const char* comment, const char* workingDir,
bool escapeOldStyle = true) const; bool escapeOldStyle = true,
bool uses_terminal = false) const;
cmSourceFile* AddCustomCommandToOutput( cmSourceFile* AddCustomCommandToOutput(
const std::vector<std::string>& outputs, const std::vector<std::string>& outputs,
const std::vector<std::string>& depends, const std::vector<std::string>& depends,
@ -182,7 +183,8 @@ public:
const cmCustomCommandLines& commandLines, const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir, const char* comment, const char* workingDir,
bool replace = false, bool replace = false,
bool escapeOldStyle = true); bool escapeOldStyle = true,
bool uses_terminal = false);
cmSourceFile* AddCustomCommandToOutput( cmSourceFile* AddCustomCommandToOutput(
const std::string& output, const std::string& output,
const std::vector<std::string>& depends, const std::vector<std::string>& depends,
@ -190,7 +192,8 @@ public:
const cmCustomCommandLines& commandLines, const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir, const char* comment, const char* workingDir,
bool replace = false, bool replace = false,
bool escapeOldStyle = true); bool escapeOldStyle = true,
bool uses_terminal = false);
void AddCustomCommandOldStyle(const std::string& target, void AddCustomCommandOldStyle(const std::string& target,
const std::vector<std::string>& outputs, const std::vector<std::string>& outputs,
const std::vector<std::string>& depends, const std::vector<std::string>& depends,
@ -237,7 +240,8 @@ public:
const std::vector<std::string>& depends, const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, const cmCustomCommandLines& commandLines,
bool escapeOldStyle = true, bool escapeOldStyle = true,
const char* comment = 0); const char* comment = 0,
bool uses_terminal = false);
/** /**
* Add a link library to the build. * Add a link library to the build.

View File

@ -116,7 +116,6 @@ protected:
void WriteObjectBuildStatements(); void WriteObjectBuildStatements();
void WriteObjectBuildStatement(cmSourceFile const* source, void WriteObjectBuildStatement(cmSourceFile const* source,
bool writeOrderDependsTargetForTarget); bool writeOrderDependsTargetForTarget);
void WriteCustomCommandBuildStatement(cmCustomCommand *cc);
cmNinjaDeps GetObjects() const cmNinjaDeps GetObjects() const
{ return this->Objects; } { return this->Objects; }

View File

@ -35,6 +35,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
&this->GetTarget()->GetPostBuildCommands() &this->GetTarget()->GetPostBuildCommands()
}; };
bool uses_terminal = false;
for (unsigned i = 0; i != 2; ++i) { for (unsigned i = 0; i != 2; ++i) {
for (std::vector<cmCustomCommand>::const_iterator for (std::vector<cmCustomCommand>::const_iterator
ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) { ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) {
@ -42,6 +44,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
this->GetMakefile()); this->GetMakefile());
this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps); this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps);
this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands); this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands);
if (ci->GetUsesTerminal())
uses_terminal = true;
} }
} }
@ -110,6 +114,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
command, command,
desc, desc,
"Utility command for " + this->GetTargetName(), "Utility command for " + this->GetTargetName(),
uses_terminal,
cmNinjaDeps(1, utilCommandName), cmNinjaDeps(1, utilCommandName),
deps); deps);

View File

@ -483,3 +483,26 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}") COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}")
add_library(NormDepends "${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
)

View File

@ -6,3 +6,4 @@ run_cmake(BadArgument)
run_cmake(NoArguments) run_cmake(NoArguments)
run_cmake(NoOutputOrTarget) run_cmake(NoOutputOrTarget)
run_cmake(OutputAndTarget) run_cmake(OutputAndTarget)
run_cmake(SourceUsesTerminal)

View File

@ -0,0 +1 @@
1

View File

@ -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\)

View File

@ -0,0 +1 @@
add_custom_command(SOURCE t TARGET t USES_TERMINAL)

View File

@ -2,3 +2,4 @@ include(RunCMake)
run_cmake(NoArguments) run_cmake(NoArguments)
run_cmake(BadTargetName) run_cmake(BadTargetName)
run_cmake(UsesTerminalNoCommand)

View File

@ -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\)

View File

@ -0,0 +1 @@
add_custom_target(MyTarget USES_TERMINAL)