/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmLocalUnixMakefileGenerator3.h"

#include <algorithm>
#include <cassert>
#include <cstdio>
#include <functional>
#include <utility>

#include <cm/memory>
#include <cm/optional>
#include <cm/string_view>
#include <cm/vector>
#include <cmext/algorithm>
#include <cmext/string_view>

#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"

#include "cmCMakePath.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
#include "cmDependsCompiler.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMakefileTargetGenerator.h"
#include "cmOutputConverter.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTargetDepend.h"
#include "cmValue.h"
#include "cmVersion.h"
#include "cmake.h"

// Include dependency scanners for supported languages.  Only the
// C/C++ scanner is needed for bootstrapping CMake.
#include "cmDependsC.h"
#ifndef CMAKE_BOOTSTRAP
#  include "cmDependsFortran.h"
#  include "cmDependsJava.h"
#endif

namespace {
// Helper function used below.
std::string cmSplitExtension(std::string const& in, std::string& base)
{
  std::string ext;
  std::string::size_type dot_pos = in.rfind('.');
  if (dot_pos != std::string::npos) {
    // Remove the extension first in case &base == &in.
    ext = in.substr(dot_pos);
    base = in.substr(0, dot_pos);
  } else {
    base = in;
  }
  return ext;
}

// Helper predicate for removing absolute paths that don't point to the
// source or binary directory. It is used when CMAKE_DEPENDS_IN_PROJECT_ONLY
// is set ON, to only consider in-project dependencies during the build.
class NotInProjectDir
{
public:
  // Constructor with the source and binary directory's path
  NotInProjectDir(cm::string_view sourceDir, cm::string_view binaryDir)
    : SourceDir(sourceDir)
    , BinaryDir(binaryDir)
  {
  }

  // Operator evaluating the predicate
  bool operator()(std::string const& p) const
  {
    auto path = cmCMakePath(p).Normal();

    // Keep all relative paths:
    if (path.IsRelative()) {
      return false;
    }

    // If it's an absolute path, check if it starts with the source
    // directory:
    return !(cmCMakePath(this->SourceDir).IsPrefix(path) ||
             cmCMakePath(this->BinaryDir).IsPrefix(path));
  }

private:
  // The path to the source directory
  cm::string_view SourceDir;
  // The path to the binary directory
  cm::string_view BinaryDir;
};
}

cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
  cmGlobalGenerator* gg, cmMakefile* mf)
  : cmLocalCommonGenerator(gg, mf)
{
  this->MakefileVariableSize = 0;
  this->ColorMakefile = false;
  this->SkipPreprocessedSourceRules = false;
  this->SkipAssemblySourceRules = false;
  this->MakeCommandEscapeTargetTwice = false;
  this->BorlandMakeCurlyHack = false;
}

cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() = default;

std::string cmLocalUnixMakefileGenerator3::GetConfigName() const
{
  auto const& configNames = this->GetConfigNames();
  assert(configNames.size() == 1);
  return configNames.front();
}

void cmLocalUnixMakefileGenerator3::Generate()
{
  // Record whether some options are enabled to avoid checking many
  // times later.
  if (!this->GetGlobalGenerator()->GetCMakeInstance()->GetIsInTryCompile()) {
    if (this->Makefile->IsSet("CMAKE_COLOR_MAKEFILE")) {
      this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE");
    } else {
      this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_DIAGNOSTICS");
    }
  }
  this->SkipPreprocessedSourceRules =
    this->Makefile->IsOn("CMAKE_SKIP_PREPROCESSED_SOURCE_RULES");
  this->SkipAssemblySourceRules =
    this->Makefile->IsOn("CMAKE_SKIP_ASSEMBLY_SOURCE_RULES");

  // Generate the rule files for each target.
  cmGlobalUnixMakefileGenerator3* gg =
    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
  for (cmGeneratorTarget* gt :
       this->GlobalGenerator->GetLocalGeneratorTargetsInOrder(this)) {
    if (!gt->IsInBuildSystem()) {
      continue;
    }

    auto& gtVisited = this->GetCommandsVisited(gt);
    auto const& deps = this->GlobalGenerator->GetTargetDirectDepends(gt);
    for (auto const& d : deps) {
      // Take the union of visited source files of custom commands
      auto depVisited = this->GetCommandsVisited(d);
      gtVisited.insert(depVisited.begin(), depVisited.end());
    }

    std::unique_ptr<cmMakefileTargetGenerator> tg(
      cmMakefileTargetGenerator::New(gt));
    if (tg) {
      tg->WriteRuleFiles();
      gg->RecordTargetProgress(tg.get());
    }
  }

  // write the local Makefile
  this->WriteLocalMakefile();

  // Write the cmake file with information for this directory.
  this->WriteDirectoryInformationFile();
}

void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
{
  // Compute the path to use when referencing the current output
  // directory from the top output directory.
  this->HomeRelativeOutputPath =
    this->MaybeRelativeToTopBinDir(this->GetCurrentBinaryDirectory());
  if (this->HomeRelativeOutputPath == ".") {
    this->HomeRelativeOutputPath.clear();
  }
  if (!this->HomeRelativeOutputPath.empty()) {
    this->HomeRelativeOutputPath += "/";
  }
}

void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
  std::map<std::string, LocalObjectInfo>& localObjectFiles)
{
  for (auto const& gt : this->GetGeneratorTargets()) {
    if (!gt->CanCompileSources()) {
      continue;
    }
    std::vector<cmSourceFile const*> objectSources;
    gt->GetObjectSources(objectSources, this->GetConfigName());
    // Compute full path to object file directory for this target.
    std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
                               '/', this->GetTargetDirectory(gt.get()), '/');
    // Compute the name of each object file.
    for (cmSourceFile const* sf : objectSources) {
      bool hasSourceExtension = true;
      std::string objectName =
        this->GetObjectFileNameWithoutTarget(*sf, dir, &hasSourceExtension);
      if (cmSystemTools::FileIsFullPath(objectName)) {
        objectName = cmSystemTools::GetFilenameName(objectName);
      }
      LocalObjectInfo& info = localObjectFiles[objectName];
      info.HasSourceExtension = hasSourceExtension;
      info.emplace_back(gt.get(), sf->GetLanguage());
    }
  }
}

void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets(
  std::vector<std::string>& targets)
{
  std::map<std::string, LocalObjectInfo> localObjectFiles;
  this->GetLocalObjectFiles(localObjectFiles);
  for (auto const& localObjectFile : localObjectFiles) {
    targets.push_back(localObjectFile.first);

    std::string::size_type dot_pos = localObjectFile.first.rfind(".");
    std::string base = localObjectFile.first.substr(0, dot_pos);
    if (localObjectFile.second.HasPreprocessRule) {
      targets.push_back(base + ".i");
    }

    if (localObjectFile.second.HasAssembleRule) {
      targets.push_back(base + ".s");
    }
  }
}

std::string cmLocalUnixMakefileGenerator3::GetLinkDependencyFile(
  cmGeneratorTarget* target, std::string const& /*config*/) const
{
  return cmStrCat(target->GetSupportDirectory(), "/link.d");
}

void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
{
  // generate the includes
  std::string ruleFileName = "Makefile";

  // Open the rule file.  This should be copy-if-different because the
  // rules may depend on this file itself.
  std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
  cmGeneratedFileStream ruleFileStream(
    ruleFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
  if (!ruleFileStream) {
    return;
  }
  // always write the top makefile
  if (!this->IsRootMakefile()) {
    ruleFileStream.SetCopyIfDifferent(true);
  }

  // write the all rules
  this->WriteLocalAllRules(ruleFileStream);

  // only write local targets unless at the top Keep track of targets already
  // listed.
  std::set<std::string> emittedTargets;
  if (!this->IsRootMakefile()) {
    // write our targets, and while doing it collect up the object
    // file rules
    this->WriteLocalMakefileTargets(ruleFileStream, emittedTargets);
  } else {
    cmGlobalUnixMakefileGenerator3* gg =
      static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
    gg->WriteConvenienceRules(ruleFileStream, emittedTargets);
  }

  bool do_preprocess_rules = this->GetCreatePreprocessedSourceRules();
  bool do_assembly_rules = this->GetCreateAssemblySourceRules();

  std::map<std::string, LocalObjectInfo> localObjectFiles;
  this->GetLocalObjectFiles(localObjectFiles);

  // now write out the object rules
  // for each object file name
  for (auto& localObjectFile : localObjectFiles) {
    // Add a convenience rule for building the object file.
    this->WriteObjectConvenienceRule(
      ruleFileStream, "target to build an object file", localObjectFile.first,
      localObjectFile.second);

    // Check whether preprocessing and assembly rules make sense.
    // They make sense only for C and C++ sources.
    bool lang_has_preprocessor = false;
    bool lang_has_assembly = false;

    for (LocalObjectEntry const& entry : localObjectFile.second) {
      if (entry.Language == "C" || entry.Language == "CXX" ||
          entry.Language == "CUDA" || entry.Language == "Fortran" ||
          entry.Language == "HIP" || entry.Language == "ISPC") {
        // Right now, C, C++, CUDA, Fortran, HIP and ISPC have both a
        // preprocessor and the ability to generate assembly code
        lang_has_preprocessor = true;
        lang_has_assembly = true;
        break;
      }
    }

    // Add convenience rules for preprocessed and assembly files.
    if (lang_has_preprocessor && do_preprocess_rules) {
      std::string::size_type dot_pos = localObjectFile.first.rfind(".");
      std::string base = localObjectFile.first.substr(0, dot_pos);
      this->WriteObjectConvenienceRule(ruleFileStream,
                                       "target to preprocess a source file",
                                       (base + ".i"), localObjectFile.second);
      localObjectFile.second.HasPreprocessRule = true;
    }

    if (lang_has_assembly && do_assembly_rules) {
      std::string::size_type dot_pos = localObjectFile.first.rfind(".");
      std::string base = localObjectFile.first.substr(0, dot_pos);
      this->WriteObjectConvenienceRule(
        ruleFileStream, "target to generate assembly for a file",
        (base + ".s"), localObjectFile.second);
      localObjectFile.second.HasAssembleRule = true;
    }
  }

  // add a help target as long as there isn;t a real target named help
  if (emittedTargets.insert("help").second) {
    cmGlobalUnixMakefileGenerator3* gg =
      static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
    gg->WriteHelpRule(ruleFileStream, this);
  }

  this->WriteSpecialTargetsBottom(ruleFileStream);
}

void cmLocalUnixMakefileGenerator3::WriteObjectConvenienceRule(
  std::ostream& ruleFileStream, char const* comment, std::string const& output,
  LocalObjectInfo const& info)
{
  // If the rule includes the source file extension then create a
  // version that has the extension removed.  The help should include
  // only the version without source extension.
  bool inHelp = true;
  if (info.HasSourceExtension) {
    // Remove the last extension.  This should be kept.
    std::string outBase1 = output;
    std::string outExt1 = cmSplitExtension(outBase1, outBase1);

    // Now remove the source extension and put back the last
    // extension.
    std::string outNoExt;
    cmSplitExtension(outBase1, outNoExt);
    outNoExt += outExt1;

    // Add a rule to drive the rule below.
    std::vector<std::string> depends;
    depends.emplace_back(output);
    std::vector<std::string> no_commands;
    this->WriteMakeRule(ruleFileStream, nullptr, outNoExt, depends,
                        no_commands, true, true);
    inHelp = false;
  }

  // Recursively make the rule for each target using the object file.
  std::vector<std::string> commands;
  for (LocalObjectEntry const& t : info) {
    std::string tgtMakefileName = this->GetRelativeTargetDirectory(t.Target);
    std::string targetName = tgtMakefileName;
    tgtMakefileName += "/build.make";
    targetName += "/";
    targetName += output;
    commands.push_back(
      this->GetRecursiveMakeCall(tgtMakefileName, targetName));
  }
  this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                        this->GetCurrentBinaryDirectory());

  // Write the rule to the makefile.
  std::vector<std::string> no_depends;
  this->WriteMakeRule(ruleFileStream, comment, output, no_depends, commands,
                      true, inHelp);
}

