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

#include <algorithm>
#include <sstream>
#include <utility>

#include <cm/filesystem>
#include <cm/string_view>
#include <cmext/string_view>

#include "cmComputeLinkInformation.h"
#include "cmGenExContext.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"

cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
  : GeneratorTarget(gt)
  , Makefile(gt->Makefile)
  , LocalCommonGenerator(
      static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
  , GlobalCommonGenerator(static_cast<cmGlobalCommonGenerator*>(
      gt->LocalGenerator->GetGlobalGenerator()))
  , ConfigNames(this->LocalCommonGenerator->GetConfigNames())
{
}

cmCommonTargetGenerator::~cmCommonTargetGenerator() = default;

std::vector<std::string> const& cmCommonTargetGenerator::GetConfigNames() const
{
  return this->ConfigNames;
}

cmValue cmCommonTargetGenerator::GetFeature(std::string const& feature,
                                            std::string const& config)
{
  return this->GeneratorTarget->GetFeature(feature, config);
}

void cmCommonTargetGenerator::AppendFortranFormatFlags(
  std::string& flags, cmSourceFile const& source)
{
  std::string const srcfmt = source.GetSafeProperty("Fortran_FORMAT");
  cmOutputConverter::FortranFormat format =
    cmOutputConverter::GetFortranFormat(srcfmt);
  if (format == cmOutputConverter::FortranFormatNone) {
    std::string const& tgtfmt =
      this->GeneratorTarget->GetSafeProperty("Fortran_FORMAT");
    format = cmOutputConverter::GetFortranFormat(tgtfmt);
  }
  char const* var = nullptr;
  switch (format) {
    case cmOutputConverter::FortranFormatFixed:
      var = "CMAKE_Fortran_FORMAT_FIXED_FLAG";
      break;
    case cmOutputConverter::FortranFormatFree:
      var = "CMAKE_Fortran_FORMAT_FREE_FLAG";
      break;
    default:
      break;
  }
  if (var) {
    this->LocalCommonGenerator->AppendFlags(
      flags, this->Makefile->GetSafeDefinition(var));
  }
}

void cmCommonTargetGenerator::AppendFortranPreprocessFlags(
  std::string& flags, cmSourceFile const& source,
  PreprocessFlagsRequired requires_pp)
{
  std::string const srcpp = source.GetSafeProperty("Fortran_PREPROCESS");
  cmOutputConverter::FortranPreprocess preprocess =
    cmOutputConverter::GetFortranPreprocess(srcpp);
  if (preprocess == cmOutputConverter::FortranPreprocess::Unset) {
    std::string const& tgtpp =
      this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS");
    preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
  }
  char const* var = nullptr;
  switch (preprocess) {
    case cmOutputConverter::FortranPreprocess::Needed:
      if (requires_pp == PreprocessFlagsRequired::YES) {
        var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON";
      }
      break;
    case cmOutputConverter::FortranPreprocess::NotNeeded:
      var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF";
      break;
    default:
      break;
  }
  if (var) {
    this->LocalCommonGenerator->AppendCompileOptions(
      flags, this->Makefile->GetSafeDefinition(var));
  }
}

std::string cmCommonTargetGenerator::GetFlags(std::string const& l,
                                              std::string const& config,
                                              std::string const& arch)
{
  std::string const key = config + arch;

  auto i = this->Configs[key].FlagsByLanguage.find(l);
  if (i == this->Configs[key].FlagsByLanguage.end()) {
    std::string flags;

    this->LocalCommonGenerator->GetTargetCompileFlags(this->GeneratorTarget,
                                                      config, l, flags, arch);

    ByLanguageMap::value_type entry(l, flags);
    i = this->Configs[key].FlagsByLanguage.insert(entry).first;
  }
  return i->second;
}

std::string cmCommonTargetGenerator::GetDefines(std::string const& l,
                                                std::string const& config)
{
  auto i = this->Configs[config].DefinesByLanguage.find(l);
  if (i == this->Configs[config].DefinesByLanguage.end()) {
    std::set<std::string> defines;
    this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget, config,
                                                 l, defines);

    std::string definesString;
    this->LocalCommonGenerator->JoinDefines(defines, definesString, l);

    ByLanguageMap::value_type entry(l, definesString);
    i = this->Configs[config].DefinesByLanguage.insert(entry).first;
  }
  return i->second;
}

