1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
4 Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com>
6 Distributed under the OSI-approved BSD License (the "License");
7 see accompanying file Copyright.txt for details.
9 This software is distributed WITHOUT ANY WARRANTY; without even the
10 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 See the License for more information.
12 ============================================================================*/
13 #include "cmNinjaUtilityTargetGenerator.h"
14 #include "cmCustomCommand.h"
15 #include "cmGeneratedFileStream.h"
16 #include "cmGlobalNinjaGenerator.h"
17 #include "cmMakefile.h"
18 #include "cmSourceFile.h"
21 cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(cmTarget *target)
22 : cmNinjaTargetGenerator(target) {}
24 cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {}
26 void cmNinjaUtilityTargetGenerator::Generate()
28 std::vector<std::string> commands;
29 cmNinjaDeps deps, outputs;
31 const std::vector<cmCustomCommand> *cmdLists[2] = {
32 &this->GetTarget()->GetPreBuildCommands(),
33 &this->GetTarget()->GetPostBuildCommands()
36 for (unsigned i = 0; i != 2; ++i) {
37 for (std::vector<cmCustomCommand>::const_iterator
38 ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) {
39 this->GetLocalGenerator()->AppendCustomCommandDeps(&*ci, deps);
40 this->GetLocalGenerator()->AppendCustomCommandLines(&*ci, commands);
44 const std::vector<cmSourceFile*>& sources =
45 this->GetTarget()->GetSourceFiles();
46 for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
47 source != sources.end(); ++source)
49 if(cmCustomCommand* cc = (*source)->GetCustomCommand())
51 this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
53 // Depend on all custom command outputs.
54 const std::vector<std::string>& ccOutputs = cc->GetOutputs();
55 std::transform(ccOutputs.begin(), ccOutputs.end(),
56 std::back_inserter(deps), MapToNinjaPath());
60 this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
61 this->GetLocalGenerator()->AppendTargetDepends(this->GetTarget(), deps);
63 if (commands.empty()) {
64 cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
65 "Utility command for "
66 + this->GetTargetName(),
71 this->GetLocalGenerator()->BuildCommandLine(commands);
72 const char *echoStr = this->GetTarget()->GetProperty("EchoString");
77 desc = "Running utility command for " + this->GetTargetName();
79 // TODO: fix problematic global targets. For now, search and replace the
81 cmSystemTools::ReplaceString(
83 "$(CMAKE_SOURCE_DIR)",
84 this->GetLocalGenerator()->ConvertToOutputFormat(
85 this->GetTarget()->GetMakefile()->GetHomeDirectory(),
86 cmLocalGenerator::SHELL).c_str());
87 cmSystemTools::ReplaceString(
89 "$(CMAKE_BINARY_DIR)",
90 this->GetLocalGenerator()->ConvertToOutputFormat(
91 this->GetTarget()->GetMakefile()->GetHomeOutputDirectory(),
92 cmLocalGenerator::SHELL).c_str());
93 cmSystemTools::ReplaceString(command, "$(ARGS)", "");
95 if (command.find('$') != std::string::npos)
98 std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash();
99 utilCommandName += this->GetTargetName() + ".util";
101 this->GetGlobalGenerator()->WriteCustomCommandBuild(
104 "Utility command for " + this->GetTargetName(),
105 cmNinjaDeps(1, utilCommandName),
108 cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
111 cmNinjaDeps(1, utilCommandName));
114 this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),