void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
  std::ostream& ruleFileStream, std::set<std::string>& emitted)
{
  std::vector<std::string> depends;
  std::vector<std::string> commands;

  // for each target we just provide a rule to cd up to the top and do a make
  // on the target
  std::string localName;
  for (auto const& target : this->GetGeneratorTargets()) {
    if ((target->GetType() == cmStateEnums::EXECUTABLE) ||
        (target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
        (target->GetType() == cmStateEnums::SHARED_LIBRARY) ||
        (target->GetType() == cmStateEnums::MODULE_LIBRARY) ||
        (target->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
        (target->GetType() == cmStateEnums::UTILITY)) {
      emitted.insert(target->GetName());

      // for subdirs add a rule to build this specific target by name.
      localName =
        cmStrCat(this->GetRelativeTargetDirectory(target.get()), "/rule");
      commands.clear();
      depends.clear();

      // Build the target for this pass.
      std::string makefile2 = "CMakeFiles/Makefile2";
      commands.push_back(this->GetRecursiveMakeCall(makefile2, localName));
      this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                            this->GetCurrentBinaryDirectory());
      this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
                          localName, depends, commands, true);

      // Add a target with the canonical name (no prefix, suffix or path).
      if (localName != target->GetName()) {
        commands.clear();
        depends.push_back(localName);
        this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
                            target->GetName(), depends, commands, true);
      }

      // Add a fast rule to build the target
      std::string makefileName = cmStrCat(
        this->GetRelativeTargetDirectory(target.get()), "/build.make");
      // make sure the makefile name is suitable for a makefile
      std::string makeTargetName =
        cmStrCat(this->GetRelativeTargetDirectory(target.get()), "/build");
      localName = cmStrCat(target->GetName(), "/fast");
      depends.clear();
      commands.clear();
      commands.push_back(
        this->GetRecursiveMakeCall(makefileName, makeTargetName));
      this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                            this->GetCurrentBinaryDirectory());
      this->WriteMakeRule(ruleFileStream, "fast build rule for target.",
                          localName, depends, commands, true);

      // Add a local name for the rule to relink the target before
      // installation.
      if (target->NeedRelinkBeforeInstall(this->GetConfigName())) {
        makeTargetName = cmStrCat(
          this->GetRelativeTargetDirectory(target.get()), "/preinstall");
        localName = cmStrCat(target->GetName(), "/preinstall");
        depends.clear();
        commands.clear();
        commands.push_back(
          this->GetRecursiveMakeCall(makefile2, makeTargetName));
        this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                              this->GetCurrentBinaryDirectory());
        this->WriteMakeRule(ruleFileStream,
                            "Manual pre-install relink rule for target.",
                            localName, depends, commands, true);
      }
    }
  }
}

void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
{
  std::string infoFileName =
    cmStrCat(this->GetCurrentBinaryDirectory(),
             "/CMakeFiles/CMakeDirectoryInformation.cmake");

  // Open the output file.
  cmGeneratedFileStream infoFileStream(infoFileName);
  if (!infoFileStream) {
    return;
  }

  infoFileStream.SetCopyIfDifferent(true);
  // Write the do not edit header.
  this->WriteDisclaimer(infoFileStream);

  // Setup relative path conversion tops.
  infoFileStream << "# Relative path conversion top directories.\n"
                    "set(CMAKE_RELATIVE_PATH_TOP_SOURCE \""
                 << this->GetRelativePathTopSource() << "\")\n"
                 << "set(CMAKE_RELATIVE_PATH_TOP_BINARY \""
                 << this->GetRelativePathTopBinary() << "\")\n"
                 << '\n';

  // Tell the dependency scanner to use unix paths if necessary.
  if (cmSystemTools::GetForceUnixPaths()) {
    infoFileStream << "# Force unix paths in dependencies.\n"
                      "set(CMAKE_FORCE_UNIX_PATHS 1)\n"
                      "\n";
  }

  // Store the include regular expressions for this directory.
  infoFileStream << "\n"
                    "# The C and CXX include file regular expressions for "
                    "this directory.\n"
                    "set(CMAKE_C_INCLUDE_REGEX_SCAN ";
  cmLocalUnixMakefileGenerator3::WriteCMakeArgument(
    infoFileStream, this->Makefile->GetIncludeRegularExpression());
  infoFileStream << ")\n"
                    "set(CMAKE_C_INCLUDE_REGEX_COMPLAIN ";
  cmLocalUnixMakefileGenerator3::WriteCMakeArgument(
    infoFileStream, this->Makefile->GetComplainRegularExpression());
  infoFileStream
    << ")\n"
    << "set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})\n"
       "set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN "
       "${CMAKE_C_INCLUDE_REGEX_COMPLAIN})\n";
}

std::string cmLocalUnixMakefileGenerator3::ConvertToFullPath(
  std::string const& localPath)
{
  std::string dir =
    cmStrCat(this->GetCurrentBinaryDirectory(), '/', localPath);
  return dir;
}

std::string const& cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath()
{
  return this->HomeRelativeOutputPath;
}

std::string cmLocalUnixMakefileGenerator3::ConvertToMakefilePath(
  std::string const& path) const
{
  cmGlobalUnixMakefileGenerator3* gg =
    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
  return gg->ConvertToMakefilePath(path);
}

void cmLocalUnixMakefileGenerator3::WriteMakeRule(
  std::ostream& os, char const* comment, std::string const& target,
  std::vector<std::string> const& depends,
  std::vector<std::string> const& commands, bool symbolic, bool in_help)
{
  // Make sure there is a target.
  if (target.empty()) {
    std::string err("No target for WriteMakeRule! called with comment: ");
    if (comment) {
      err += comment;
    }
    cmSystemTools::Error(err);
    return;
  }

  std::string replace;

  // Write the comment describing the rule in the makefile.
  if (comment) {
    replace = comment;
    std::string::size_type lpos = 0;
    std::string::size_type rpos;
    while ((rpos = replace.find('\n', lpos)) != std::string::npos) {
      os << "# " << replace.substr(lpos, rpos - lpos) << "\n";
      lpos = rpos + 1;
    }
    os << "# " << replace.substr(lpos) << "\n";
  }

  // Construct the left hand side of the rule.
  std::string tgt =
    this->ConvertToMakefilePath(this->MaybeRelativeToTopBinDir(target));

  char const* space = "";
  if (tgt.size() == 1) {
    // Add a space before the ":" to avoid drive letter confusion on
    // Windows.
    space = " ";
  }

  // Mark the rule as symbolic if requested.
  if (symbolic) {
    if (cmValue sym =
          this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE")) {
      os << tgt << space << ": " << *sym << '\n';
    }
  }

  // Write the rule.
  if (depends.empty()) {
    // No dependencies.  The commands will always run.
    os << tgt << space << ":\n";
  } else {
    // Split dependencies into multiple rule lines.  This allows for
    // very long dependency lists even on older make implementations.
    for (std::string const& depend : depends) {
      os << tgt << space << ": "
         << this->ConvertToMakefilePath(this->MaybeRelativeToTopBinDir(depend))
         << '\n';
    }
  }

  if (!commands.empty()) {
    // Write the list of commands.
    os << cmWrap("\t", commands, "", "\n") << '\n';
  }
  if (symbolic && !this->IsWatcomWMake()) {
    os << ".PHONY : " << tgt << '\n';
  }
  os << '\n';
  // Add the output to the local help if requested.
  if (in_help) {
    this->LocalHelp.push_back(target);
  }
}

