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

#include <algorithm>
#include <functional>
#include <map>
#include <sstream>
#include <utility>

#include <cm/memory>
#include <cm/string>
#include <cmext/algorithm>
#include <cmext/memory>

#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGhsMultiGpj.h"
#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmValue.h"
#include "cmVersion.h"
#include "cmake.h"

const char* cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj";
#ifdef __linux__
const char* cmGlobalGhsMultiGenerator::DEFAULT_BUILD_PROGRAM = "gbuild";
#elif defined(_WIN32)
const char* cmGlobalGhsMultiGenerator::DEFAULT_BUILD_PROGRAM = "gbuild.exe";
#endif
const char* cmGlobalGhsMultiGenerator::CHECK_BUILD_SYSTEM_TARGET =
  "RERUN_CMAKE";

cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
  : cmGlobalGenerator(cm)
{
  cm->GetState()->SetGhsMultiIDE(true);
}

cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator() = default;

std::unique_ptr<cmLocalGenerator>
cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmMakefile* mf)
{
  return std::unique_ptr<cmLocalGenerator>(
    cm::make_unique<cmLocalGhsMultiGenerator>(this, mf));
}

cmDocumentationEntry cmGlobalGhsMultiGenerator::GetDocumentation()
{
  return {
    GetActualName(),
    "Generates Green Hills MULTI files (experimental, work-in-progress)."
  };
}

void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
  cmGeneratorTarget* gt) const
{
  // Compute full path to object file directory for this target.
  std::string dir =
    cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
             gt->LocalGenerator->GetTargetDirectory(gt), '/');
  gt->ObjectDirectory = dir;
}

bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
                                                    bool build, cmMakefile* mf)
{
  /* In build mode nothing to be done.
   * Toolset already determined and build tool absolute path is cached.
   */
  if (build) {
    return true;
  }

  /* Determine the absolute directory for the toolset */
  std::string tsp;
  this->GetToolset(mf, tsp, ts);

  /* no toolset was found */
  if (tsp.empty()) {
    return false;
  }

  /* set the build tool to use */
  std::string gbuild(tsp + ((tsp.back() == '/') ? "" : "/") +
                     DEFAULT_BUILD_PROGRAM);
  cmValue prevTool = mf->GetDefinition("CMAKE_MAKE_PROGRAM");

  /* check if the toolset changed from last generate */
  if (cmNonempty(prevTool) && !cmSystemTools::ComparePath(gbuild, *prevTool)) {
    std::string const& e = cmStrCat(
      "toolset build tool: ", gbuild, '\n',
      "Does not match the previously used build tool: ", *prevTool, '\n',
      "Either remove the CMakeCache.txt file and CMakeFiles "
      "directory or choose a different binary directory.");
    mf->IssueMessage(MessageType::FATAL_ERROR, e);
    return false;
  }

  /* store the toolset that is being used for this build */
  mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild, "build program to use",
                         cmStateEnums::INTERNAL, true);

  mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp);

  return true;
}

bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
                                                     cmMakefile* mf)
{
  /* set primary target */
  cmValue t = mf->GetDefinition("GHS_PRIMARY_TARGET");
  if (t.IsOff()) {
    /* Use the value from `-A` or use `arm` */
    std::string arch = "arm";
    if (!cmIsOff(p)) {
      arch = p;
    }
    cmValue platform = mf->GetDefinition("GHS_TARGET_PLATFORM");
    std::string tgt = cmStrCat(arch, '_', platform, ".tgt");

    /* update the primary target name*/
    mf->AddDefinition("GHS_PRIMARY_TARGET", tgt);
  }
  return true;
}

void cmGlobalGhsMultiGenerator::EnableLanguage(
  std::vector<std::string> const& l, cmMakefile* mf, bool optional)
{
  mf->AddDefinition("CMAKE_SYSTEM_NAME", "GHS-MULTI");

  mf->AddDefinition("GHSMULTI", "1"); // identifier for user CMake files

  this->cmGlobalGenerator::EnableLanguage(l, mf, optional);
}

bool cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile* /*mf*/)
{
  // The GHS generator only knows how to lookup its build tool
  // during generation of the project files, but this
  // can only be done after the toolset is specified.

  return true;
}

