CMake Nightly Date Stamp
[kiteware-cmake.git] / Source / cmMakefileUtilityTargetGenerator.cxx
blob7f854ee6e640defcb7ad7c20a8f562375ab45b5f
1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmMakefileUtilityTargetGenerator.h"
5 #include <ostream>
6 #include <string>
7 #include <utility>
8 #include <vector>
10 #include <cm/memory>
12 #include "cmGeneratedFileStream.h"
13 #include "cmGeneratorTarget.h"
14 #include "cmGlobalUnixMakefileGenerator3.h"
15 #include "cmLocalUnixMakefileGenerator3.h"
16 #include "cmMakefile.h"
17 #include "cmOSXBundleGenerator.h"
18 #include "cmStringAlgorithms.h"
19 #include "cmSystemTools.h"
21 cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
22 cmGeneratorTarget* target)
23 : cmMakefileTargetGenerator(target)
25 this->CustomCommandDriver = OnUtility;
26 this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
27 this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
30 cmMakefileUtilityTargetGenerator::~cmMakefileUtilityTargetGenerator() =
31 default;
33 void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
35 this->CreateRuleFile();
37 *this->BuildFileStream << "# Utility rule file for "
38 << this->GeneratorTarget->GetName() << ".\n\n";
40 const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")
41 ? "$(CMAKE_BINARY_DIR)/"
42 : "");
44 // Include the dependencies for the target.
45 std::string dependFile =
46 cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
47 *this->BuildFileStream
48 << "# Include any custom commands dependencies for this target.\n"
49 << this->GlobalGenerator->IncludeDirective << " " << root
50 << cmSystemTools::ConvertToOutputPath(
51 this->LocalGenerator->MaybeRelativeToTopBinDir(dependFile))
52 << "\n\n";
53 if (!cmSystemTools::FileExists(dependFile)) {
54 // Write an empty dependency file.
55 cmGeneratedFileStream depFileStream(
56 dependFile, false, this->GlobalGenerator->GetMakefileEncoding());
57 depFileStream << "# Empty custom commands generated dependencies file for "
58 << this->GeneratorTarget->GetName() << ".\n"
59 << "# This may be replaced when dependencies are built.\n";
62 std::string dependTimestamp =
63 cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts");
64 if (!cmSystemTools::FileExists(dependTimestamp)) {
65 // Write a dependency timestamp file.
66 cmGeneratedFileStream depFileStream(
67 dependTimestamp, false, this->GlobalGenerator->GetMakefileEncoding());
68 depFileStream << "# CMAKE generated file: DO NOT EDIT!\n"
69 << "# Timestamp file for custom commands dependencies "
70 "management for "
71 << this->GeneratorTarget->GetName() << ".\n";
74 if (!this->NoRuleMessages) {
75 // Include the progress variables for the target.
76 *this->BuildFileStream
77 << "# Include the progress variables for this target.\n"
78 << this->GlobalGenerator->IncludeDirective << " " << root
79 << cmSystemTools::ConvertToOutputPath(
80 this->LocalGenerator->MaybeRelativeToTopBinDir(
81 this->ProgressFileNameFull))
82 << "\n\n";
85 // write the custom commands for this target
86 this->WriteTargetBuildRules();
88 // Collect the commands and dependencies.
89 std::vector<std::string> commands;
90 std::vector<std::string> depends;
92 // Utility targets store their rules in pre- and post-build commands.
93 this->LocalGenerator->AppendCustomDepends(
94 depends, this->GeneratorTarget->GetPreBuildCommands());
96 this->LocalGenerator->AppendCustomDepends(
97 depends, this->GeneratorTarget->GetPostBuildCommands());
99 this->LocalGenerator->AppendCustomCommands(
100 commands, this->GeneratorTarget->GetPreBuildCommands(),
101 this->GeneratorTarget, this->LocalGenerator->GetBinaryDirectory());
103 // Depend on all custom command outputs for sources
104 this->DriveCustomCommands(depends);
106 this->LocalGenerator->AppendCustomCommands(
107 commands, this->GeneratorTarget->GetPostBuildCommands(),
108 this->GeneratorTarget, this->LocalGenerator->GetBinaryDirectory());
110 // Add dependencies on targets that must be built first.
111 this->AppendTargetDepends(depends);
113 // Add a dependency on the rule file itself.
114 this->LocalGenerator->AppendRuleDepend(depends,
115 this->BuildFileNameFull.c_str());
117 // If the rule is empty add the special empty rule dependency needed
118 // by some make tools.
119 if (depends.empty() && commands.empty()) {
120 std::string hack = this->GlobalGenerator->GetEmptyRuleHackDepends();
121 if (!hack.empty()) {
122 depends.push_back(std::move(hack));
126 // Write the rule.
127 this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr,
128 this->GeneratorTarget->GetName(),
129 depends, commands, true);
131 // Write the main driver rule to build everything in this target.
132 this->WriteTargetDriverRule(this->GeneratorTarget->GetName(), false);
134 // Write clean target
135 this->WriteTargetCleanRules();
137 // Write the dependency generation rule. This must be done last so
138 // that multiple output pair information is available.
139 this->WriteTargetDependRules();
141 // close the streams
142 this->CloseFileStreams();