std::string cmLocalUnixMakefileGenerator3::MaybeConvertWatcomShellCommand(
  std::string const& cmd)
{
  if (this->IsWatcomWMake() && cmSystemTools::FileIsFullPath(cmd) &&
      cmd.find_first_of("( )") != std::string::npos) {
    // On Watcom WMake use the windows short path for the command
    // name.  This is needed to avoid funny quoting problems on
    // lines with shell redirection operators.
    std::string scmd;
    if (cmSystemTools::GetShortPath(cmd, scmd)) {
      return this->ConvertToOutputFormat(scmd, cmOutputConverter::SHELL);
    }
  }
  return std::string();
}

void cmLocalUnixMakefileGenerator3::WriteMakeVariables(
  std::ostream& makefileStream)
{
  this->WriteDivider(makefileStream);
  makefileStream << "# Set environment variables for the build.\n"
                    "\n";
  cmGlobalUnixMakefileGenerator3* gg =
    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
  if (gg->DefineWindowsNULL) {
    makefileStream << "!IF \"$(OS)\" == \"Windows_NT\"\n"
                      "NULL=\n"
                      "!ELSE\n"
                      "NULL=nul\n"
                      "!ENDIF\n";
  }
  if (this->IsWindowsShell()) {
    makefileStream << "SHELL = cmd.exe\n"
                      "\n";
  } else {
#if !defined(__VMS)
    makefileStream << "# The shell in which to execute make rules.\n"
                      "SHELL = /bin/sh\n"
                      "\n";
#endif
  }

  std::string cmakeShellCommand =
    this->MaybeConvertWatcomShellCommand(cmSystemTools::GetCMakeCommand());
  if (cmakeShellCommand.empty()) {
    cmakeShellCommand = this->ConvertToOutputFormat(
      cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
  }

  makefileStream
    << "# The CMake executable.\n"
       "CMAKE_COMMAND = "
    << cmakeShellCommand
    << "\n"
       "\n"
       "# The command to remove a file.\n"
       "RM = "
    << cmakeShellCommand
    << " -E rm -f\n"
       "\n"
       "# Escaping for special characters.\n"
       "EQUALS = =\n"
       "\n"
       "# The top-level source directory on which CMake was run.\n"
       "CMAKE_SOURCE_DIR = "
    << this->ConvertToOutputFormat(this->GetSourceDirectory(),
                                   cmOutputConverter::SHELL)
    << "\n"
       "\n"
       "# The top-level build directory on which CMake was run.\n"
       "CMAKE_BINARY_DIR = "
    << this->ConvertToOutputFormat(this->GetBinaryDirectory(),
                                   cmOutputConverter::SHELL)
    << "\n"
       "\n";
}

void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop(
  std::ostream& makefileStream)
{
  this->WriteDivider(makefileStream);
  makefileStream << "# Special targets provided by cmake.\n"
                    "\n";

  std::vector<std::string> no_commands;
  std::vector<std::string> no_depends;

  // Special target to cleanup operation of make tool.
  // This should be the first target except for the default_target in
  // the interface Makefile.
  this->WriteMakeRule(makefileStream,
                      "Disable implicit rules so canonical targets will work.",
                      ".SUFFIXES", no_depends, no_commands, false);

  if (!this->IsNMake() && !this->IsWatcomWMake() &&
      !this->BorlandMakeCurlyHack) {
    // turn off RCS and SCCS automatic stuff from gmake
    constexpr char const* vcs_rules[] = {
      "%,v", "RCS/%", "RCS/%,v", "SCCS/s.%", "s.%",
    };
    for (auto const* vcs_rule : vcs_rules) {
      std::vector<std::string> vcs_depend;
      vcs_depend.emplace_back(vcs_rule);
      this->WriteMakeRule(makefileStream, "Disable VCS-based implicit rules.",
                          "%", vcs_depend, no_commands, false);
    }
  }
  // Add a fake suffix to keep HP happy.  Must be max 32 chars for SGI make.
  std::vector<std::string> depends;
  depends.emplace_back(".hpux_make_needs_suffix_list");
  this->WriteMakeRule(makefileStream, nullptr, ".SUFFIXES", depends,
                      no_commands, false);
  if (this->IsWatcomWMake()) {
    // Switch on WMake feature, if an error or interrupt occurs during
    // makefile processing, the current target being made may be deleted
    // without prompting (the same as command line -e option).
    makefileStream << "\n"
                      ".ERASE\n"
                      "\n";
  }
  if (this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) {
    makefileStream << "# Produce verbose output by default.\n"
                      "VERBOSE = 1\n"
                      "\n";
  }
  if (this->IsWatcomWMake()) {
    makefileStream << "!ifndef VERBOSE\n"
                      ".SILENT\n"
                      "!endif\n"
                      "\n";
  } else {
    makefileStream << "# Command-line flag to silence nested $(MAKE).\n"
                      "$(VERBOSE)MAKESILENT = -s\n"
                      "\n";

    // Write special target to silence make output.  This must be after
    // the default target in case VERBOSE is set (which changes the
    // name).  The setting of CMAKE_VERBOSE_MAKEFILE to ON will cause a
    // "VERBOSE=1" to be added as a make variable which will change the
    // name of this special target.  This gives a make-time choice to
    // the user.
    // Write directly to the stream since WriteMakeRule escapes '$'.
    makefileStream << "#Suppress display of executed commands.\n"
                      "$(VERBOSE).SILENT:\n"
                      "\n";
  }

  // Work-around for makes that drop rules that have no dependencies
  // or commands.
  cmGlobalUnixMakefileGenerator3* gg =
    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
  std::string hack = gg->GetEmptyRuleHackDepends();
  if (!hack.empty()) {
    no_depends.push_back(std::move(hack));
  }
  std::string hack_cmd = gg->GetEmptyRuleHackCommand();
  if (!hack_cmd.empty()) {
    no_commands.push_back(std::move(hack_cmd));
  }

  // Special symbolic target that never exists to force dependers to
  // run their rules.
  this->WriteMakeRule(makefileStream, "A target that is always out of date.",
                      "cmake_force", no_depends, no_commands, true);

  // Variables for reference by other rules.
  this->WriteMakeVariables(makefileStream);
}

void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsBottom(
  std::ostream& makefileStream)
{
  this->WriteDivider(makefileStream);
  makefileStream << "# Special targets to cleanup operation of make.\n"
                    "\n";

  // Write special "cmake_check_build_system" target to run cmake with
  // the --check-build-system flag.
  if (!this->GlobalGenerator->GlobalSettingIsOn(
        "CMAKE_SUPPRESS_REGENERATION")) {
    // Build command to run CMake to check if anything needs regenerating.
    std::vector<std::string> commands;
    cmake* cm = this->GlobalGenerator->GetCMakeInstance();
    if (cm->DoWriteGlobVerifyTarget()) {
      std::string rescanRule =
        cmStrCat("$(CMAKE_COMMAND) -P ",
                 this->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
                                             cmOutputConverter::SHELL));
      commands.push_back(rescanRule);
    }
    std::string cmakefileName = "CMakeFiles/Makefile.cmake";
    std::string runRule = cmStrCat(
      "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) ",
      cm->GetIgnoreCompileWarningAsError() ? "--compile-no-warning-as-error "
                                           : "",
      cm->GetIgnoreLinkWarningAsError() ? "--link-no-warning-as-error " : "",
      "--check-build-system ",
      this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL),
      " 0");

    std::vector<std::string> no_depends;
    commands.push_back(std::move(runRule));
    if (!this->IsRootMakefile()) {
      this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                            this->GetCurrentBinaryDirectory());
    }
    this->WriteMakeRule(makefileStream,
                        "Special rule to run CMake to check the build system "
                        "integrity.\n"
                        "No rule that depends on this can have "
                        "commands that come from listfiles\n"
                        "because they might be regenerated.",
                        "cmake_check_build_system", no_depends, commands,
                        true);
  }
}

void cmLocalUnixMakefileGenerator3::WriteConvenienceRule(
  std::ostream& ruleFileStream, std::string const& realTarget,
  std::string const& helpTarget)
{
  // A rule is only needed if the names are different.
  if (realTarget != helpTarget) {
    // The helper target depends on the real target.
    std::vector<std::string> depends;
    depends.push_back(realTarget);

    // There are no commands.
    std::vector<std::string> no_commands;

    // Write the rule.
    this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
                        helpTarget, depends, no_commands, true);
  }
}

std::string cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory(
  cmGeneratorTarget const* target) const
{
  std::string dir =
    cmStrCat(this->HomeRelativeOutputPath, this->GetTargetDirectory(target));
  return dir;
}

void cmLocalUnixMakefileGenerator3::AppendFlags(
  std::string& flags, std::string const& newFlags) const
{
  if (this->IsWatcomWMake() && !newFlags.empty()) {
    std::string newf = newFlags;
    if (newf.find("\\\"") != std::string::npos) {
      cmSystemTools::ReplaceString(newf, "\\\"", "\"");
      this->cmLocalGenerator::AppendFlags(flags, newf);
      return;
    }
  }
  this->cmLocalGenerator::AppendFlags(flags, newFlags);
}

void cmLocalUnixMakefileGenerator3::AppendRuleDepend(
  std::vector<std::string>& depends, char const* ruleFileName)
{
  // Add a dependency on the rule file itself unless an option to skip
  // it is specifically enabled by the user or project.
  cmValue nodep = this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY");
  if (nodep.IsOff()) {
    depends.emplace_back(ruleFileName);
  }
}