void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsp,
                                           const std::string& ts)
{
  /* Determine tsp - full path of the toolset from ts (toolset hint via -T) */

  std::string root = mf->GetSafeDefinition("GHS_TOOLSET_ROOT");

  // Check if `-T` was set by user
  if (ts.empty()) {
    // Enter toolset search mode
    std::vector<std::string> output;

    // Make sure root exists...
    if (!cmSystemTools::PathExists(root)) {
      std::string msg =
        "GHS_TOOLSET_ROOT directory \"" + root + "\" does not exist.";
      mf->IssueMessage(MessageType::FATAL_ERROR, msg);
      tsp = "";
      return;
    }

    // Add a directory separator
    if (root.back() != '/') {
      root += "/";
    }

    // Get all compiler directories in toolset root
    cmSystemTools::Glob(root, "comp_[^;]+", output);

    if (output.empty()) {
      // No compiler directories found
      std::string msg =
        "No GHS toolsets found in GHS_TOOLSET_ROOT \"" + root + "\".";
      mf->IssueMessage(MessageType::FATAL_ERROR, msg);
      tsp = "";
    } else {
      // Use latest? version
      tsp = root + output.back();
    }

  } else {
    // Toolset was provided by user
    std::string tryPath;

    // NOTE: CollapseFullPath() will determine if user toolset was full path or
    //       or relative path.
    tryPath = cmSystemTools::CollapseFullPath(ts, root);
    if (!cmSystemTools::FileExists(tryPath)) {
      std::string msg = "GHS toolset \"" + tryPath + "\" does not exist.";
      mf->IssueMessage(MessageType::FATAL_ERROR, msg);
      tsp = "";
    } else {
      tsp = tryPath;
    }
  }
}

void cmGlobalGhsMultiGenerator::WriteFileHeader(std::ostream& fout)
{
  /* clang-format off */
  fout << "#!gbuild\n"
          "#\n"
          "# CMAKE generated file: DO NOT EDIT!\n"
          "# Generated by \"" << GetActualName() << "\""
          " Generator, CMake Version " << cmVersion::GetMajorVersion() << '.'
       << cmVersion::GetMinorVersion() << "\n"
          "#\n\n";
  /* clang-format on */
}

void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
{
  fout << "Commands {\n"
          "  Custom_Rule_Command {\n"
          "    name = \"Custom Rule Command\"\n"
          "    exec = \""
#ifdef _WIN32
          "cmd.exe"
#else
          "/bin/sh"
#endif
          "\"\n"
          "    options = {\"SpecialOptions\"}\n"
          "  }\n"
          "}\n"

          "\n\n"
          "FileTypes {\n"
          "  CmakeRule {\n"
          "    name = \"Custom Rule\"\n"
          "    action = \"&Run\"\n"
          "    extensions = {\""
#ifdef _WIN32
          "bat"
#else
          "sh"
#endif
          "\"}\n"
          "    grepable = false\n"
          "    command = \"Custom Rule Command\"\n"
          "    commandLine = \"$COMMAND "
#ifdef _WIN32
          "/c"
#endif
          " $INPUTFILE\"\n"
          "    progress = \"Processing Custom Rule\"\n"
          "    promoteToFirstPass = true\n"
          "    outputType = \"None\"\n"
          "    color = \"#800080\"\n"
          "  }\n"
          "}\n";
}

void cmGlobalGhsMultiGenerator::WriteCustomTargetBOD(std::ostream& fout)
{
  fout << "FileTypes {\n"
          "  CmakeTarget {\n"
          "    name = \"Custom Target\"\n"
          "    action = \"&Execute\"\n"
          "    grepable = false\n"
          "    outputType = \"None\"\n"
          "    color = \"#800080\"\n"
          "  }\n"
          "}\n";
}

