| 671 | } |
| 672 | |
| 673 | void cmGlobalNinjaGenerator::CleanMetaData() |
| 674 | { |
| 675 | constexpr size_t ninja_tool_arg_size = 8; // 2 `-_` flags and 4 separators |
| 676 | auto run_ninja_tool = [this](std::vector<char const*> const& args) { |
| 677 | std::vector<std::string> command; |
| 678 | command.push_back(this->NinjaCommand); |
| 679 | command.emplace_back("-C"); |
| 680 | command.emplace_back(this->GetCMakeInstance()->GetHomeOutputDirectory()); |
| 681 | command.emplace_back("-t"); |
| 682 | for (auto const& arg : args) { |
| 683 | command.emplace_back(arg); |
| 684 | } |
| 685 | std::string error; |
| 686 | if (!cmSystemTools::RunSingleCommand(command, nullptr, &error, nullptr, |
| 687 | nullptr, |
| 688 | cmSystemTools::OUTPUT_NONE)) { |
| 689 | this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, |
| 690 | cmStrCat("Running\n '", |
| 691 | cmJoin(command, "' '"), |
| 692 | "'\n" |
| 693 | "failed with:\n ", |
| 694 | error)); |
| 695 | cmSystemTools::SetFatalErrorOccurred(); |
| 696 | } |
| 697 | }; |
| 698 | |
| 699 | // Can the tools below expect 'build.ninja' to be loadable? |
| 700 | bool const expectBuildManifest = |
| 701 | !this->IsMultiConfig() && this->OutputPathPrefix.empty(); |
| 702 | |
| 703 | // Skip some ninja tools if they need 'build.ninja' but it is missing. |
| 704 | bool const missingBuildManifest = expectBuildManifest && |
| 705 | this->NinjaSupportsUnconditionalRecompactTool && |
| 706 | !cmSystemTools::FileExists("build.ninja"); |
| 707 | |
| 708 | // The `recompact` tool loads the manifest. As above, we don't have a single |
| 709 | // `build.ninja` to load for this in Ninja-Multi. This may be relaxed in the |
| 710 | // future pending further investigation into how Ninja works upstream |
| 711 | // (ninja#1721). |
| 712 | if (this->NinjaSupportsUnconditionalRecompactTool && |
| 713 | !this->GetCMakeInstance()->GetRegenerateDuringBuild() && |
| 714 | expectBuildManifest && !missingBuildManifest) { |
| 715 | run_ninja_tool({ "recompact" }); |
| 716 | } |
| 717 | if (this->NinjaSupportsRestatTool && this->OutputPathPrefix.empty()) { |
| 718 | cmNinjaDeps outputs; |
| 719 | this->AddRebuildManifestOutputs(outputs); |
| 720 | auto output_it = outputs.begin(); |
| 721 | size_t static_arg_size = ninja_tool_arg_size + this->NinjaCommand.size() + |
| 722 | this->GetCMakeInstance()->GetHomeOutputDirectory().size(); |
| 723 | // The Windows command-line length limit is 32768, but if `ninja` is |
| 724 | // wrapped by a `.bat` file, the limit is 8192. Leave plenty. |
| 725 | constexpr size_t maximum_arg_size = 8000; |
| 726 | while (output_it != outputs.end()) { |
| 727 | size_t total_arg_size = static_arg_size; |
| 728 | std::vector<char const*> args; |
| 729 | args.reserve(std::distance(output_it, outputs.end()) + 1); |
| 730 | args.push_back("restat"); |
no test coverage detected