void cmLocalUnixMakefileGenerator3::AppendRuleDepends(
  std::vector<std::string>& depends, std::vector<std::string> const& ruleFiles)
{
  // Add a dependency on the rule file itself unless an option to skip
  // it is specifically enabled by the user or project.
  if (!this->Makefile->IsOn("CMAKE_SKIP_RULE_DEPENDENCY")) {
    cm::append(depends, ruleFiles);
  }
}

void cmLocalUnixMakefileGenerator3::AppendCustomDepends(
  std::vector<std::string>& depends, std::vector<cmCustomCommand> const& ccs)
{
  for (cmCustomCommand const& cc : ccs) {
    cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
    this->AppendCustomDepend(depends, ccg);
  }
}

void cmLocalUnixMakefileGenerator3::AppendCustomDepend(
  std::vector<std::string>& depends, cmCustomCommandGenerator const& ccg)
{
  for (std::string const& d : ccg.GetDepends()) {
    // Lookup the real name of the dependency in case it is a CMake target.
    std::string dep;
    if (this->GetRealDependency(d, this->GetConfigName(), dep)) {
      depends.push_back(std::move(dep));
    }
  }
}

void cmLocalUnixMakefileGenerator3::AppendCustomCommands(
  std::vector<std::string>& commands, std::vector<cmCustomCommand> const& ccs,
  cmGeneratorTarget* target, std::string const& relative)
{
  for (cmCustomCommand const& cc : ccs) {
    cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
    this->AppendCustomCommand(commands, ccg, target, relative, true);
  }
}

void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
  std::vector<std::string>& commands, cmCustomCommandGenerator const& ccg,
  cmGeneratorTarget* target, std::string const& relative, bool echo_comment,
  std::ostream* content)
{
  // Optionally create a command to display the custom command's
  // comment text.  This is used for pre-build, pre-link, and
  // post-build command comments.  Custom build step commands have
  // their comments generated elsewhere.
  if (echo_comment) {
    if (cm::optional<std::string> comment = ccg.GetComment()) {
      this->AppendEcho(commands, *comment,
                       cmLocalUnixMakefileGenerator3::EchoGenerate);
    }
  }

  // if the command specified a working directory use it.
  std::string dir = this->GetCurrentBinaryDirectory();
  std::string workingDir = ccg.GetWorkingDirectory();
  if (!workingDir.empty()) {
    dir = workingDir;
  }
  if (content) {
    *content << dir;
  }

  auto rulePlaceholderExpander = this->CreateRulePlaceholderExpander();

  // Add each command line to the set of commands.
  std::vector<std::string> commands1;
  for (unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) {
    // Build the command line in a single string.
    std::string cmd = ccg.GetCommand(c);
    if (!cmd.empty()) {
      // Use "call " before any invocations of .bat or .cmd files
      // invoked as custom commands in the WindowsShell.
      //
      bool useCall = false;

      if (this->IsWindowsShell()) {
        std::string suffix;
        if (cmd.size() > 4) {
          suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size() - 4));
          if (suffix == ".bat" || suffix == ".cmd") {
            useCall = true;
          }
        }
      }

      cmSystemTools::ReplaceString(cmd, "/./", "/");
      // Convert the command to a relative path only if the current
      // working directory will be the start-output directory.
      bool had_slash = cmd.find('/') != std::string::npos;
      if (workingDir.empty()) {
        cmd = this->MaybeRelativeToCurBinDir(cmd);
      }
      bool has_slash = cmd.find('/') != std::string::npos;
      if (had_slash && !has_slash) {
        // This command was specified as a path to a file in the
        // current directory.  Add a leading "./" so it can run
        // without the current directory being in the search path.
        cmd = cmStrCat("./", cmd);
      }

      std::string launcher;
      // Short-circuit if there is no launcher.
      std::string val = this->GetRuleLauncher(
        target, "RULE_LAUNCH_CUSTOM",
        this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
      if (cmNonempty(val)) {
        // Expand rule variables referenced in the given launcher command.
        cmRulePlaceholderExpander::RuleVariables vars;
        vars.CMTargetName = target->GetName().c_str();
        vars.CMTargetType =
          cmState::GetTargetTypeName(target->GetType()).c_str();
        vars.CMTargetLabels = target->GetTargetLabelsString().c_str();
        std::string output;
        std::vector<std::string> const& outputs = ccg.GetOutputs();
        for (size_t i = 0; i < outputs.size(); ++i) {
          output = cmStrCat(output,
                            this->ConvertToOutputFormat(
                              ccg.GetWorkingDirectory().empty()
                                ? this->MaybeRelativeToCurBinDir(outputs[i])
                                : outputs[i],
                              cmOutputConverter::SHELL));
          if (i != outputs.size() - 1) {
            output = cmStrCat(output, ",");
          }
        }
        vars.Output = output.c_str();
        vars.Role = ccg.GetCC().GetRole().c_str();

        launcher = val;
        rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
        if (!launcher.empty()) {
          launcher += " ";
        }
      }

      std::string shellCommand = this->MaybeConvertWatcomShellCommand(cmd);
      if (shellCommand.empty()) {
        shellCommand =
          this->ConvertToOutputFormat(cmd, cmOutputConverter::SHELL);
      }
      cmd = launcher + shellCommand;

      ccg.AppendArguments(c, cmd);
      if (content) {
        // Rule content does not include the launcher.
        *content << (cmd.c_str() + launcher.size());
      }
      if (this->BorlandMakeCurlyHack) {
        // Borland Make has a very strange bug.  If the first curly
        // brace anywhere in the command string is a left curly, it
        // must be written {{} instead of just {.  Otherwise some
        // curly braces are removed.  The hack can be skipped if the
        // first curly brace is the last character.
        std::string::size_type lcurly = cmd.find('{');
        if (lcurly != std::string::npos && lcurly < (cmd.size() - 1)) {
          std::string::size_type rcurly = cmd.find('}');
          if (rcurly == std::string::npos || rcurly > lcurly) {
            // The first curly is a left curly.  Use the hack.
            cmd =
              cmStrCat(cmd.substr(0, lcurly), "{{}", cmd.substr(lcurly + 1));
          }
        }
      }
      if (launcher.empty()) {
        if (useCall) {
          cmd = cmStrCat("call ", cmd);
        } else if (this->IsNMake() && cmd[0] == '"') {
          cmd = cmStrCat("echo >nul && ", cmd);
        }
      }
      commands1.push_back(std::move(cmd));
    }
  }

  // Setup the proper working directory for the commands.
  this->CreateCDCommand(commands1, dir, relative);

  cmGlobalUnixMakefileGenerator3* gg =
    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);

  // Prefix the commands with the jobserver prefix "+"
  if (ccg.GetCC().GetJobserverAware() && gg->IsGNUMakeJobServerAware()) {
    std::transform(commands1.begin(), commands1.end(), commands1.begin(),
                   [](std::string const& cmd) { return cmStrCat("+", cmd); });
  }

  // push back the custom commands
  cm::append(commands, commands1);
}