std::string cmCommonTargetGenerator::GetIncludes(std::string const& l,
                                                 std::string const& config)
{
  auto i = this->Configs[config].IncludesByLanguage.find(l);
  if (i == this->Configs[config].IncludesByLanguage.end()) {
    std::string includes;
    this->AddIncludeFlags(includes, l, config);
    ByLanguageMap::value_type entry(l, includes);
    i = this->Configs[config].IncludesByLanguage.insert(entry).first;
  }
  return i->second;
}

cmCommonTargetGenerator::LinkedTargetDirs
cmCommonTargetGenerator::GetLinkedTargetDirectories(
  std::string const& lang, std::string const& config) const
{
  LinkedTargetDirs dirs;
  std::set<cmGeneratorTarget const*> forward_emitted;
  std::set<cmGeneratorTarget const*> direct_emitted;
  cmGlobalCommonGenerator* const gg = this->GlobalCommonGenerator;

  enum class Forwarding
  {
    Yes,
    No
  };

  if (cmComputeLinkInformation* cli =
        this->GeneratorTarget->GetLinkInformation(config)) {

    auto findSyntheticTarget =
      [this,
       &config](cmGeneratorTarget const* linkee) -> cmGeneratorTarget const* {
      if (!linkee) {
        return nullptr;
      }

      // Check the map of direct synthetic dependencies for a substitute
      auto const& synthDeps = this->GeneratorTarget->GetSyntheticDeps(config);
      auto it = synthDeps.find(linkee);
      if (it != synthDeps.end() && !it->second.empty()) {
        return it->second.front();
      }

      // Check linked targets to finding synthetic targets for transitive deps
      std::vector<cmGeneratorTarget const*> pending;
      std::set<cmGeneratorTarget const*> visited;
      for (auto const& dep : synthDeps) {
        for (auto const* synth : dep.second) {
          if (synth && visited.insert(synth).second) {
            pending.push_back(synth);
          }
        }
      }

      while (!pending.empty()) {
        auto const* current = pending.back();
        pending.pop_back();
        auto const& transitiveSynthDeps = current->GetSyntheticDeps(config);
        auto itLinkeeSynth = transitiveSynthDeps.find(linkee);
        if (itLinkeeSynth != transitiveSynthDeps.end() &&
            !itLinkeeSynth->second.empty()) {
          return itLinkeeSynth->second.front();
        }
        for (auto const& entry : transitiveSynthDeps) {
          for (auto const* synth : entry.second) {
            if (synth && visited.insert(synth).second) {
              pending.push_back(synth);
            }
          }
        }
      }

      return nullptr;
    };

    auto addLinkedTarget = [this, &lang, &config, &dirs, &direct_emitted,
                            &forward_emitted, &findSyntheticTarget,
                            gg](cmGeneratorTarget const* linkee,
                                Forwarding forward) {
      // Check if the linkee has a synthetic target to use for importing
      cmGeneratorTarget const* mappedLinkee = linkee;
      if (auto const* synth = findSyntheticTarget(linkee)) {
        mappedLinkee = synth;
      }

      if (mappedLinkee &&
          !mappedLinkee->IsImported()
          // Skip targets that build after this one in a static lib cycle.
          && gg->TargetOrderIndexLess(mappedLinkee, this->GeneratorTarget)
          // We can ignore the INTERFACE_LIBRARY items because
          // Target->GetLinkInformation already processed their
          // link interface and they don't have any output themselves.
          && (mappedLinkee->GetType() != cmStateEnums::INTERFACE_LIBRARY
              // Synthesized targets may have relevant rules.
              || mappedLinkee->IsSynthetic()) &&
          ((lang == "CXX"_s && mappedLinkee->HaveCxx20ModuleSources()) ||
           (lang == "Fortran"_s &&
            mappedLinkee->HaveFortranSources(config)))) {
        cmLocalGenerator* lg = mappedLinkee->GetLocalGenerator();
        std::string di = mappedLinkee->GetSupportDirectory();
        if (lg->GetGlobalGenerator()->IsMultiConfig()) {
          di = cmStrCat(di, '/', config);
        }
        if (forward == Forwarding::Yes &&
            forward_emitted.insert(mappedLinkee).second) {
          dirs.Forward.push_back(di);
        }
        if (direct_emitted.insert(mappedLinkee).second) {
          dirs.Direct.emplace_back(di);
        }
      }
    };
    for (auto const& item : cli->GetItems()) {
      if (item.Target) {
        addLinkedTarget(item.Target, Forwarding::No);
      } else if (item.ObjectSource && lang == "Fortran"_s
                 /* Object source files do not have a language associated with
                    them. */
                 /* && item.ObjectSource->GetLanguage() == "Fortran"_s*/) {
        // Fortran modules provided by `$<TARGET_OBJECTS>` as linked items
        // should be collated for use in this target.
        addLinkedTarget(this->LocalCommonGenerator->FindGeneratorTargetToUse(
                          item.ObjectSource->GetObjectLibrary()),
                        Forwarding::Yes);
      }
    }
    for (cmGeneratorTarget const* target : cli->GetExternalObjectTargets()) {
      addLinkedTarget(target, Forwarding::No);
    }
    if (lang == "Fortran"_s) {
      // Fortran modules provided by `$<TARGET_OBJECTS>` as sources should be
      // collated for use in this target.
      for (cmGeneratorTarget const* target :
           this->GeneratorTarget->GetSourceObjectLibraries(config)) {
        addLinkedTarget(target, Forwarding::Yes);
      }
    }
  }
  return dirs;
}