void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
                                                     cmLocalGenerator* root)
{
  this->WriteFileHeader(fout);
  this->WriteMacros(fout, root);
  this->WriteHighLevelDirectives(fout, root);
  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);

  fout << "# Top Level Project File\n";

  // Specify BSP option if supplied by user
  // -- not all platforms require this entry in the project file
  cmValue bspName = root->GetMakefile()->GetDefinition("GHS_BSP_NAME");
  if (!bspName.IsOff()) {
    fout << "    -bsp " << *bspName << '\n';
  }

  // Specify OS DIR if supplied by user
  // -- not all platforms require this entry in the project file
  cmValue osDir = root->GetMakefile()->GetDefinition("GHS_OS_DIR");
  if (!osDir.IsOff()) {
    cmValue osDirOption =
      root->GetMakefile()->GetDefinition("GHS_OS_DIR_OPTION");
    fout << "    ";
    if (osDirOption.IsOff()) {
      fout << "";
    } else {
      fout << *osDirOption;
    }
    fout << "\"" << osDir << "\"\n";
  }
}

void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
                                                 bool filterPredefined)
{
  std::set<std::string> predefinedTargets;
  predefinedTargets.insert(this->GetInstallTargetName());
  predefinedTargets.insert(this->GetAllTargetName());
  predefinedTargets.insert(std::string(CHECK_BUILD_SYSTEM_TARGET));

  // All known targets
  for (cmGeneratorTarget const* target : this->ProjectTargets) {
    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
        target->GetType() == cmStateEnums::MODULE_LIBRARY ||
        target->GetType() == cmStateEnums::SHARED_LIBRARY ||
        (target->GetType() == cmStateEnums::GLOBAL_TARGET &&
         target->GetName() != this->GetInstallTargetName())) {
      continue;
    }
    /* Check if the current target is a predefined CMake target */
    bool predefinedTarget =
      predefinedTargets.find(target->GetName()) != predefinedTargets.end();
    if ((filterPredefined && predefinedTarget) ||
        (!filterPredefined && !predefinedTarget)) {
      fout << target->GetName() + ".tgt" + FILE_EXTENSION << " [Project]\n";
    }
  }
}

void cmGlobalGhsMultiGenerator::WriteProjectLine(
  std::ostream& fout, cmGeneratorTarget const* target,
  std::string& rootBinaryDir)
{
  cmValue projFile = target->GetProperty("GENERATOR_FILE_NAME");
  cmValue projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
  /* If either value is not valid then this particular target is an
   * unsupported target type and should be skipped.
   */
  if (projFile && projType) {
    std::string path = cmSystemTools::RelativePath(rootBinaryDir, *projFile);

    fout << path;
    fout << ' ' << *projType << '\n';
  }
}

void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
{
  std::string rootBinaryDir = root->GetCurrentBinaryDirectory();

  // All known targets
  for (cmGeneratorTarget const* target : this->ProjectTargets) {
    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
        target->GetType() == cmStateEnums::MODULE_LIBRARY ||
        target->GetType() == cmStateEnums::SHARED_LIBRARY ||
        (target->GetType() == cmStateEnums::GLOBAL_TARGET &&
         target->GetName() != this->GetInstallTargetName())) {
      continue;
    }

    // create target build file
    std::string name = cmStrCat(target->GetName(), ".tgt", FILE_EXTENSION);
    std::string fname = cmStrCat(rootBinaryDir, "/", name);
    cmGeneratedFileStream fbld(fname);
    fbld.SetCopyIfDifferent(true);
    this->WriteFileHeader(fbld);
    GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld);
    std::vector<cmGeneratorTarget const*> build;
    if (this->ComputeTargetBuildOrder(target, build)) {
      cmSystemTools::Error(
        cmStrCat("The inter-target dependency graph for target [",
                 target->GetName(), "] had a cycle.\n"));
    } else {
      for (auto& tgt : build) {
        this->WriteProjectLine(fbld, tgt, rootBinaryDir);
      }
    }
    fbld.Close();
  }
}

void cmGlobalGhsMultiGenerator::Generate()
{
  std::string fname;

  // first do the superclass method
  this->cmGlobalGenerator::Generate();

  // output top-level projects
  for (auto& it : this->ProjectMap) {
    this->OutputTopLevelProject(it.second[0], it.second);
  }

  // create custom rule BOD file
  fname = this->GetCMakeInstance()->GetHomeOutputDirectory() +
    "/CMakeFiles/custom_rule.bod";
  cmGeneratedFileStream frule(fname);
  frule.SetCopyIfDifferent(true);
  this->WriteFileHeader(frule);
  this->WriteCustomRuleBOD(frule);
  frule.Close();

  // create custom target BOD file
  fname = this->GetCMakeInstance()->GetHomeOutputDirectory() +
    "/CMakeFiles/custom_target.bod";
  cmGeneratedFileStream ftarget(fname);
  ftarget.SetCopyIfDifferent(true);
  this->WriteFileHeader(ftarget);
  this->WriteCustomTargetBOD(ftarget);
  ftarget.Close();
}