void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
  std::vector<std::string>& commands, std::set<std::string> const& files,
  cmGeneratorTarget* target, char const* filename)
{
  std::string currentBinDir = this->GetCurrentBinaryDirectory();
  std::string cleanfile = cmStrCat(
    currentBinDir, '/', this->GetTargetDirectory(target), "/cmake_clean");
  if (filename) {
    cleanfile += "_";
    cleanfile += filename;
  }
  cleanfile += ".cmake";
  cmsys::ofstream fout(cleanfile.c_str());
  if (!fout) {
    cmSystemTools::Error("Could not create " + cleanfile);
  }
  if (!files.empty()) {
    fout << "file(REMOVE_RECURSE\n";
    for (std::string const& file : files) {
      std::string fc = this->MaybeRelativeToCurBinDir(file);
      fout << "  " << cmOutputConverter::EscapeForCMake(fc) << '\n';
    }
    fout << ")\n";
  }
  {
    std::string remove = cmStrCat(
      "$(CMAKE_COMMAND) -P ",
      this->ConvertToOutputFormat(this->MaybeRelativeToCurBinDir(cleanfile),
                                  cmOutputConverter::SHELL));
    commands.push_back(std::move(remove));
  }

  // For the main clean rule add per-language cleaning.
  if (!filename) {
    // Get the set of source languages in the target.
    std::set<std::string> languages;
    target->GetLanguages(
      languages, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
    /* clang-format off */
    fout << "\n"
            "# Per-language clean rules from dependency scanning.\n"
            "foreach(lang " << cmJoin(languages, " ") << ")\n"
            "  include(" << this->GetTargetDirectory(target)
         << "/cmake_clean_${lang}.cmake OPTIONAL)\n"
            "endforeach()\n";
    /* clang-format on */
  }
}

void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
  std::vector<std::string>& commands)
{
  cmList cleanFiles;
  // Look for additional files registered for cleaning in this directory.
  if (cmValue prop_value =
        this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
    cleanFiles.assign(cmGeneratorExpression::Evaluate(
      *prop_value, this,
      this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")));
  }
  if (cleanFiles.empty()) {
    return;
  }

  auto const& rootLG = this->GetGlobalGenerator()->GetLocalGenerators().at(0);
  std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory();
  std::string cleanfile =
    cmStrCat(currentBinaryDir, "/CMakeFiles/cmake_directory_clean.cmake");
  // Write clean script
  {
    cmsys::ofstream fout(cleanfile.c_str());
    if (!fout) {
      cmSystemTools::Error("Could not create " + cleanfile);
      return;
    }
    fout << "file(REMOVE_RECURSE\n";
    for (std::string const& cfl : cleanFiles) {
      std::string fc = rootLG->MaybeRelativeToCurBinDir(
        cmSystemTools::CollapseFullPath(cfl, currentBinaryDir));
      fout << "  " << cmOutputConverter::EscapeForCMake(fc) << '\n';
    }
    fout << ")\n";
  }
  // Create command
  {
    std::string remove = cmStrCat(
      "$(CMAKE_COMMAND) -P ",
      this->ConvertToOutputFormat(rootLG->MaybeRelativeToCurBinDir(cleanfile),
                                  cmOutputConverter::SHELL));
    commands.push_back(std::move(remove));
  }
}

void cmLocalUnixMakefileGenerator3::AppendEcho(
  std::vector<std::string>& commands, std::string const& text, EchoColor color,
  EchoProgress const* progress)
{
  // Choose the color for the text.
  std::string color_name;
  if (this->GlobalGenerator->GetToolSupportsColor() && this->ColorMakefile) {
    // See cmake::ExecuteEchoColor in cmake.cxx for these options.
    // This color set is readable on both black and white backgrounds.
    switch (color) {
      case EchoNormal:
        break;
      case EchoDepend:
        color_name = "--magenta --bold ";
        break;
      case EchoBuild:
        color_name = "--green ";
        break;
      case EchoLink:
        color_name = "--green --bold ";
        break;
      case EchoGenerate:
        color_name = "--blue --bold ";
        break;
      case EchoGlobal:
        color_name = "--cyan ";
        break;
    }
  }

  // Echo one line at a time.
  std::string line;
  line.reserve(200);
  for (char const* c = text.c_str();; ++c) {
    if (*c == '\n' || *c == '\0') {
      // Avoid writing a blank last line on end-of-string.
      if (*c != '\0' || !line.empty()) {
        // Add a command to echo this line.
        std::string cmd;
        if (color_name.empty() && !progress) {
          // Use the native echo command.
          cmd = cmStrCat("@echo ", this->EscapeForShell(line, false, true));
        } else {
          // Use cmake to echo the text in color.
          cmd = cmStrCat(
            "@$(CMAKE_COMMAND) -E cmake_echo_color \"--switch=$(COLOR)\" ",
            color_name);
          if (progress) {
            cmd = cmStrCat(cmd, "--progress-dir=",
                           this->ConvertToOutputFormat(
                             progress->Dir, cmOutputConverter::SHELL),
                           " --progress-num=", progress->Arg, ' ');
          }
          cmd += this->EscapeForShell(line);
        }
        commands.emplace_back(std::move(cmd));
      }

      // Reset the line to empty.
      line.clear();

      // Progress appears only on first line.
      progress = nullptr;

      // Terminate on end-of-string.
      if (*c == '\0') {
        return;
      }
    } else if (*c != '\r') {
      // Append this character to the current line.
      line += *c;
    }
  }
}

std::string cmLocalUnixMakefileGenerator3::CreateMakeVariable(
  std::string const& s, std::string const& s2)
{
  std::string unmodified = cmStrCat(s, s2);
  // if there is no restriction on the length of make variables
  // and there are no "." characters in the string, then return the
  // unmodified combination.
  if ((!this->MakefileVariableSize &&
       unmodified.find('.') == std::string::npos) &&
      (!this->MakefileVariableSize &&
       unmodified.find('+') == std::string::npos) &&
      (!this->MakefileVariableSize &&
       unmodified.find('-') == std::string::npos)) {
    return unmodified;
  }

  // see if the variable has been defined before and return
  // the modified version of the variable
  auto i = this->MakeVariableMap.find(unmodified);
  if (i != this->MakeVariableMap.end()) {
    return i->second;
  }
  // start with the unmodified variable
  std::string ret = unmodified;
  // if this there is no value for this->MakefileVariableSize then
  // the string must have bad characters in it
  if (!this->MakefileVariableSize) {
    std::replace(ret.begin(), ret.end(), '.', '_');
    cmSystemTools::ReplaceString(ret, "-", "__");
    cmSystemTools::ReplaceString(ret, "+", "___");
    int ni = 0;
    char buffer[12];
    // make sure the _ version is not already used, if
    // it is used then add number to the end of the variable
    while (this->ShortMakeVariableMap.count(ret) && ni < 1000) {
      ++ni;
      snprintf(buffer, sizeof(buffer), "%04d", ni);
      ret = unmodified + buffer;
    }
    this->ShortMakeVariableMap[ret] = "1";
    this->MakeVariableMap[unmodified] = ret;
    return ret;
  }

  // if the string is greater than 32 chars it is an invalid variable name
  // for borland make
  if (static_cast<int>(ret.size()) > this->MakefileVariableSize) {
    int keep = this->MakefileVariableSize - 8;
    int size = keep + 3;
    std::string str1 = s;
    std::string str2 = s2;
    // we must shorten the combined string by 4 characters
    // keep no more than 24 characters from the second string
    if (static_cast<int>(str2.size()) > keep) {
      str2 = str2.substr(0, keep);
    }
    if (static_cast<int>(str1.size()) + static_cast<int>(str2.size()) > size) {
      str1 = str1.substr(0, size - str2.size());
    }
    char buffer[12];
    int ni = 0;
    snprintf(buffer, sizeof(buffer), "%04d", ni);
    ret = str1 + str2 + buffer;
    while (this->ShortMakeVariableMap.count(ret) && ni < 1000) {
      ++ni;
      snprintf(buffer, sizeof(buffer), "%04d", ni);
      ret = str1 + str2 + buffer;
    }
    if (ni == 1000) {
      cmSystemTools::Error("Borland makefile variable length too long");
      return unmodified;
    }
    // once an unused variable is found
    this->ShortMakeVariableMap[ret] = "1";
  }
  // always make an entry into the unmodified to variable map
  this->MakeVariableMap[unmodified] = ret;
  return ret;
}

bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
  std::string const& tgtInfo, bool verbose, bool color)
{
  // read in the target info file
  if (!this->Makefile->ReadListFile(tgtInfo) ||
      cmSystemTools::GetErrorOccurredFlag()) {
    cmSystemTools::Error("Target DependInfo.cmake file not found");
  }

  bool status = true;

  // Check if any multiple output pairs have a missing file.
  this->CheckMultipleOutputs(verbose);

  std::string const targetDir = cmSystemTools::GetFilenamePath(tgtInfo);
  if (!this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES").empty()) {
    // dependencies are managed by CMake itself

    std::string const internalDependFile = targetDir + "/depend.internal";
    std::string const dependFile = targetDir + "/depend.make";

    // If the target DependInfo.cmake file has changed since the last
    // time dependencies were scanned then force rescanning.  This may
    // happen when a new source file is added and CMake regenerates the
    // project but no other sources were touched.
    bool needRescanDependInfo = false;
    cmFileTimeCache* ftc =
      this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache();
    {
      int result;
      if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
        if (verbose) {
          cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
                                         "\" is newer than depender \"",
                                         internalDependFile, "\".\n"));
        }
        needRescanDependInfo = true;
      }
    }

    // If the directory information is newer than depend.internal, include
    // dirs may have changed. In this case discard all old dependencies.
    bool needRescanDirInfo = false;
    {
      std::string dirInfoFile =
        cmStrCat(this->GetCurrentBinaryDirectory(),
                 "/CMakeFiles/CMakeDirectoryInformation.cmake");
      int result;
      if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
          result < 0) {
        if (verbose) {
          cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
                                         "\" is newer than depender \"",
                                         internalDependFile, "\".\n"));
        }
        needRescanDirInfo = true;
      }
    }

    // Check the implicit dependencies to see if they are up to date.
    // The build.make file may have explicit dependencies for the object
    // files but these will not affect the scanning process so they need
    // not be considered.
    cmDepends::DependencyMap validDependencies;
    bool needRescanDependencies = false;
    if (!needRescanDirInfo) {
      cmDependsC checker;
      checker.SetVerbose(verbose);
      checker.SetFileTimeCache(ftc);
      // cmDependsC::Check() fills the vector validDependencies() with the
      // dependencies for those files where they are still valid, i.e.
      // neither the files themselves nor any files they depend on have
      // changed. We don't do that if the CMakeDirectoryInformation.cmake
      // file has changed, because then potentially all dependencies have
      // changed. This information is given later on to cmDependsC, which
      // then only rescans the files where it did not get valid dependencies
      // via this dependency vector. This means that in the normal case, when
      // only few or one file have been edited, then also only this one file
      // is actually scanned again, instead of all files for this target.
      needRescanDependencies =
        !checker.Check(dependFile, internalDependFile, validDependencies);
    }

    if (needRescanDependInfo || needRescanDirInfo || needRescanDependencies) {
      // The dependencies must be regenerated.
      if (verbose) {
        std::string targetName = cmSystemTools::GetFilenameName(targetDir);
        targetName = targetName.substr(0, targetName.length() - 4);
        std::string message =
          cmStrCat("Scanning dependencies of target ", targetName);
        cmSystemTools::MakefileColorEcho(
          cmsysTerminal_Color_ForegroundMagenta |
            cmsysTerminal_Color_ForegroundBold,
          message.c_str(), true, color);
      }

      status = this->ScanDependencies(targetDir, dependFile,
                                      internalDependFile, validDependencies);
    }
  }

  auto depends =
    this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
  if (!depends.empty()) {
    // dependencies are managed by compiler
    cmList depFiles{ depends, cmList::EmptyElements::Yes };
    std::string const internalDepFile =
      targetDir + "/compiler_depend.internal";
    std::string const depFile = targetDir + "/compiler_depend.make";
    cmDepends::DependencyMap dependencies;
    cmDependsCompiler depsManager;
    bool projectOnly = cmIsOn(
      this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_IN_PROJECT_ONLY"));

    depsManager.SetVerbose(verbose);
    depsManager.SetLocalGenerator(this);

    if (!depsManager.CheckDependencies(
          internalDepFile, depFiles, dependencies,
          projectOnly ? NotInProjectDir(this->GetSourceDirectory(),
                                        this->GetBinaryDirectory())
                      : std::function<bool(std::string const&)>())) {
      // regenerate dependencies files
      if (verbose) {
        std::string targetName = cmCMakePath(targetDir)
                                   .GetFileName()
                                   .RemoveExtension()
                                   .GenericString();
        auto message =
          cmStrCat("Consolidate compiler generated dependencies of target ",
                   targetName);
        cmSystemTools::MakefileColorEcho(
          cmsysTerminal_Color_ForegroundMagenta |
            cmsysTerminal_Color_ForegroundBold,
          message.c_str(), true, color);
      }

      // Open the make depends file.  This should be copy-if-different
      // because the make tool may try to reload it needlessly otherwise.
      cmGeneratedFileStream ruleFileStream(
        depFile, false, this->GlobalGenerator->GetMakefileEncoding());
      ruleFileStream.SetCopyIfDifferent(true);
      if (!ruleFileStream) {
        return false;
      }

      // Open the cmake dependency tracking file.  This should not be
      // copy-if-different because dependencies are re-scanned when it is
      // older than the DependInfo.cmake.
      cmGeneratedFileStream internalRuleFileStream(
        internalDepFile, false, this->GlobalGenerator->GetMakefileEncoding());
      if (!internalRuleFileStream) {
        return false;
      }

      this->WriteDisclaimer(ruleFileStream);
      this->WriteDisclaimer(internalRuleFileStream);

      depsManager.WriteDependencies(dependencies, ruleFileStream,
                                    internalRuleFileStream);
    }
  }

  // The dependencies are already up-to-date.
  return status;
}