std::string cmCommonTargetGenerator::ComputeTargetCompilePDB(
  std::string const& config) const
{
  std::string compilePdbPath;
  if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) {
    return compilePdbPath;
  }

  compilePdbPath = this->GeneratorTarget->GetCompilePDBPath(config);
  if (compilePdbPath.empty()) {
    // Match VS default: `$(IntDir)vc$(PlatformToolsetVersion).pdb`.
    // A trailing slash tells the toolchain to add its default file name.
    compilePdbPath = this->GeneratorTarget->GetSupportDirectory();
    if (this->GlobalCommonGenerator->IsMultiConfig()) {
      compilePdbPath += "/";
      compilePdbPath += config;
    }
    compilePdbPath += "/";
    if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
      // Match VS default for static libs: `$(IntDir)$(ProjectName).pdb`.
      compilePdbPath += this->GeneratorTarget->GetName();
      compilePdbPath += ".pdb";
    }
  }

  return compilePdbPath;
}

std::string cmCommonTargetGenerator::GetManifests(std::string const& config)
{
  std::vector<cmSourceFile const*> manifest_srcs;
  this->GeneratorTarget->GetManifests(manifest_srcs, config);

  std::vector<std::string> manifests;
  manifests.reserve(manifest_srcs.size());

  std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
  std::string manifestFlag = this->Makefile->GetDefinition(
    cmStrCat("CMAKE_", lang, "_LINKER_MANIFEST_FLAG"));
  for (cmSourceFile const* manifest_src : manifest_srcs) {
    manifests.push_back(manifestFlag +
                        this->LocalCommonGenerator->ConvertToOutputFormat(
                          this->LocalCommonGenerator->MaybeRelativeToWorkDir(
                            manifest_src->GetFullPath()),
                          cmOutputConverter::SHELL));
  }

  return cmJoin(manifests, " ");
}

std::string cmCommonTargetGenerator::GetAIXExports(std::string const&)
{
  std::string aixExports;
  if (this->GeneratorTarget->IsAIX()) {
    if (cmValue exportAll =
          this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) {
      if (exportAll.IsOff()) {
        aixExports = "-n";
      }
    }
  }
  return aixExports;
}