void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
  cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
{
  std::string fname;

  if (generators.empty()) {
    return;
  }

  // Collect all targets under this root generator and the transitive
  // closure of their dependencies.
  TargetDependSet projectTargets;
  TargetDependSet originalTargets;
  this->GetTargetSets(projectTargets, originalTargets, root, generators);
  OrderedTargetDependSet sortedProjectTargets(projectTargets, "");
  this->ProjectTargets.clear();
  for (cmGeneratorTarget const* t : sortedProjectTargets) {
    /* save list of all targets in sorted order */
    this->ProjectTargets.push_back(t);
  }

  /* Name top-level projects as filename.top.gpj to avoid name clashes
   * with target projects.  This avoid the issue where the project has
   * the same name as the executable target.
   */
  fname = cmStrCat(root->GetCurrentBinaryDirectory(), '/',
                   root->GetProjectName(), ".top", FILE_EXTENSION);

  cmGeneratedFileStream top(fname);
  top.SetCopyIfDifferent(true);
  this->WriteTopLevelProject(top, root);
  this->WriteTargets(root);
  this->WriteSubProjects(top, true);
  this->WriteSubProjects(top, false);
  top.Close();
}

std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalGhsMultiGenerator::GenerateBuildCommand(
  const std::string& makeProgram, const std::string& projectName,
  const std::string& projectDir, std::vector<std::string> const& targetNames,
  const std::string& /*config*/, int jobs, bool verbose,
  const cmBuildOptions& /*buildOptions*/,
  std::vector<std::string> const& makeOptions)
{
  GeneratedMakeCommand makeCommand;

  makeCommand.Add(this->SelectMakeProgram(makeProgram));

  if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
    if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
      makeCommand.Add("-parallel");
    } else {
      makeCommand.Add(std::string("-parallel=") + std::to_string(jobs));
    }
  }

  /* determine the top-project file in the project directory */
  std::string proj = projectName + ".top" + FILE_EXTENSION;
  std::vector<std::string> files;
  cmSystemTools::Glob(projectDir, ".*\\.top\\.gpj", files);
  if (!files.empty()) {
    /* use the real top-level project in the directory */
    proj = files.at(0);
  }
  makeCommand.Add("-top", proj);

  /* determine targets to build */
  bool build_all = false;
  if (!targetNames.empty()) {
    for (const auto& tname : targetNames) {
      if (!tname.empty()) {
        if (tname == "clean") {
          makeCommand.Add("-clean");
        } else {
          makeCommand.Add(tname + ".tgt.gpj");
        }
      } else {
        build_all = true;
      }
    }
  } else {
    build_all = true;
  }

  if (build_all) {
    /* transform name to default build */;
    std::string all = std::string(this->GetAllTargetName()) + ".tgt.gpj";
    makeCommand.Add(all);
  }

  if (verbose) {
    makeCommand.Add("-commands");
  }
  makeCommand.Add(makeOptions.begin(), makeOptions.end());

  return { std::move(makeCommand) };
}

void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
                                            cmLocalGenerator* root)
{
  fout << "macro PROJ_NAME=" << root->GetProjectName() << '\n';
  cmValue ghsGpjMacros = root->GetMakefile()->GetDefinition("GHS_GPJ_MACROS");
  if (ghsGpjMacros) {
    cmList expandedList{ *ghsGpjMacros };
    for (std::string const& arg : expandedList) {
      fout << "macro " << arg << '\n';
    }
  }
}