bool cmLocalUnixMakefileGenerator3::ScanDependencies(
  std::string const& targetDir, std::string const& dependFile,
  std::string const& internalDependFile, cmDepends::DependencyMap& validDeps)
{
  // Read the directory information file.
  cmMakefile* mf = this->Makefile;
  bool haveDirectoryInfo = false;
  {
    std::string dirInfoFile =
      cmStrCat(this->GetCurrentBinaryDirectory(),
               "/CMakeFiles/CMakeDirectoryInformation.cmake");
    if (mf->ReadListFile(dirInfoFile) &&
        !cmSystemTools::GetErrorOccurredFlag()) {
      haveDirectoryInfo = true;
    }
  }

  // Lookup useful directory information.
  if (haveDirectoryInfo) {
    // Test whether we need to force Unix paths.
    if (cmValue force = mf->GetDefinition("CMAKE_FORCE_UNIX_PATHS")) {
      if (!force.IsOff()) {
        cmSystemTools::SetForceUnixPaths(true);
      }
    }

    // Setup relative path top directories.
    cmValue relativePathTopSource =
      mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE");
    cmValue relativePathTopBinary =
      mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY");
    if (relativePathTopSource && relativePathTopBinary) {
      this->SetRelativePathTop(*relativePathTopSource, *relativePathTopBinary);
    }
  } else {
    cmSystemTools::Error("Directory Information file not found");
  }

  // Open the make depends file.  This should be copy-if-different
  // because the make tool may try to reload it needlessly otherwise.
  cmGeneratedFileStream ruleFileStream(
    dependFile, false, this->GlobalGenerator->GetMakefileEncoding());
  ruleFileStream.SetCopyIfDifferent(true);
  if (!ruleFileStream) {
    return false;
  }

  // Open the cmake dependency tracking file.  This should not be
  // copy-if-different because dependencies are re-scanned when it is
  // older than the DependInfo.cmake.
  cmGeneratedFileStream internalRuleFileStream(
    internalDependFile, false, this->GlobalGenerator->GetMakefileEncoding());
  if (!internalRuleFileStream) {
    return false;
  }

  this->WriteDisclaimer(ruleFileStream);
  this->WriteDisclaimer(internalRuleFileStream);

  // for each language we need to scan, scan it
  cmList langs{ mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES") };
  for (std::string const& lang : langs) {
    // construct the checker
    // Create the scanner for this language
    std::unique_ptr<cmDepends> scanner;
    if (lang == "C" || lang == "CXX" || lang == "RC" || lang == "ASM" ||
        lang == "OBJC" || lang == "OBJCXX" || lang == "CUDA" ||
        lang == "HIP" || lang == "ISPC") {
      // TODO: Handle RC (resource files) dependencies correctly.
      scanner = cm::make_unique<cmDependsC>(this, targetDir, lang, &validDeps);
    }
#ifndef CMAKE_BOOTSTRAP
    else if (lang == "Fortran") {
      ruleFileStream << "# Note that incremental build could trigger "
                        "a call to cmake_copy_f90_mod on each re-build\n";
      scanner = cm::make_unique<cmDependsFortran>(this);
    } else if (lang == "Java") {
      scanner = cm::make_unique<cmDependsJava>();
    }
#endif

    if (scanner) {
      scanner->SetLocalGenerator(this);
      scanner->SetFileTimeCache(
        this->GlobalGenerator->GetCMakeInstance()->GetFileTimeCache());
      scanner->SetLanguage(lang);
      scanner->SetTargetDirectory(targetDir);
      scanner->Write(ruleFileStream, internalRuleFileStream);
    }
  }

  return true;
}

void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
{
  cmMakefile* mf = this->Makefile;

  // Get the string listing the multiple output pairs.
  cmValue pairs_string = mf->GetDefinition("CMAKE_MULTIPLE_OUTPUT_PAIRS");
  if (!pairs_string) {
    return;
  }

  // Convert the string to a list and preserve empty entries.
  cmList pairs{ *pairs_string, cmList::EmptyElements::Yes };
  for (auto i = pairs.begin(); i != pairs.end() && (i + 1) != pairs.end();) {
    std::string const& depender = *i++;
    std::string const& dependee = *i++;

    // If the depender is missing then delete the dependee to make
    // sure both will be regenerated.
    if (cmSystemTools::FileExists(dependee) &&
        !cmSystemTools::FileExists(depender)) {
      if (verbose) {
        cmSystemTools::Stdout(cmStrCat(
          "Deleting primary custom command output \"", dependee,
          "\" because another output \"", depender, "\" does not exist.\n"));
      }
      cmSystemTools::RemoveFile(dependee);
    }
  }
}

void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
  std::ostream& ruleFileStream)
{
  this->WriteDisclaimer(ruleFileStream);

  // Write the main entry point target.  This must be the VERY first
  // target so that make with no arguments will run it.
  {
    // Just depend on the all target to drive the build.
    std::vector<std::string> depends;
    std::vector<std::string> no_commands;
    depends.emplace_back("all");

    // Write the rule.
    this->WriteMakeRule(ruleFileStream,
                        "Default target executed when no arguments are "
                        "given to make.",
                        "default_target", depends, no_commands, true);

    // Help out users that try "gmake target1 target2 -j".
    cmGlobalUnixMakefileGenerator3* gg =
      static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
    if (gg->AllowNotParallel()) {
      std::vector<std::string> no_depends;
      this->WriteMakeRule(ruleFileStream,
                          "Allow only one \"make -f "
                          "Makefile2\" at a time, but pass "
                          "parallelism.",
                          ".NOTPARALLEL", no_depends, no_commands, false);
    }
  }

  this->WriteSpecialTargetsTop(ruleFileStream);

  // Include the progress variables for the target.
  // Write all global targets
  this->WriteDivider(ruleFileStream);
  ruleFileStream << "# Targets provided globally by CMake.\n"
                    "\n";
  auto const& targets = this->GetGeneratorTargets();
  for (auto const& gt : targets) {
    if (gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
      std::string targetString =
        "Special rule for the target " + gt->GetName();
      std::vector<std::string> commands;
      std::vector<std::string> depends;

      cmValue p = gt->GetProperty("EchoString");
      char const* text = p ? p->c_str() : "Running external command ...";
      depends.reserve(gt->GetUtilities().size());
      for (BT<std::pair<std::string, bool>> const& u : gt->GetUtilities()) {
        depends.push_back(u.Value.first);
      }
      this->AppendEcho(commands, text,
                       cmLocalUnixMakefileGenerator3::EchoGlobal);

      // Global targets store their rules in pre- and post-build commands.
      this->AppendCustomDepends(depends, gt->GetPreBuildCommands());
      this->AppendCustomDepends(depends, gt->GetPostBuildCommands());
      this->AppendCustomCommands(commands, gt->GetPreBuildCommands(), gt.get(),
                                 this->GetCurrentBinaryDirectory());
      this->AppendCustomCommands(commands, gt->GetPostBuildCommands(),
                                 gt.get(), this->GetCurrentBinaryDirectory());
      std::string targetName = gt->GetName();
      this->WriteMakeRule(ruleFileStream, targetString.c_str(), targetName,
                          depends, commands, true);

      // Provide a "/fast" version of the target.
      depends.clear();
      if ((targetName == "install") || (targetName == "install/local") ||
          (targetName == "install/strip")) {
        // Provide a fast install target that does not depend on all
        // but has the same command.
        depends.emplace_back("preinstall/fast");
      } else {
        // Just forward to the real target so at least it will work.
        depends.push_back(targetName);
        commands.clear();
      }
      targetName += "/fast";
      this->WriteMakeRule(ruleFileStream, targetString.c_str(), targetName,
                          depends, commands, true);
    }
  }

  std::vector<std::string> depends;
  std::vector<std::string> commands;

  // Write the all rule.
  std::string recursiveTarget =
    cmStrCat(this->GetCurrentBinaryDirectory(), "/all");

  bool regenerate =
    !this->GlobalGenerator->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
  if (regenerate) {
    depends.emplace_back("cmake_check_build_system");
  }

  std::string const progressDir = this->ConvertToOutputFormat(
    cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles"),
    cmOutputConverter::SHELL);
  std::string const progressMarks = this->ConvertToOutputFormat(
    this->ConvertToFullPath("/CMakeFiles/progress.marks"),
    cmOutputConverter::SHELL);
  std::string const progressStartCommand =
    cmStrCat("$(CMAKE_COMMAND) -E cmake_progress_start ", progressDir, ' ',
             progressMarks);
  std::string const progressFinishCommand =
    cmStrCat("$(CMAKE_COMMAND) -E cmake_progress_start ", progressDir, " 0");

  commands.emplace_back(progressStartCommand);
  std::string mf2Dir = "CMakeFiles/Makefile2";
  commands.push_back(this->GetRecursiveMakeCall(mf2Dir, recursiveTarget));
  this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                        this->GetCurrentBinaryDirectory());
  commands.emplace_back(progressFinishCommand);
  this->WriteMakeRule(ruleFileStream, "The main all target", "all", depends,
                      commands, true);

  // Write the codegen rule.
  if (this->GetGlobalGenerator()->CheckCMP0171()) {
    recursiveTarget = cmStrCat(this->GetCurrentBinaryDirectory(), "/codegen");
    depends.clear();
    commands.clear();
    if (regenerate) {
      depends.emplace_back("cmake_check_build_system");
    }
    commands.emplace_back(progressStartCommand);
    commands.push_back(this->GetRecursiveMakeCall(mf2Dir, recursiveTarget));
    this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                          this->GetCurrentBinaryDirectory());
    commands.emplace_back(progressFinishCommand);
    this->WriteMakeRule(ruleFileStream, "The main codegen target", "codegen",
                        depends, commands, true);
  }

  // Write the clean rule.
  recursiveTarget = cmStrCat(this->GetCurrentBinaryDirectory(), "/clean");
  commands.clear();
  depends.clear();
  commands.push_back(this->GetRecursiveMakeCall(mf2Dir, recursiveTarget));
  this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                        this->GetCurrentBinaryDirectory());
  this->WriteMakeRule(ruleFileStream, "The main clean target", "clean",
                      depends, commands, true);
  commands.clear();
  depends.clear();
  depends.emplace_back("clean");
  this->WriteMakeRule(ruleFileStream, "The main clean target", "clean/fast",
                      depends, commands, true);

  // Write the preinstall rule.
  recursiveTarget = cmStrCat(this->GetCurrentBinaryDirectory(), "/preinstall");
  commands.clear();
  depends.clear();
  cmValue noall =
    this->Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
  if (noall.IsOff()) {
    // Drive the build before installing.
    depends.emplace_back("all");
  } else if (regenerate) {
    // At least make sure the build system is up to date.
    depends.emplace_back("cmake_check_build_system");
  }
  commands.push_back(this->GetRecursiveMakeCall(mf2Dir, recursiveTarget));
  this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                        this->GetCurrentBinaryDirectory());
  this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
                      "preinstall", depends, commands, true);
  depends.clear();
  this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
                      "preinstall/fast", depends, commands, true);

  if (regenerate) {
    // write the depend rule, really a recompute depends rule
    depends.clear();
    commands.clear();
    cmake* cm = this->GlobalGenerator->GetCMakeInstance();
    if (cm->DoWriteGlobVerifyTarget()) {
      std::string rescanRule =
        cmStrCat("$(CMAKE_COMMAND) -P ",
                 this->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
                                             cmOutputConverter::SHELL));
      commands.push_back(rescanRule);
    }
    std::string cmakefileName = "CMakeFiles/Makefile.cmake";
    {
      std::string runRule = cmStrCat(
        "$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) ",
        cm->GetIgnoreCompileWarningAsError() ? "--compile-no-warning-as-error "
                                             : "",
        cm->GetIgnoreLinkWarningAsError() ? "--link-no-warning-as-error " : "",
        "--check-build-system ",
        this->ConvertToOutputFormat(cmakefileName, cmOutputConverter::SHELL),
        " 1");
      commands.push_back(std::move(runRule));
    }
    this->CreateCDCommand(commands, this->GetBinaryDirectory(),
                          this->GetCurrentBinaryDirectory());
    this->WriteMakeRule(ruleFileStream, "clear depends", "depend", depends,
                        commands, true);
  }
}