void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
                                               std::string const& lang,
                                               char const* name, bool so)
{
  // Lookup the flag to specify the version.
  std::string fvar = cmStrCat("CMAKE_", lang, "_OSX_", name, "_VERSION_FLAG");
  cmValue flag = this->Makefile->GetDefinition(fvar);

  // Skip if no such flag.
  if (!flag) {
    return;
  }

  // Lookup the target version information.
  int major;
  int minor;
  int patch;
  std::string prop = cmStrCat("MACHO_", name, "_VERSION");
  std::string fallback_prop = so ? "SOVERSION" : "VERSION";
  this->GeneratorTarget->GetTargetVersionFallback(prop, fallback_prop, major,
                                                  minor, patch);
  if (major > 0 || minor > 0 || patch > 0) {
    // Append the flag since a non-zero version is specified.
    std::ostringstream vflag;
    vflag << *flag << major << "." << minor << "." << patch;
    this->LocalCommonGenerator->AppendFlags(flags, vflag.str());
  }
}

std::string cmCommonTargetGenerator::GetCompilerLauncher(
  std::string const& lang, std::string const& config)
{
  std::string compilerLauncher;
  if (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
      lang == "HIP" || lang == "ISPC" || lang == "OBJC" || lang == "OBJCXX") {
    std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
    cmValue clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
    std::string const evaluatedClauncher = cmGeneratorExpression::Evaluate(
      *clauncher, this->GeneratorTarget->GetLocalGenerator(), config,
      this->GeneratorTarget, nullptr, this->GeneratorTarget, lang);
    if (!evaluatedClauncher.empty()) {
      compilerLauncher = evaluatedClauncher;
    }
  }
  return compilerLauncher;
}