void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
  std::ostream& fout, cmLocalGenerator* root)
{
  /* put primary target and customization files into project file */
  cmValue const tgt = root->GetMakefile()->GetDefinition("GHS_PRIMARY_TARGET");

  /* clang-format off */
  fout << "primaryTarget=" << tgt << "\n"
          "customization=" << root->GetBinaryDirectory()
       << "/CMakeFiles/custom_rule.bod\n"
          "customization=" << root->GetBinaryDirectory()
       << "/CMakeFiles/custom_target.bod" << '\n';
  /* clang-format on */

  cmValue const customization =
    root->GetMakefile()->GetDefinition("GHS_CUSTOMIZATION");
  if (cmNonempty(customization)) {
    fout << "customization="
         << cmGlobalGhsMultiGenerator::TrimQuotes(*customization) << '\n';
    this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
  }
}

std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string str)
{
  cm::erase(str, '"');
  return str;
}

bool cmGlobalGhsMultiGenerator::TargetCompare::operator()(
  cmGeneratorTarget const* l, cmGeneratorTarget const* r) const
{
  // Make sure a given named target is ordered first,
  // e.g. to set ALL_BUILD as the default active project.
  // When the empty string is named this is a no-op.
  if (r->GetName() == this->First) {
    return false;
  }
  if (l->GetName() == this->First) {
    return true;
  }
  return l->GetName() < r->GetName();
}

cmGlobalGhsMultiGenerator::OrderedTargetDependSet::OrderedTargetDependSet(
  TargetDependSet const& targets, std::string const& first)
  : derived(TargetCompare(first))
{
  this->insert(targets.begin(), targets.end());
}

bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder(
  cmGeneratorTarget const* tgt, std::vector<cmGeneratorTarget const*>& build)
{
  std::vector<cmGeneratorTarget const*> t{ tgt };
  return this->ComputeTargetBuildOrder(t, build);
}

bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder(
  std::vector<cmGeneratorTarget const*>& tgt,
  std::vector<cmGeneratorTarget const*>& build)
{
  std::set<cmGeneratorTarget const*> temp;
  std::set<cmGeneratorTarget const*> perm;

  for (const auto* const ti : tgt) {
    bool r = this->VisitTarget(temp, perm, build, ti);
    if (r) {
      return r;
    }
  }
  return false;
}

bool cmGlobalGhsMultiGenerator::VisitTarget(
  std::set<cmGeneratorTarget const*>& temp,
  std::set<cmGeneratorTarget const*>& perm,
  std::vector<cmGeneratorTarget const*>& order, cmGeneratorTarget const* ti)
{
  /* check if permanent mark is set*/
  if (perm.find(ti) == perm.end()) {
    /* set temporary mark; check if revisit*/
    if (temp.insert(ti).second) {
      /* sort targets lexicographically to ensure that nodes are always visited
       * in the same order */
      OrderedTargetDependSet sortedTargets(this->GetTargetDirectDepends(ti),
                                           "");
      for (auto const& di : sortedTargets) {
        if (this->VisitTarget(temp, perm, order, di)) {
          return true;
        }
      }
      /* mark as complete; insert into beginning of list*/
      perm.insert(ti);
      order.push_back(ti);
      return false;
    }
    /* revisiting item - not a DAG */
    return true;
  }
  /* already complete */
  return false;
}