void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
                                                      bool verbose)
{
  // Get the list of target files to check
  cmValue infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES");
  if (!infoDef) {
    return;
  }
  cmList files{ *infoDef };

  // Each depend information file corresponds to a target.  Clear the
  // dependencies for that target.
  cmDepends clearer;
  clearer.SetVerbose(verbose);
  for (std::string const& file : files) {
    auto snapshot = mf->GetState()->CreateBaseSnapshot();
    cmMakefile lmf(mf->GetGlobalGenerator(), snapshot);
    lmf.ReadListFile(file);

    if (!lmf.GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES").empty()) {
      std::string dir = cmSystemTools::GetFilenamePath(file);

      // Clear the implicit dependency makefile.
      std::string dependFile = dir + "/depend.make";
      clearer.Clear(dependFile);

      // Remove the internal dependency check file to force
      // regeneration.
      std::string internalDependFile = dir + "/depend.internal";
      cmSystemTools::RemoveFile(internalDependFile);
    }

    auto depsFiles = lmf.GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
    if (!depsFiles.empty()) {
      auto dir = cmCMakePath(file).GetParentPath();
      // Clear the implicit dependency makefile.
      auto depFile = cmCMakePath(dir).Append("compiler_depend.make");
      clearer.Clear(depFile.GenericString());

      // Remove the internal dependency check file
      auto internalDepFile =
        cmCMakePath(dir).Append("compiler_depend.internal");
      cmSystemTools::RemoveFile(internalDepFile.GenericString());

      // Touch timestamp file to force dependencies regeneration
      auto DepTimestamp = cmCMakePath(dir).Append("compiler_depend.ts");
      cmSystemTools::Touch(DepTimestamp.GenericString(), true);

      // clear the dependencies files generated by the compiler
      cmList dependencies{ depsFiles, cmList::EmptyElements::Yes };
      cmDependsCompiler depsManager;
      depsManager.SetVerbose(verbose);
      depsManager.ClearDependencies(dependencies);
    }
  }
}

