in lib/Commands/NinjaCommand.cpp [461:604]
static void dumpNinjaManifestText(StringRef file, ninja::Manifest* manifest) {
// Dump the manifest.
std::cout << "# Loaded Manifest: \"" << file.str() << "\"\n";
std::cout << "\n";
// Dump the top-level bindings.
std::cout << "# Top-Level Bindings\n";
assert(manifest->getRootScope().getParent() == nullptr);
std::vector<std::pair<std::string, std::string>> bindings;
for (const auto& entry: manifest->getRootScope().getBindings()) {
bindings.push_back({ entry.getKey(), entry.getValue() });
}
std::sort(bindings.begin(), bindings.end());
for (const auto& entry: bindings) {
std::cout << entry.first << " = \""
<< util::escapedString(entry.second) << "\"\n";
}
std::cout << "\n";
// Dump the pools, if present.
if (!manifest->getPools().empty()) {
std::cout << "# Pools\n";
std::vector<ninja::Pool*> pools;
for (const auto& entry: manifest->getPools()) {
pools.push_back(entry.getValue());
}
std::sort(pools.begin(), pools.end(), [] (ninja::Pool* a, ninja::Pool* b) {
return a->getName() < b->getName();
});
for (const auto& pool: pools) {
// Write the rule entry.
std::cout << "pool " << pool->getName() << "\n";
if (uint32_t depth = pool->getDepth()) {
std::cout << " depth = " << depth << "\n";
}
std::cout << "\n";
}
}
// Dump the rules.
std::cout << "# Rules\n";
std::vector<ninja::Rule*> rules;
for (const auto& entry: manifest->getRootScope().getRules()) {
rules.push_back(entry.getValue());
}
std::sort(rules.begin(), rules.end(), [] (ninja::Rule* a, ninja::Rule* b) {
return a->getName() < b->getName();
});
for (const auto& rule: rules) {
// Write the rule entry.
std::cout << "rule " << rule->getName() << "\n";
// Write the parameters.
std::vector<std::pair<std::string, std::string>> parameters;
for (const auto& entry: rule->getParameters()) {
parameters.push_back({ entry.getKey(), entry.getValue() });
}
std::sort(parameters.begin(), parameters.end());
for (const auto& entry: parameters) {
std::cout << " " << entry.first << " = \""
<< util::escapedString(entry.second) << "\"\n";
}
std::cout << "\n";
}
// Dump the commands.
std::vector<ninja::Command*> commands(manifest->getCommands());
std::sort(commands.begin(), commands.end(),
[] (ninja::Command* a, ninja::Command* b) {
// Commands can not have duplicate outputs, so comparing based
// only on the first still provides a total ordering.
return a->getOutputs()[0]->getScreenPath() <
b->getOutputs()[0]->getScreenPath();
});
std::cout << "# Commands\n";
for (const auto& command: commands) {
// Write the command entry.
std::cout << "build";
for (const auto& node: command->getOutputs()) {
std::cout << " \"" << util::escapedString(node->getScreenPath()) << "\"";
}
std::cout << ": " << command->getRule()->getName();
unsigned count = 0;
for (const auto& node: command->getInputs()) {
std::cout << " ";
if (count == (command->getNumExplicitInputs() +
command->getNumImplicitInputs())) {
std::cout << "|| ";
} else if (count == command->getNumExplicitInputs()) {
std::cout << "| ";
}
std::cout << "\"" << util::escapedString(node->getScreenPath()) << "\"";
++count;
}
std::cout << "\n";
// Write out the attributes.
std::cout << " command = \""
<< util::escapedString(command->getCommandString()) << "\"\n";
std::cout << " description = \""
<< util::escapedString(command->getDescription()) << "\"\n";
switch (command->getDepsStyle()) {
case ninja::Command::DepsStyleKind::None:
break;
case ninja::Command::DepsStyleKind::GCC:
std::cout << " deps = gcc\n";
std::cout << " depfile = \""
<< util::escapedString(command->getDepsFile()) << "\"\n";
break;
case ninja::Command::DepsStyleKind::MSVC:
std::cout << " deps = msvc\n";
break;
}
if (command->hasGeneratorFlag())
std::cout << " generator = 1\n";
if (command->hasRestatFlag())
std::cout << " restat = 1\n";
if (const ninja::Pool* executionPool = command->getExecutionPool()) {
std::cout << " pool = " << executionPool->getName() << "\n";
}
std::cout << "\n";
}
// Dump the default targets, if specified.
if (!manifest->getDefaultTargets().empty()) {
std::cout << "# Default Targets\n";
std::vector<ninja::Node*> defaultTargets = manifest->getDefaultTargets();
std::sort(defaultTargets.begin(), defaultTargets.end(),
[] (ninja::Node* a, ninja::Node* b) {
return a->getScreenPath() < b->getScreenPath();
});
std::cout << "default ";
for (const auto& node: defaultTargets) {
if (node != defaultTargets[0])
std::cout << " ";
std::cout << "\"" << node->getScreenPath() << "\"";
}
std::cout << "\n\n";
}
}