std::string cmCommonTargetGenerator::GenerateCodeCheckRules(
  cmSourceFile const& source, std::string& compilerLauncher,
  std::string const& cmakeCmd, std::string const& config,
  std::function<std::string(std::string const&)> const& pathConverter)
{
  auto const lang = source.GetLanguage();
  std::string tidy;
  std::string iwyu;
  std::string cpplint;
  std::string cppcheck;
  std::string icstat;
  std::string pvs;

  auto evaluateProp = [&](std::string const& prop) -> std::string {
    auto const value = this->GeneratorTarget->GetProperty(prop);
    if (!value) {
      return std::string{};
    }
    auto evaluatedProp = cmGeneratorExpression::Evaluate(
      *value, this->GeneratorTarget->GetLocalGenerator(), config,
      this->GeneratorTarget, nullptr, this->GeneratorTarget, lang);
    return evaluatedProp;
  };
  std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
  tidy = evaluateProp(tidy_prop);

  if (lang == "C" || lang == "CXX") {
    std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
    iwyu = evaluateProp(iwyu_prop);

    std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
    cpplint = evaluateProp(cpplint_prop);

    std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
    cppcheck = evaluateProp(cppcheck_prop);

    std::string const icstat_prop = cmStrCat(lang, "_ICSTAT");
    icstat = evaluateProp(icstat_prop);

    std::string const pvs_prop = cmStrCat(lang, "_PVS_STUDIO");
    pvs = evaluateProp(pvs_prop);
  }

  if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
      cmNonempty(cppcheck) || cmNonempty(icstat) || cmNonempty(pvs)) {
    std::string code_check = cmakeCmd + " -E __run_co_compile";
    if (!compilerLauncher.empty()) {
      // In __run_co_compile case the launcher command is supplied
      // via --launcher=<maybe-list> and consumed
      code_check =
        cmStrCat(std::move(code_check), " --launcher=",
                 this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
                   compilerLauncher));
      compilerLauncher.clear();
    }
    if (cmNonempty(iwyu)) {
      code_check += " --iwyu=";

      // Only add --driver-mode if it is not already specified, as adding
      // it unconditionally might override a user-specified driver-mode
      if (iwyu.find("--driver-mode=") == std::string::npos) {
        cmValue const p = this->Makefile->GetDefinition(
          cmStrCat("CMAKE_", lang, "_INCLUDE_WHAT_YOU_USE_DRIVER_MODE"));
        std::string driverMode;

        if (cmNonempty(p)) {
          driverMode = *p;
        } else {
          driverMode = lang == "C" ? "gcc" : "g++";
        }

        code_check +=
          this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
            cmStrCat(iwyu, ";--driver-mode=", driverMode));
      } else {
        code_check +=
          this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(iwyu);
      }
    }
    if (cmNonempty(tidy)) {
      code_check += " --tidy=";
      cmValue const p = this->Makefile->GetDefinition(
        cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE"));
      std::string driverMode;
      if (cmNonempty(p)) {
        driverMode = *p;
      } else {
        driverMode = lang == "C" ? "gcc" : "g++";
      }

      auto const generatorName = this->GeneratorTarget->GetLocalGenerator()
                                   ->GetGlobalGenerator()
                                   ->GetName();
      auto const clangTidyExportFixedDir =
        this->GeneratorTarget->GetClangTidyExportFixesDirectory(lang);
      auto fixesFile = this->GetClangTidyReplacementsFilePath(
        clangTidyExportFixedDir, source, config);
      std::string exportFixes;
      if (!clangTidyExportFixedDir.empty()) {
        this->GlobalCommonGenerator->AddClangTidyExportFixesDir(
          clangTidyExportFixedDir);
      }
      if (generatorName.find("Make") != std::string::npos) {
        if (!clangTidyExportFixedDir.empty()) {
          this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
          cmSystemTools::MakeDirectory(
            cmSystemTools::GetFilenamePath(fixesFile));
          fixesFile = this->GeneratorTarget->GetLocalGenerator()
                        ->MaybeRelativeToCurBinDir(fixesFile);
          exportFixes = cmStrCat(";--export-fixes=", fixesFile);
        }
        code_check +=
          this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
            cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode,
                     exportFixes));
      } else if (generatorName.find("Ninja") != std::string::npos ||
                 generatorName.find("FASTBuild") != std::string::npos) {
        if (!clangTidyExportFixedDir.empty()) {
          this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
          cmSystemTools::MakeDirectory(
            cmSystemTools::GetFilenamePath(fixesFile));
          if (pathConverter) {
            fixesFile = pathConverter(fixesFile);
          }
          exportFixes = cmStrCat(";--export-fixes=", fixesFile);
        }
        code_check +=
          this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
            cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode,
                     exportFixes));
      }
    }
    if (cmNonempty(pvs)) {
      cmMakefile* mf =
        this->GeneratorTarget->GetLocalGenerator()->GetMakefile();
      std::string extraPvsArgs;
      if (lang == "CXX") {
        extraPvsArgs +=
          cmStrCat(";--cxx;", mf->GetDefinition("CMAKE_CXX_COMPILER"));
      } else if (lang == "C") {
        extraPvsArgs +=
          cmStrCat(";--cc;", mf->GetDefinition("CMAKE_C_COMPILER"));
      }
      // cocompile args
      code_check += " --pvs-studio=";
      code_check += this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
        cmStrCat(pvs, extraPvsArgs));
      code_check += " --object=";
      code_check +=
        this->GeneratorTarget->GetLocalGenerator()->ConvertToOutputFormat(
          cmSystemTools::CollapseFullPath(
            cmStrCat(this->GeneratorTarget->GetObjectDirectory(config), '/',
                     this->GeneratorTarget->GetObjectName(&source))),
          cmOutputConverter::SHELL);
    }
    if (cmNonempty(cpplint)) {
      code_check += " --cpplint=";
      code_check +=
        this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(cpplint);
    }
    if (cmNonempty(cppcheck)) {
      code_check += " --cppcheck=";
      code_check +=
        this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(cppcheck);
    }
    if (cmNonempty(icstat)) {
      code_check += " --icstat=";
      std::string checksParam{};
      std::string dbParam{};
      // Set default values for mandatory parameters
      std::string checksFile{ "cstat_sel_checks.txt" };
      std::string dbFile{ "cstat.db" };
      // Populate the command line with C-STAT
      // mandatory parameters unless specified
      if (icstat.find("--checks=") == std::string::npos) {
        checksParam = cmStrCat(";--checks=", checksFile);
      }
      if (icstat.find("--db=") == std::string::npos) {
        dbParam = cmStrCat(";--db=", dbFile);
      }
      code_check += this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
        cmStrCat(icstat, checksParam, dbParam));
    }
    if (cmNonempty(tidy) || (cmNonempty(cpplint)) || (cmNonempty(cppcheck)) ||
        cmNonempty(pvs)) {
      code_check += " --source=";
      code_check +=
        this->GeneratorTarget->GetLocalGenerator()->ConvertToOutputFormat(
          source.GetFullPath(), cmOutputConverter::SHELL);
    }
    code_check += " -- ";
    return code_check;
  }
  return "";
}

