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