void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
  std::ostream& cmakefileStream, cmGeneratorTarget* target)
{
  // To enable dependencies filtering
  cmakefileStream << "\n"
                     "# Consider dependencies only in project.\n"
                     "set(CMAKE_DEPENDS_IN_PROJECT_ONLY "
                  << (cmIsOn(this->Makefile->GetSafeDefinition(
                        "CMAKE_DEPENDS_IN_PROJECT_ONLY"))
                        ? "ON"
                        : "OFF")
                  << ")\n\n";

  bool requireFortran = false;
  if (target->HaveFortranSources(this->GetConfigName())) {
    requireFortran = true;
  }

  auto const& implicitLangs =
    this->GetImplicitDepends(target, cmDependencyScannerKind::CMake);

  // list the languages
  cmakefileStream << "# The set of languages for which implicit "
                     "dependencies are needed:\n"
                     "set(CMAKE_DEPENDS_LANGUAGES\n";
  for (auto const& implicitLang : implicitLangs) {
    cmakefileStream << "  \"" << implicitLang.first << "\"\n";
    if (requireFortran && implicitLang.first == "Fortran"_s) {
      requireFortran = false;
    }
  }
  if (requireFortran) {
    cmakefileStream << "  \"Fortran\"\n";
  }
  cmakefileStream << "  )\n";

  if (!implicitLangs.empty()) {
    // now list the files for each language
    cmakefileStream
      << "# The set of files for implicit dependencies of each language:\n";
    for (auto const& implicitLang : implicitLangs) {
      auto const& lang = implicitLang.first;

      cmakefileStream << "set(CMAKE_DEPENDS_CHECK_" << lang << '\n';
      auto const& implicitPairs = implicitLang.second;

      // for each file pair
      for (auto const& implicitPair : implicitPairs) {
        for (auto const& di : implicitPair.second) {
          cmakefileStream << "  \"" << di << "\" \"" << implicitPair.first
                          << "\"\n";
        }
      }
      cmakefileStream << "  )\n";

      // Tell the dependency scanner what compiler is used.
      std::string cidVar = cmStrCat("CMAKE_", lang, "_COMPILER_ID");
      cmValue cid = this->Makefile->GetDefinition(cidVar);
      if (cmNonempty(cid)) {
        cmakefileStream << "set(CMAKE_" << lang << "_COMPILER_ID \"" << *cid
                        << "\")\n";
      }

      if (lang == "Fortran") {
        std::string smodSep =
          this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
        std::string smodExt =
          this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
        cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_SEP \"" << smodSep
                        << "\")\n"
                           "set(CMAKE_Fortran_SUBMODULE_EXT \""
                        << smodExt << "\")\n";
      }

      // Build a list of preprocessor definitions for the target.
      std::set<std::string> defines;
      this->GetTargetDefines(target, this->GetConfigName(), lang, defines);
      if (!defines.empty()) {
        cmakefileStream << "\n"
                           "# Preprocessor definitions for this target.\n"
                           "set(CMAKE_TARGET_DEFINITIONS_"
                        << lang << '\n';
        for (std::string const& define : defines) {
          cmakefileStream << "  " << cmOutputConverter::EscapeForCMake(define)
                          << '\n';
        }
        cmakefileStream << "  )\n";
      }

      // Target-specific include directories:
      cmakefileStream << "\n"
                         "# The include file search paths:\n"
                         "set(CMAKE_"
                      << lang << "_TARGET_INCLUDE_PATH\n";
      std::vector<std::string> includes;

      this->GetIncludeDirectories(includes, target, lang,
                                  this->GetConfigName());
      std::string const& binaryDir = this->GetState()->GetBinaryDirectory();
      if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
        std::string const& sourceDir = this->GetState()->GetSourceDirectory();
        cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir));
      }
      for (std::string const& include : includes) {
        cmakefileStream << "  \"" << this->MaybeRelativeToTopBinDir(include)
                        << "\"\n";
      }
      cmakefileStream << "  )\n";
    }

    // Store include transform rule properties.  Write the directory
    // rules first because they may be overridden by later target rules.
    cmList transformRules;
    if (cmValue xform =
          this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
      transformRules.assign(*xform);
    }
    if (cmValue xform =
          target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
      transformRules.append(*xform);
    }
    if (!transformRules.empty()) {
      cmakefileStream << "\nset(CMAKE_INCLUDE_TRANSFORMS\n";
      for (std::string const& tr : transformRules) {
        cmakefileStream << "  " << cmOutputConverter::EscapeForCMake(tr)
                        << '\n';
      }
      cmakefileStream << "  )\n";
    }
  }

  auto const& compilerLangs =
    this->GetImplicitDepends(target, cmDependencyScannerKind::Compiler);

  // list the dependency files managed by the compiler
  cmakefileStream << "\n# The set of dependency files which are needed:\n"
                     "set(CMAKE_DEPENDS_DEPENDENCY_FILES\n";
  for (auto const& compilerLang : compilerLangs) {
    auto const& compilerPairs = compilerLang.second;
    if (compilerLang.first == "CUSTOM"_s) {
      for (auto const& compilerPair : compilerPairs) {
        for (auto const& src : compilerPair.second) {
          cmakefileStream << R"(  "" ")"
                          << this->MaybeRelativeToTopBinDir(compilerPair.first)
                          << R"(" "custom" ")"
                          << this->MaybeRelativeToTopBinDir(src) << "\"\n";
        }
      }
    } else if (compilerLang.first == "LINK"_s) {
      auto depFormat = this->Makefile->GetDefinition(
        cmStrCat("CMAKE_", target->GetLinkerLanguage(this->GetConfigName()),
                 "_LINKER_DEPFILE_FORMAT"));
      for (auto const& compilerPair : compilerPairs) {
        for (auto const& src : compilerPair.second) {
          cmakefileStream << R"(  "" ")"
                          << this->MaybeRelativeToTopBinDir(compilerPair.first)
                          << "\" \"" << depFormat << "\" \""
                          << this->MaybeRelativeToTopBinDir(src) << "\"\n";
        }
      }
    } else {
      auto depFormat = this->Makefile->GetSafeDefinition(
        cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
      for (auto const& compilerPair : compilerPairs) {
        for (auto const& src : compilerPair.second) {
          cmakefileStream << "  \"" << src << "\" \""
                          << this->MaybeRelativeToTopBinDir(compilerPair.first)
                          << "\" \"" << depFormat << "\" \""
                          << this->MaybeRelativeToTopBinDir(compilerPair.first)
                          << ".d\"\n";
        }
      }
    }
  }
  cmakefileStream << "  )\n";
}

void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
{
  os << "# CMAKE generated file: DO NOT EDIT!\n"
        "# Generated by \""
     << this->GlobalGenerator->GetName()
     << "\""
        " Generator, CMake Version "
     << cmVersion::GetMajorVersion() << '.' << cmVersion::GetMinorVersion()
     << "\n\n";
}

std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall(
  std::string const& makefile, std::string const& tgt)
{
  // Call make on the given file.
  std::string cmd = cmStrCat(
    "$(MAKE) $(MAKESILENT) -f ",
    this->ConvertToOutputFormat(makefile, cmOutputConverter::SHELL), ' ');

  cmGlobalUnixMakefileGenerator3* gg =
    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
  // Pass down verbosity level.
  if (!gg->MakeSilentFlag.empty()) {
    cmd += gg->MakeSilentFlag;
    cmd += " ";
  }

  // Most unix makes will pass the command line flags to make down to
  // sub-invoked makes via an environment variable.  However, some
  // makes do not support that, so you have to pass the flags
  // explicitly.
  if (gg->PassMakeflags) {
    cmd += "-$(MAKEFLAGS) ";
  }

  // Add the target.
  if (!tgt.empty()) {
    // The make target is always relative to the top of the build tree.
    std::string tgt2 = this->MaybeRelativeToTopBinDir(tgt);

    // The target may have been written with windows paths.
    cmSystemTools::ConvertToOutputSlashes(tgt2);

    // Escape one extra time if the make tool requires it.
    if (this->MakeCommandEscapeTargetTwice) {
      tgt2 = this->EscapeForShell(tgt2, true, false);
    }

    // The target name is now a string that should be passed verbatim
    // on the command line.
    cmd += this->EscapeForShell(tgt2, true, false);
  }
  return cmd;
}

void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
{
  os << "#======================================"
        "=======================================\n";
}

void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os,
                                                       std::string const& s)
{
  // Write the given string to the stream with escaping to get it back
  // into CMake through the lexical scanner.
  os << '"';
  for (char c : s) {
    if (c == '\\') {
      os << "\\\\";
    } else if (c == '"') {
      os << "\\\"";
    } else {
      os << c;
    }
  }
  os << '"';
}

std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
  std::string const& p, bool useWatcomQuote)
{
  // Split the path into its components.
  std::vector<std::string> components;
  cmSystemTools::SplitPath(p, components);

  // Open the quoted result.
  std::string result;
  if (useWatcomQuote) {
#if defined(_WIN32) && !defined(__CYGWIN__)
    result = "'";
#else
    result = "\"'";
#endif
  } else {
    result = "\"";
  }

  // Return an empty path if there are no components.
  if (!components.empty()) {
    // Choose a slash direction and fix root component.
    char const* slash = "/";
#if defined(_WIN32) && !defined(__CYGWIN__)
    if (!cmSystemTools::GetForceUnixPaths()) {
      slash = "\\";
      for (char& i : components[0]) {
        if (i == '/') {
          i = '\\';
        }
      }
    }
#endif

    // Begin the quoted result with the root component.
    result += components[0];

    if (components.size() > 1) {
      // Now add the rest of the components separated by the proper slash
      // direction for this platform.
      auto compEnd = std::remove(components.begin() + 1, components.end() - 1,
                                 std::string());
      auto compStart = components.begin() + 1;
      result += cmJoin(cmMakeRange(compStart, compEnd), slash);
      // Only the last component can be empty to avoid double slashes.
      result += slash;
      result += components.back();
    }
  }

  // Close the quoted result.
  if (useWatcomQuote) {
#if defined(_WIN32) && !defined(__CYGWIN__)
    result += "'";
#else
    result += "'\"";
#endif
  } else {
    result += "\"";
  }

  return result;
}

std::string cmLocalUnixMakefileGenerator3::GetTargetDirectory(
  cmGeneratorTarget const* target) const
{
  std::string dir = cmStrCat("CMakeFiles/", target->GetName());
#if defined(__VMS)
  dir += "_dir";
#else
  dir += ".dir";
#endif
  return dir;
}

cmLocalUnixMakefileGenerator3::ImplicitDependLanguageMap const&
cmLocalUnixMakefileGenerator3::GetImplicitDepends(
  cmGeneratorTarget const* tgt, cmDependencyScannerKind scanner)
{
  return this->ImplicitDepends[tgt->GetName()][scanner];
}

void cmLocalUnixMakefileGenerator3::AddImplicitDepends(
  cmGeneratorTarget const* tgt, std::string const& lang,
  std::string const& obj, std::string const& src,
  cmDependencyScannerKind scanner)
{
  this->ImplicitDepends[tgt->GetName()][scanner][lang][obj].push_back(src);
}

void cmLocalUnixMakefileGenerator3::CreateCDCommand(
  std::vector<std::string>& commands, std::string const& tgtDir,
  std::string const& relDir)
{
  // do we need to cd?
  if (tgtDir == relDir) {
    return;
  }

  // In a Windows shell we must change drive letter too.  The shell
  // used by NMake and Borland make does not support "cd /d" so this
  // feature simply cannot work with them (Borland make does not even
  // support changing the drive letter with just "d:").
  char const* cd_cmd = this->IsMinGWMake() ? "cd /d " : "cd ";

  cmGlobalUnixMakefileGenerator3* gg =
    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
  if (!gg->UnixCD) {
    // On Windows we must perform each step separately and then change
    // back because the shell keeps the working directory between
    // commands.
    std::string cmd =
      cmStrCat(cd_cmd, this->ConvertToOutputForExisting(tgtDir));
    commands.insert(commands.begin(), cmd);

    // Change back to the starting directory.
    cmd = cmStrCat(cd_cmd, this->ConvertToOutputForExisting(relDir));
    commands.push_back(std::move(cmd));
  } else {
    // On UNIX we must construct a single shell command to change
    // directory and build because make resets the directory between
    // each command.
    std::string outputForExisting = this->ConvertToOutputForExisting(tgtDir);
    std::string prefix = cd_cmd + outputForExisting + " && ";
    std::transform(commands.begin(), commands.end(), commands.begin(),
                   [&prefix](std::string const& s) { return prefix + s; });
  }
}