std::string cmCommonTargetGenerator::GetLinkerLauncher(
  std::string const& config)
{
  std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
  std::string propName = lang + "_LINKER_LAUNCHER";
  cmValue launcherProp = this->GeneratorTarget->GetProperty(propName);
  if (cmNonempty(launcherProp)) {
    cm::GenEx::Context context(this->LocalCommonGenerator, config, lang);
    cmGeneratorExpressionDAGChecker dagChecker{ this->GeneratorTarget,
                                                propName, nullptr, nullptr,
                                                context };
    std::string evaluatedLinklauncher = cmGeneratorExpression::Evaluate(
      *launcherProp, context.LG, context.Config, this->GeneratorTarget,
      &dagChecker, this->GeneratorTarget, context.Language);
    // Convert ;-delimited list to single string
    cmList args{ evaluatedLinklauncher, cmList::EmptyElements::Yes };
    if (!args.empty()) {
      args[0] = this->LocalCommonGenerator->ConvertToOutputFormat(
        args[0], cmOutputConverter::SHELL);
      for (std::string& i : cmMakeRange(args.begin() + 1, args.end())) {
        i = this->LocalCommonGenerator->EscapeForShell(i);
      }
      return cmJoin(args, " ");
    }
  }
  return std::string();
}

bool cmCommonTargetGenerator::HaveRequiredLanguages(
  std::vector<cmSourceFile const*> const& sources,
  std::set<std::string>& languagesNeeded) const
{
  for (cmSourceFile const* sf : sources) {
    languagesNeeded.insert(sf->GetLanguage());
  }

  auto* makefile = this->Makefile;
  auto* state = makefile->GetState();
  auto unary = [&state, &makefile](std::string const& lang) -> bool {
    bool const valid = state->GetLanguageEnabled(lang);
    if (!valid) {
      makefile->IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat("The language ", lang,
                 " was requested for compilation but was not enabled."
                 " To enable a language it needs to be specified in a"
                 " 'project' or 'enable_language' command in the root"
                 " CMakeLists.txt"));
    }
    return valid;
  };
  return std::all_of(languagesNeeded.cbegin(), languagesNeeded.cend(), unary);
}

void cmCommonTargetGenerator::ComputeRustFlagsForObjects(
  std::string& linkCrates, std::string& nativeObjects,
  std::vector<std::string> const& objects)
{
  std::stringstream rlibsArgs;
  std::stringstream objectsArgs;
  auto const processObject = [&](std::string const& obj) {
    cm::filesystem::path const objPath(obj);
    if (objPath.extension() == ".rlib") {
      // Drop the "lib..." prefix and the ".rs" suffix. The prefix is required
      // by Rust on the crate rlib file, but is hidden from the user when using
      // the crate from Rust source code, so we drop it to be consistent with
      // common usage in Rust.
      std::string objStem = objPath.stem().string();
      objStem = objStem.substr(3, objStem.length() - 6);
      rlibsArgs << " --extern=" << objStem << "="
                << this->LocalCommonGenerator->ConvertToOutputFormat(
                     obj, cmOutputConverter::SHELL);
    } else {
      objectsArgs << " -Clink-arg="
                  << this->LocalCommonGenerator->ConvertToOutputFormat(
                       obj, cmOutputConverter::SHELL);
    }
  };
  for (auto const& obj : objects) {
    processObject(obj);
  }
  linkCrates += rlibsArgs.str();
  nativeObjects += objectsArgs.str();
}
