cmake/Source/cmNinjaUtilityTargetGenerator.cxx

159 lines
5.7 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2012-04-19 19:04:21 +03:00
#include "cmNinjaUtilityTargetGenerator.h"
2016-07-09 11:21:54 +02:00
2012-04-19 19:04:21 +03:00
#include "cmCustomCommand.h"
2016-07-09 11:21:54 +02:00
#include "cmCustomCommandGenerator.h"
2012-04-19 19:04:21 +03:00
#include "cmGeneratedFileStream.h"
2016-10-30 18:24:19 +01:00
#include "cmGeneratorTarget.h"
2012-04-19 19:04:21 +03:00
#include "cmGlobalNinjaGenerator.h"
2016-10-30 18:24:19 +01:00
#include "cmLocalNinjaGenerator.h"
2012-04-19 19:04:21 +03:00
#include "cmMakefile.h"
2016-10-30 18:24:19 +01:00
#include "cmNinjaTypes.h"
#include "cmOutputConverter.h"
2012-04-19 19:04:21 +03:00
#include "cmSourceFile.h"
2017-04-14 19:02:05 +02:00
#include "cmStateTypes.h"
2016-10-30 18:24:19 +01:00
#include "cmSystemTools.h"
#include "cmake.h"
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
2012-04-19 19:04:21 +03:00
2014-08-03 19:52:23 +02:00
cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
2016-07-09 11:21:54 +02:00
cmGeneratorTarget* target)
: cmNinjaTargetGenerator(target)
{
}
2012-04-19 19:04:21 +03:00
2016-07-09 11:21:54 +02:00
cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator()
{
}
2012-04-19 19:04:21 +03:00
void cmNinjaUtilityTargetGenerator::Generate()
{
2016-10-30 18:24:19 +01:00
std::string utilCommandName =
this->GetLocalGenerator()->GetCurrentBinaryDirectory();
utilCommandName += cmake::GetCMakeFilesDirectory();
utilCommandName += "/";
2015-04-27 22:25:09 +02:00
utilCommandName += this->GetTargetName() + ".util";
2016-10-30 18:24:19 +01:00
utilCommandName = this->ConvertToNinjaPath(utilCommandName);
2015-04-27 22:25:09 +02:00
2012-04-19 19:04:21 +03:00
std::vector<std::string> commands;
2015-04-27 22:25:09 +02:00
cmNinjaDeps deps, outputs, util_outputs(1, utilCommandName);
2012-04-19 19:04:21 +03:00
2016-07-09 11:21:54 +02:00
const std::vector<cmCustomCommand>* cmdLists[2] = {
2016-03-13 13:35:51 +01:00
&this->GetGeneratorTarget()->GetPreBuildCommands(),
&this->GetGeneratorTarget()->GetPostBuildCommands()
2012-04-19 19:04:21 +03:00
};
2015-04-27 22:25:09 +02:00
bool uses_terminal = false;
2012-04-19 19:04:21 +03:00
for (unsigned i = 0; i != 2; ++i) {
2016-07-09 11:21:54 +02:00
for (std::vector<cmCustomCommand>::const_iterator ci =
cmdLists[i]->begin();
ci != cmdLists[i]->end(); ++ci) {
2015-04-27 22:25:09 +02:00
cmCustomCommandGenerator ccg(*ci, this->GetConfigName(),
2015-11-17 17:22:37 +01:00
this->GetLocalGenerator());
2015-04-27 22:25:09 +02:00
this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps);
this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands);
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
std::transform(ccByproducts.begin(), ccByproducts.end(),
std::back_inserter(util_outputs), MapToNinjaPath());
2016-10-30 18:24:19 +01:00
if (ci->GetUsesTerminal()) {
2015-04-27 22:25:09 +02:00
uses_terminal = true;
2016-10-30 18:24:19 +01:00
}
2012-04-19 19:04:21 +03:00
}
}
2014-08-03 19:52:23 +02:00
std::vector<cmSourceFile*> sources;
2016-07-09 11:21:54 +02:00
std::string config =
this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
2016-03-13 13:35:51 +01:00
this->GetGeneratorTarget()->GetSourceFiles(sources, config);
2016-07-09 11:21:54 +02:00
for (std::vector<cmSourceFile*>::const_iterator source = sources.begin();
source != sources.end(); ++source) {
if (cmCustomCommand* cc = (*source)->GetCustomCommand()) {
2015-04-27 22:25:09 +02:00
cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
2015-11-17 17:22:37 +01:00
this->GetLocalGenerator());
2016-07-09 11:21:54 +02:00
this->GetLocalGenerator()->AddCustomCommandTarget(
cc, this->GetGeneratorTarget());
2012-04-19 19:04:21 +03:00
// Depend on all custom command outputs.
2015-04-27 22:25:09 +02:00
const std::vector<std::string>& ccOutputs = ccg.GetOutputs();
const std::vector<std::string>& ccByproducts = ccg.GetByproducts();
2012-04-19 19:04:21 +03:00
std::transform(ccOutputs.begin(), ccOutputs.end(),
std::back_inserter(deps), MapToNinjaPath());
2015-04-27 22:25:09 +02:00
std::transform(ccByproducts.begin(), ccByproducts.end(),
std::back_inserter(deps), MapToNinjaPath());
2012-04-19 19:04:21 +03:00
}
2016-07-09 11:21:54 +02:00
}
2012-04-19 19:04:21 +03:00
2016-03-13 13:35:51 +01:00
this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(),
outputs);
this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(),
deps);
2012-04-19 19:04:21 +03:00
if (commands.empty()) {
2016-07-09 11:21:54 +02:00
this->GetGlobalGenerator()->WritePhonyBuild(
this->GetBuildFileStream(),
"Utility command for " + this->GetTargetName(), outputs, deps);
2012-04-19 19:04:21 +03:00
} else {
std::string command =
this->GetLocalGenerator()->BuildCommandLine(commands);
2016-07-09 11:21:54 +02:00
const char* echoStr =
this->GetGeneratorTarget()->GetProperty("EchoString");
2012-04-19 19:04:21 +03:00
std::string desc;
2016-10-30 18:24:19 +01:00
if (echoStr) {
2012-04-19 19:04:21 +03:00
desc = echoStr;
2016-10-30 18:24:19 +01:00
} else {
2012-04-19 19:04:21 +03:00
desc = "Running utility command for " + this->GetTargetName();
2016-10-30 18:24:19 +01:00
}
2012-04-19 19:04:21 +03:00
// TODO: fix problematic global targets. For now, search and replace the
// makefile vars.
cmSystemTools::ReplaceString(
2016-07-09 11:21:54 +02:00
command, "$(CMAKE_SOURCE_DIR)",
this->GetLocalGenerator()
->ConvertToOutputFormat(
this->GetLocalGenerator()->GetSourceDirectory(),
cmOutputConverter::SHELL)
.c_str());
2012-04-19 19:04:21 +03:00
cmSystemTools::ReplaceString(
2016-07-09 11:21:54 +02:00
command, "$(CMAKE_BINARY_DIR)",
this->GetLocalGenerator()
->ConvertToOutputFormat(
this->GetLocalGenerator()->GetBinaryDirectory(),
cmOutputConverter::SHELL)
.c_str());
2012-04-19 19:04:21 +03:00
cmSystemTools::ReplaceString(command, "$(ARGS)", "");
2016-10-30 18:24:19 +01:00
if (command.find('$') != std::string::npos) {
2012-04-19 19:04:21 +03:00
return;
2016-10-30 18:24:19 +01:00
}
2012-04-19 19:04:21 +03:00
2016-07-09 11:21:54 +02:00
for (cmNinjaDeps::const_iterator oi = util_outputs.begin(),
oe = util_outputs.end();
oi != oe; ++oi) {
2015-04-27 22:25:09 +02:00
this->GetGlobalGenerator()->SeenCustomCommandOutput(*oi);
2016-07-09 11:21:54 +02:00
}
2012-04-19 19:04:21 +03:00
this->GetGlobalGenerator()->WriteCustomCommandBuild(
2016-07-09 11:21:54 +02:00
command, desc, "Utility command for " + this->GetTargetName(),
2016-10-30 18:24:19 +01:00
/*depfile*/ "", uses_terminal,
2016-07-09 11:21:54 +02:00
/*restat*/ true, util_outputs, deps);
this->GetGlobalGenerator()->WritePhonyBuild(
this->GetBuildFileStream(), "", outputs,
cmNinjaDeps(1, utilCommandName));
2012-04-19 19:04:21 +03:00
}
2016-10-30 18:24:19 +01:00
// Add an alias for the logical target name regardless of what directory
// contains it. Skip this for GLOBAL_TARGET because they are meant to
// be per-directory and have one at the top-level anyway.
2017-04-14 19:02:05 +02:00
if (this->GetGeneratorTarget()->GetType() != cmStateEnums::GLOBAL_TARGET) {
2016-10-30 18:24:19 +01:00
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
this->GetGeneratorTarget());
}
2012-04-19 19:04:21 +03:00
}