bool cmGlobalGhsMultiGenerator::AddCheckTarget()
{
  // Skip the target if no regeneration is to be done.
  if (this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION")) {
    return false;
  }

  // Get the generators.
  std::vector<std::unique_ptr<cmLocalGenerator>> const& generators =
    this->LocalGenerators;
  auto& lg =
    cm::static_reference_cast<cmLocalGhsMultiGenerator>(generators[0]);

  // The name of the output file for the custom command.
  this->StampFile = lg.GetBinaryDirectory() + std::string("/CMakeFiles/") +
    CHECK_BUILD_SYSTEM_TARGET;

  // Add a custom rule to re-run CMake if any input files changed.
  {
    // Collect the input files used to generate all targets in this
    // project.
    std::vector<std::string> listFiles;
    for (const auto& gen : generators) {
      cm::append(listFiles, gen->GetMakefile()->GetListFiles());
    }

    // Add the cache file.
    listFiles.emplace_back(cmStrCat(
      this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeCache.txt"));

    // Print not implemented warning.
    if (this->GetCMakeInstance()->DoWriteGlobVerifyTarget()) {
      std::ostringstream msg;
      msg << "Any pre-check scripts, such as those generated for file(GLOB "
             "CONFIGURE_DEPENDS), will not be run by gbuild.";
      this->GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_WARNING,
                                             msg.str());
    }

    // Sort the list of input files and remove duplicates.
    std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
    auto newEnd = std::unique(listFiles.begin(), listFiles.end());
    listFiles.erase(newEnd, listFiles.end());

    // Create a rule to re-run CMake and create output file.
    cmCustomCommandLines commandLines;
    commandLines.emplace_back(
      cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), "-E", "rm", "-f",
                          this->StampFile }));
    std::string argS = cmStrCat("-S", lg.GetSourceDirectory());
    std::string argB = cmStrCat("-B", lg.GetBinaryDirectory());
    commandLines.emplace_back(
      cmMakeCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB }));
    commandLines.emplace_back(cmMakeCommandLine(
      { cmSystemTools::GetCMakeCommand(), "-E", "touch", this->StampFile }));

    /* Create the target(Exclude from ALL_BUILD).
     *
     * The build tool, currently, does not support rereading the project files
     * if they get updated. So do not run this target as part of ALL_BUILD.
     */
    auto cc = cm::make_unique<cmCustomCommand>();
    cmTarget* tgt =
      lg.AddUtilityCommand(CHECK_BUILD_SYSTEM_TARGET, true, std::move(cc));
    auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, &lg);
    auto* gt = ptr.get();
    lg.AddGeneratorTarget(std::move(ptr));

    // Add the rule.
    cc = cm::make_unique<cmCustomCommand>();
    cc->SetOutputs(this->StampFile);
    cc->SetDepends(listFiles);
    cc->SetCommandLines(commandLines);
    cc->SetComment("Checking Build System");
    cc->SetEscapeOldStyle(false);
    cc->SetStdPipesUTF8(true);

    if (cmSourceFile* file =
          lg.AddCustomCommandToOutput(std::move(cc), true)) {
      gt->AddSource(file->ResolveFullPath());
    } else {
      cmSystemTools::Error("Error adding rule for " + this->StampFile);
    }
    // Organize in the "predefined targets" folder:
    if (this->UseFolderProperty()) {
      tgt->SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
    }
  }

  return true;
}

void cmGlobalGhsMultiGenerator::AddAllTarget()
{
  // Add a special target that depends on ALL projects for easy build
  // of one configuration only.
  for (auto const& it : this->ProjectMap) {
    std::vector<cmLocalGenerator*> const& gen = it.second;
    // add the ALL_BUILD to the first local generator of each project
    if (!gen.empty()) {
      // Use no actual command lines so that the target itself is not
      // considered always out of date.
      auto cc = cm::make_unique<cmCustomCommand>();
      cc->SetEscapeOldStyle(false);
      cc->SetComment("Build all projects");
      cmTarget* allBuild = gen[0]->AddUtilityCommand(this->GetAllTargetName(),
                                                     true, std::move(cc));

      gen[0]->AddGeneratorTarget(
        cm::make_unique<cmGeneratorTarget>(allBuild, gen[0]));

      // Organize in the "predefined targets" folder:
      if (this->UseFolderProperty()) {
        allBuild->SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
      }

      // Now make all targets depend on the ALL_BUILD target
      for (cmLocalGenerator const* i : gen) {
        for (const auto& tgt : i->GetGeneratorTargets()) {
          // Skip global or imported targets
          if (tgt->GetType() == cmStateEnums::GLOBAL_TARGET ||
              tgt->IsImported()) {
            continue;
          }
          // Skip Exclude From All Targets
          if (!this->IsExcluded(gen[0], tgt.get())) {
            allBuild->AddUtility(tgt->GetName(), false);
          }
        }
      }
    }
  }
}

void cmGlobalGhsMultiGenerator::AddExtraIDETargets()
{
  // Add a special target that depends on ALL projects.
  this->AddAllTarget();

  /* Add Custom Target to check if CMake needs to be rerun.
   *
   * The build tool, currently, does not support rereading the project files
   * if they get updated.  So do not make the other targets dependent on this
   * check.
   */
  this->AddCheckTarget();
}
