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

#include <cstddef>
#include <set>
#include <sstream>
#include <utility>
#include <vector>

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

#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOSXBundleGenerator.h"
#include "cmOutputConverter.h"
#include "cmProperty.h"
#include "cmRulePlaceholderExpander.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
  cmGeneratorTarget* target)
  : cmMakefileTargetGenerator(target)
{
  this->CustomCommandDriver = OnDepends;
  if (this->GeneratorTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
    this->TargetNames =
      this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
  }

  this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
  this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}

cmMakefileLibraryTargetGenerator::~cmMakefileLibraryTargetGenerator() =
  default;

void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
{
  // create the build.make file and directory, put in the common blocks
  this->CreateRuleFile();

  // write rules used to help build object files
  this->WriteCommonCodeRules();

  // write the per-target per-language flags
  this->WriteTargetLanguageFlags();

  // write in rules for object files and custom commands
  this->WriteTargetBuildRules();

  // write the link rules
  // Write the rule for this target type.
  switch (this->GeneratorTarget->GetType()) {
    case cmStateEnums::STATIC_LIBRARY:
      this->WriteStaticLibraryRules();
      break;
    case cmStateEnums::SHARED_LIBRARY:
      this->WriteSharedLibraryRules(false);
      if (this->GeneratorTarget->NeedRelinkBeforeInstall(
            this->GetConfigName())) {
        // Write rules to link an installable version of the target.
        this->WriteSharedLibraryRules(true);
      }
      break;
    case cmStateEnums::MODULE_LIBRARY:
      this->WriteModuleLibraryRules(false);
      if (this->GeneratorTarget->NeedRelinkBeforeInstall(
            this->GetConfigName())) {
        // Write rules to link an installable version of the target.
        this->WriteModuleLibraryRules(true);
      }
      break;
    case cmStateEnums::OBJECT_LIBRARY:
      this->WriteObjectLibraryRules();
      break;
    default:
      // If language is not known, this is an error.
      cmSystemTools::Error("Unknown Library Type");
      break;
  }

  // Write clean target
  this->WriteTargetCleanRules();

  // Write the dependency generation rule.  This must be done last so
  // that multiple output pair information is available.
  this->WriteTargetDependRules();

  // close the streams
  this->CloseFileStreams();
}

void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
{
  std::vector<std::string> commands;
  std::vector<std::string> depends;

  // Add post-build rules.
  this->LocalGenerator->AppendCustomCommands(
    commands, this->GeneratorTarget->GetPostBuildCommands(),
    this->GeneratorTarget, this->LocalGenerator->GetBinaryDirectory());

  // Depend on the object files.
  this->AppendObjectDepends(depends);

  // Write the rule.
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr,
                                      this->GeneratorTarget->GetName(),
                                      depends, commands, true);

  // Write the main driver rule to build everything in this target.
  this->WriteTargetDriverRule(this->GeneratorTarget->GetName(), false);
}

void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
{
  const bool requiresDeviceLinking = requireDeviceLinking(
    *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
  if (requiresDeviceLinking) {
    this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", false);
  }

  std::string linkLanguage =
    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());

  std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
    linkLanguage, this->GetConfigName());

  std::string extraFlags;
  this->LocalGenerator->GetStaticLibraryFlags(
    extraFlags, this->GetConfigName(), linkLanguage, this->GeneratorTarget);
  this->WriteLibraryRules(linkRuleVar, extraFlags, false);
}

void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
{
  if (this->GeneratorTarget->IsFrameworkOnApple()) {
    this->WriteFrameworkRules(relink);
    return;
  }

  if (!relink) {
    const bool requiresDeviceLinking = requireDeviceLinking(
      *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
    if (requiresDeviceLinking) {
      this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", relink);
    }
  }

  std::string linkLanguage =
    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
  std::string linkRuleVar =
    cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY");

  std::string extraFlags;
  this->GetTargetLinkFlags(extraFlags, linkLanguage);
  this->LocalGenerator->AddConfigVariableFlags(
    extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->GetConfigName());

  std::unique_ptr<cmLinkLineComputer> linkLineComputer =
    this->CreateLinkLineComputer(
      this->LocalGenerator,
      this->LocalGenerator->GetStateSnapshot().GetDirectory());

  this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
                                this->GetConfigName());

  this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
    extraFlags, this->GeneratorTarget, linkLanguage);

  this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}

void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
{
  if (!relink) {
    const bool requiresDeviceLinking = requireDeviceLinking(
      *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
    if (requiresDeviceLinking) {
      this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", relink);
    }
  }

  std::string linkLanguage =
    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
  std::string linkRuleVar =
    cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_MODULE");

  std::string extraFlags;
  this->GetTargetLinkFlags(extraFlags, linkLanguage);
  this->LocalGenerator->AddConfigVariableFlags(
    extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->GetConfigName());

  std::unique_ptr<cmLinkLineComputer> linkLineComputer =
    this->CreateLinkLineComputer(
      this->LocalGenerator,
      this->LocalGenerator->GetStateSnapshot().GetDirectory());

  this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
                                this->GetConfigName());

  this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}

void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
{
  std::string linkLanguage =
    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
  std::string linkRuleVar =
    cmStrCat("CMAKE_", linkLanguage, "_CREATE_MACOSX_FRAMEWORK");

  std::string extraFlags;
  this->GetTargetLinkFlags(extraFlags, linkLanguage);
  this->LocalGenerator->AddConfigVariableFlags(
    extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->GetConfigName());

  this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}

void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
  const std::string& linkRuleVar, bool relink)
{
#ifndef CMAKE_BOOTSTRAP
  // TODO: Merge the methods that call this method to avoid
  // code duplication.
  std::vector<std::string> commands;
  std::string const objExt =
    this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");

  // Get the name of the device object to generate.
  std::string const targetOutput =
    this->GeneratorTarget->ObjectDirectory + "cmake_device_link" + objExt;
  this->DeviceLinkObject = targetOutput;

  this->NumberOfProgressActions++;
  if (!this->NoRuleMessages) {
    cmLocalUnixMakefileGenerator3::EchoProgress progress;
    this->MakeEchoProgress(progress);
    // Add the link message.
    std::string buildEcho = cmStrCat(
      "Linking CUDA device code ",
      this->LocalGenerator->ConvertToOutputFormat(
        this->LocalGenerator->MaybeRelativeToCurBinDir(this->DeviceLinkObject),
        cmOutputConverter::SHELL));
    this->LocalGenerator->AppendEcho(
      commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
  }

  if (this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID") == "Clang") {
    this->WriteDeviceLinkRule(commands, targetOutput);
  } else {
    this->WriteNvidiaDeviceLibraryRules(linkRuleVar, relink, commands,
                                        targetOutput);
  }

  // Write the main driver rule to build everything in this target.
  this->WriteTargetDriverRule(targetOutput, relink);
}

void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
  const std::string& linkRuleVar, bool relink,
  std::vector<std::string>& commands, const std::string& targetOutput)
{
  std::string linkLanguage = "CUDA";

  // Build list of dependencies.
  std::vector<std::string> depends;
  this->AppendLinkDepends(depends, linkLanguage);

  // Add language-specific flags.
  std::string langFlags;
  this->LocalGenerator->AddLanguageFlagsForLinking(
    langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());

  // Create set of linking flags.
  std::string linkFlags;
  this->GetDeviceLinkFlags(linkFlags, linkLanguage);

  // Clean files associated with this library.
  std::set<std::string> libCleanFiles;
  libCleanFiles.insert(
    this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput));

  // Determine whether a link script will be used.
  bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();

  bool useResponseFileForObjects =
    this->CheckUseResponseFileForObjects(linkLanguage);
  bool const useResponseFileForLibs =
    this->CheckUseResponseFileForLibraries(linkLanguage);

  cmRulePlaceholderExpander::RuleVariables vars;
  vars.Language = linkLanguage.c_str();

  // Expand the rule variables.
  std::vector<std::string> real_link_commands;
  {
    bool useWatcomQuote =
      this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");

    // Set path conversion for link script shells.
    this->LocalGenerator->SetLinkScriptShell(useLinkScript);

    // Collect up flags to link in needed libraries.
    std::string linkLibs;
    std::unique_ptr<cmLinkLineComputer> linkLineComputer(
      new cmLinkLineDeviceComputer(
        this->LocalGenerator,
        this->LocalGenerator->GetStateSnapshot().GetDirectory()));
    linkLineComputer->SetForResponse(useResponseFileForLibs);
    linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
    linkLineComputer->SetRelink(relink);

    this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
                         useResponseFileForLibs, depends);

    // Construct object file lists that may be needed to expand the
    // rule.
    std::string buildObjs;
    this->CreateObjectLists(useLinkScript, false, // useArchiveRules
                            useResponseFileForObjects, buildObjs, depends,
                            useWatcomQuote);

    cmOutputConverter::OutputFormat output = (useWatcomQuote)
      ? cmOutputConverter::WATCOMQUOTE
      : cmOutputConverter::SHELL;

    std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
    objectDir = this->LocalGenerator->ConvertToOutputFormat(
      this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir),
      cmOutputConverter::SHELL);

    std::string target = this->LocalGenerator->ConvertToOutputFormat(
      this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput), output);

    std::string targetFullPathCompilePDB =
      this->ComputeTargetCompilePDB(this->GetConfigName());
    std::string targetOutPathCompilePDB =
      this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
                                                  cmOutputConverter::SHELL);

    vars.Objects = buildObjs.c_str();
    vars.ObjectDir = objectDir.c_str();
    vars.Target = target.c_str();
    vars.LinkLibraries = linkLibs.c_str();
    vars.ObjectsQuoted = buildObjs.c_str();
    vars.LanguageCompileFlags = langFlags.c_str();
    vars.LinkFlags = linkFlags.c_str();
    vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();

    std::string launcher;
    cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
                                                       "RULE_LAUNCH_LINK");
    if (cmNonempty(val)) {
      launcher = cmStrCat(*val, ' ');
    }

    std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
      this->LocalGenerator->CreateRulePlaceholderExpander());

    // Construct the main link rule and expand placeholders.
    rulePlaceholderExpander->SetTargetImpLib(targetOutput);
    std::string linkRule = this->GetLinkRule(linkRuleVar);
    cmExpandList(linkRule, real_link_commands);

    // Expand placeholders.
    for (std::string& real_link_command : real_link_commands) {
      real_link_command = cmStrCat(launcher, real_link_command);
      rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
                                                   real_link_command, vars);
    }
    // Restore path conversion to normal shells.
    this->LocalGenerator->SetLinkScriptShell(false);

    // Clean all the possible library names and symlinks.
    this->CleanFiles.insert(libCleanFiles.begin(), libCleanFiles.end());
  }

  std::vector<std::string> commands1;
  // Optionally convert the build rule to use a script to avoid long
  // command lines in the make shell.
  if (useLinkScript) {
    // Use a link script.
    const char* name = (relink ? "drelink.txt" : "dlink.txt");
    this->CreateLinkScript(name, real_link_commands, commands1, depends);
  } else {
    // No link script.  Just use the link rule directly.
    commands1 = real_link_commands;
  }
  this->LocalGenerator->CreateCDCommand(
    commands1, this->Makefile->GetCurrentBinaryDirectory(),
    this->LocalGenerator->GetBinaryDirectory());
  cm::append(commands, commands1);
  commands1.clear();

  // Compute the list of outputs.
  std::vector<std::string> outputs(1, targetOutput);

  // Write the build rule.
  this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
                      commands, false);
#else
  static_cast<void>(linkRuleVar);
  static_cast<void>(relink);
#endif
}

void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
  const std::string& linkRuleVar, const std::string& extraFlags, bool relink)
{
  // TODO: Merge the methods that call this method to avoid
  // code duplication.
  std::vector<std::string> commands;

  // Get the language to use for linking this library.
  std::string linkLanguage =
    this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());

  // Make sure we have a link language.
  if (linkLanguage.empty()) {
    cmSystemTools::Error("Cannot determine link language for target \"" +
                         this->GeneratorTarget->GetName() + "\".");
    return;
  }

  // Build list of dependencies.
  std::vector<std::string> depends;
  this->AppendLinkDepends(depends, linkLanguage);
  if (!this->DeviceLinkObject.empty()) {
    depends.push_back(this->DeviceLinkObject);
  }

  // Create set of linking flags.
  std::string linkFlags;
  this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
  this->LocalGenerator->AppendIPOLinkerFlags(
    linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);

  // Add OSX version flags, if any.
  if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
      this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
    this->AppendOSXVerFlag(linkFlags, linkLanguage, "COMPATIBILITY", true);
    this->AppendOSXVerFlag(linkFlags, linkLanguage, "CURRENT", false);
  }

  // Construct the name of the library.
  this->GeneratorTarget->GetLibraryNames(this->GetConfigName());

  // Construct the full path version of the names.
  std::string outpath;
  std::string outpathImp;
  if (this->GeneratorTarget->IsFrameworkOnApple()) {
    outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
    this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
                                              outpath, this->GetConfigName());
    outpath += '/';
  } else if (this->GeneratorTarget->IsCFBundleOnApple()) {
    outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
    this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, outpath,
                                             this->GetConfigName());
    outpath += '/';
  } else if (relink) {
    outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(),
                       "/CMakeFiles/CMakeRelink.dir");
    cmSystemTools::MakeDirectory(outpath);
    outpath += '/';
    if (!this->TargetNames.ImportLibrary.empty()) {
      outpathImp = outpath;
    }
  } else {
    outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
    cmSystemTools::MakeDirectory(outpath);
    outpath += '/';
    if (!this->TargetNames.ImportLibrary.empty()) {
      outpathImp = this->GeneratorTarget->GetDirectory(
        this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
      cmSystemTools::MakeDirectory(outpathImp);
      outpathImp += '/';
    }
  }

  std::string compilePdbOutputPath =
    this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
  cmSystemTools::MakeDirectory(compilePdbOutputPath);

  std::string pdbOutputPath =
    this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
  cmSystemTools::MakeDirectory(pdbOutputPath);
  pdbOutputPath += "/";

  std::string targetFullPath = outpath + this->TargetNames.Output;
  std::string targetFullPathPDB = pdbOutputPath + this->TargetNames.PDB;
  std::string targetFullPathSO = outpath + this->TargetNames.SharedObject;
  std::string targetFullPathReal = outpath + this->TargetNames.Real;
  std::string targetFullPathImport =
    outpathImp + this->TargetNames.ImportLibrary;

  // Construct the output path version of the names for use in command
  // arguments.
  std::string targetOutPathPDB = this->LocalGenerator->ConvertToOutputFormat(
    targetFullPathPDB, cmOutputConverter::SHELL);

  std::string targetOutPath = this->LocalGenerator->ConvertToOutputFormat(
    this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPath),
    cmOutputConverter::SHELL);
  std::string targetOutPathSO = this->LocalGenerator->ConvertToOutputFormat(
    this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathSO),
    cmOutputConverter::SHELL);
  std::string targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
    this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal),
    cmOutputConverter::SHELL);
  std::string targetOutPathImport =
    this->LocalGenerator->ConvertToOutputFormat(
      this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathImport),
      cmOutputConverter::SHELL);

  this->NumberOfProgressActions++;
  if (!this->NoRuleMessages) {
    cmLocalUnixMakefileGenerator3::EchoProgress progress;
    this->MakeEchoProgress(progress);
    // Add the link message.
    std::string buildEcho = cmStrCat("Linking ", linkLanguage);
    switch (this->GeneratorTarget->GetType()) {
      case cmStateEnums::STATIC_LIBRARY:
        buildEcho += " static library ";
        break;
      case cmStateEnums::SHARED_LIBRARY:
        buildEcho += " shared library ";
        break;
      case cmStateEnums::MODULE_LIBRARY:
        if (this->GeneratorTarget->IsCFBundleOnApple()) {
          buildEcho += " CFBundle";
        }
        buildEcho += " shared module ";
        break;
      default:
        buildEcho += " library ";
        break;
    }
    buildEcho += targetOutPath;
    this->LocalGenerator->AppendEcho(
      commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
  }

  // Clean files associated with this library.
  std::set<std::string> libCleanFiles;
  libCleanFiles.insert(
    this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal));

  std::vector<std::string> commands1;
  // Add a command to remove any existing files for this library.
  // for static libs only
  if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
    this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles,
                                             this->GeneratorTarget, "target");
    this->LocalGenerator->CreateCDCommand(
      commands1, this->Makefile->GetCurrentBinaryDirectory(),
      this->LocalGenerator->GetBinaryDirectory());
    cm::append(commands, commands1);
    commands1.clear();
  }

  if (this->TargetNames.Output != this->TargetNames.Real) {
    libCleanFiles.insert(
      this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPath));
  }
  if (this->TargetNames.SharedObject != this->TargetNames.Real &&
      this->TargetNames.SharedObject != this->TargetNames.Output) {
    libCleanFiles.insert(
      this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathSO));
  }
  if (!this->TargetNames.ImportLibrary.empty()) {
    libCleanFiles.insert(
      this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathImport));
    std::string implib;
    if (this->GeneratorTarget->GetImplibGNUtoMS(
          this->GetConfigName(), targetFullPathImport, implib)) {
      libCleanFiles.insert(
        this->LocalGenerator->MaybeRelativeToCurBinDir(implib));
    }
  }

  // List the PDB for cleaning only when the whole target is
  // cleaned.  We do not want to delete the .pdb file just before
  // linking the target.
  this->CleanFiles.insert(
    this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathPDB));

#ifdef _WIN32
  // There may be a manifest file for this target.  Add it to the
  // clean set just in case.
  if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) {
    libCleanFiles.insert(this->LocalGenerator->MaybeRelativeToCurBinDir(
      targetFullPath + ".manifest"));
  }
#endif

  // Add the pre-build and pre-link rules building but not when relinking.
  if (!relink) {
    this->LocalGenerator->AppendCustomCommands(
      commands, this->GeneratorTarget->GetPreBuildCommands(),
      this->GeneratorTarget, this->LocalGenerator->GetBinaryDirectory());
    this->LocalGenerator->AppendCustomCommands(
      commands, this->GeneratorTarget->GetPreLinkCommands(),
      this->GeneratorTarget, this->LocalGenerator->GetBinaryDirectory());
  }

  // Determine whether a link script will be used.
  bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();

  bool useResponseFileForObjects =
    this->CheckUseResponseFileForObjects(linkLanguage);
  bool const useResponseFileForLibs =
    this->CheckUseResponseFileForLibraries(linkLanguage);

  // For static libraries there might be archiving rules.
  bool haveStaticLibraryRule = false;
  std::vector<std::string> archiveCreateCommands;
  std::vector<std::string> archiveAppendCommands;
  std::vector<std::string> archiveFinishCommands;
  std::string::size_type archiveCommandLimit = std::string::npos;
  if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
    haveStaticLibraryRule = this->Makefile->IsDefinitionSet(linkRuleVar);
    std::string arCreateVar =
      cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_CREATE");

    arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
      arCreateVar, linkLanguage, this->GetConfigName());

    this->Makefile->GetDefExpandList(arCreateVar, archiveCreateCommands);
    std::string arAppendVar =
      cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");

    arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
      arAppendVar, linkLanguage, this->GetConfigName());

    this->Makefile->GetDefExpandList(arAppendVar, archiveAppendCommands);
    std::string arFinishVar =
      cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");

    arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
      arFinishVar, linkLanguage, this->GetConfigName());

    this->Makefile->GetDefExpandList(arFinishVar, archiveFinishCommands);
  }

  // Decide whether to use archiving rules.
  bool useArchiveRules = !haveStaticLibraryRule &&
    !archiveCreateCommands.empty() && !archiveAppendCommands.empty();
  if (useArchiveRules) {
    // Archiving rules are always run with a link script.
    useLinkScript = true;

    // Archiving rules never use a response file.
    useResponseFileForObjects = false;

    // Limit the length of individual object lists to less than half of
    // the command line length limit (leaving half for other flags).
    // This may result in several calls to the archiver.
    if (size_t limit = cmSystemTools::CalculateCommandLineLengthLimit()) {
      archiveCommandLimit = limit / 2;
    } else {
      archiveCommandLimit = 8000;
    }
  }

  // Expand the rule variables.
  std::vector<std::string> real_link_commands;
  {
    bool useWatcomQuote =
      this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");

    // Set path conversion for link script shells.
    this->LocalGenerator->SetLinkScriptShell(useLinkScript);

    // Collect up flags to link in needed libraries.
    std::string linkLibs;
    if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) {

      std::unique_ptr<cmLinkLineComputer> linkLineComputer =
        this->CreateLinkLineComputer(
          this->LocalGenerator,
          this->LocalGenerator->GetStateSnapshot().GetDirectory());
      linkLineComputer->SetForResponse(useResponseFileForLibs);
      linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
      linkLineComputer->SetRelink(relink);

      this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
                           useResponseFileForLibs, depends);
    }

    // Construct object file lists that may be needed to expand the
    // rule.
    std::string buildObjs;
    this->CreateObjectLists(useLinkScript, useArchiveRules,
                            useResponseFileForObjects, buildObjs, depends,
                            useWatcomQuote);
    if (!this->DeviceLinkObject.empty()) {
      buildObjs += " " +
        this->LocalGenerator->ConvertToOutputFormat(
          this->LocalGenerator->MaybeRelativeToCurBinDir(
            this->DeviceLinkObject),
          cmOutputConverter::SHELL);
    }

    std::string const& aixExports = this->GetAIXExports(this->GetConfigName());

    // maybe create .def file from list of objects
    this->GenDefFile(real_link_commands);

    std::string manifests = this->GetManifests(this->GetConfigName());

    cmRulePlaceholderExpander::RuleVariables vars;
    vars.TargetPDB = targetOutPathPDB.c_str();

    // Setup the target version.
    std::string targetVersionMajor;
    std::string targetVersionMinor;
    {
      std::ostringstream majorStream;
      std::ostringstream minorStream;
      int major;
      int minor;
      this->GeneratorTarget->GetTargetVersion(major, minor);
      majorStream << major;
      minorStream << minor;
      targetVersionMajor = majorStream.str();
      targetVersionMinor = minorStream.str();
    }
    vars.TargetVersionMajor = targetVersionMajor.c_str();
    vars.TargetVersionMinor = targetVersionMinor.c_str();

    vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
    vars.CMTargetType =
      cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
    vars.Language = linkLanguage.c_str();
    vars.AIXExports = aixExports.c_str();
    vars.Objects = buildObjs.c_str();
    std::string objectDir = this->GeneratorTarget->GetSupportDirectory();

    objectDir = this->LocalGenerator->ConvertToOutputFormat(
      this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir),
      cmOutputConverter::SHELL);

    vars.ObjectDir = objectDir.c_str();
    cmOutputConverter::OutputFormat output = (useWatcomQuote)
      ? cmOutputConverter::WATCOMQUOTE
      : cmOutputConverter::SHELL;
    std::string target = this->LocalGenerator->ConvertToOutputFormat(
      this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal),
      output);
    vars.Target = target.c_str();
    vars.LinkLibraries = linkLibs.c_str();
    vars.ObjectsQuoted = buildObjs.c_str();
    std::string targetOutSOName;
    if (this->GeneratorTarget->HasSOName(this->GetConfigName())) {
      vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
      targetOutSOName = this->LocalGenerator->ConvertToOutputFormat(
        this->TargetNames.SharedObject.c_str(), cmOutputConverter::SHELL);
      vars.TargetSOName = targetOutSOName.c_str();
    }
    vars.LinkFlags = linkFlags.c_str();

    vars.Manifests = manifests.c_str();

    // Compute the directory portion of the install_name setting.
    std::string install_name_dir;
    if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY) {
      // Get the install_name directory for the build tree.
      install_name_dir = this->GeneratorTarget->GetInstallNameDirForBuildTree(
        this->GetConfigName());

      // Set the rule variable replacement value.
      if (install_name_dir.empty()) {
        vars.TargetInstallNameDir = "";
      } else {
        // Convert to a path for the native build tool.
        install_name_dir = this->LocalGenerator->ConvertToOutputFormat(
          install_name_dir, cmOutputConverter::SHELL);
        vars.TargetInstallNameDir = install_name_dir.c_str();
      }
    }

    // Add language-specific flags.
    std::string langFlags;
    this->LocalGenerator->AddLanguageFlagsForLinking(
      langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());

    this->LocalGenerator->AddArchitectureFlags(
      langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());

    vars.LanguageCompileFlags = langFlags.c_str();

    std::string linkerLauncher =
      this->GetLinkerLauncher(this->GetConfigName());
    if (cmNonempty(linkerLauncher)) {
      vars.Launcher = linkerLauncher.c_str();
    }

    std::string launcher;
    cmProp val = this->LocalGenerator->GetRuleLauncher(this->GeneratorTarget,
                                                       "RULE_LAUNCH_LINK");
    if (cmNonempty(val)) {
      launcher = cmStrCat(*val, ' ');
    }

    std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
      this->LocalGenerator->CreateRulePlaceholderExpander());
    // Construct the main link rule and expand placeholders.
    rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
    if (useArchiveRules) {
      // Construct the individual object list strings.
      std::vector<std::string> object_strings;
      this->WriteObjectsStrings(object_strings, archiveCommandLimit);

      // Add the cuda device object to the list of archive files. This will
      // only occur on archives which have CUDA_RESOLVE_DEVICE_SYMBOLS enabled
      if (!this->DeviceLinkObject.empty()) {
        object_strings.push_back(this->LocalGenerator->ConvertToOutputFormat(
          this->LocalGenerator->MaybeRelativeToCurBinDir(
            this->DeviceLinkObject),
          cmOutputConverter::SHELL));
      }

      // Create the archive with the first set of objects.
      auto osi = object_strings.begin();
      {
        vars.Objects = osi->c_str();
        for (std::string const& acc : archiveCreateCommands) {
          std::string cmd = launcher + acc;
          rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
                                                       cmd, vars);
          real_link_commands.push_back(std::move(cmd));
        }
      }
      // Append to the archive with the other object sets.
      for (++osi; osi != object_strings.end(); ++osi) {
        vars.Objects = osi->c_str();
        for (std::string const& aac : archiveAppendCommands) {
          std::string cmd = launcher + aac;
          rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
                                                       cmd, vars);
          real_link_commands.push_back(std::move(cmd));
        }
      }
      // Finish the archive.
      vars.Objects = "";
      for (std::string const& afc : archiveFinishCommands) {
        std::string cmd = launcher + afc;
        rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, cmd,
                                                     vars);
        // If there is no ranlib the command will be ":".  Skip it.
        if (!cmd.empty() && cmd[0] != ':') {
          real_link_commands.push_back(std::move(cmd));
        }
      }
    } else {
      // Get the set of commands.
      std::string linkRule = this->GetLinkRule(linkRuleVar);
      cmExpandList(linkRule, real_link_commands);
      if (this->UseLWYU) {
        cmProp lwyuCheck =
          this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
        if (lwyuCheck) {
          std::string cmakeCommand = cmStrCat(
            this->LocalGenerator->ConvertToOutputFormat(
              cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
            " -E __run_co_compile --lwyu=");
          cmakeCommand += this->LocalGenerator->EscapeForShell(*lwyuCheck);
          cmakeCommand += cmStrCat(" --source=", targetOutPathReal);
          real_link_commands.push_back(std::move(cmakeCommand));
        }
      }

      // Expand placeholders.
      for (std::string& real_link_command : real_link_commands) {
        real_link_command = cmStrCat(launcher, real_link_command);
        rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
                                                     real_link_command, vars);
      }
    }

    // Restore path conversion to normal shells.
    this->LocalGenerator->SetLinkScriptShell(false);
  }

  // Optionally convert the build rule to use a script to avoid long
  // command lines in the make shell.
  if (useLinkScript) {
    // Use a link script.
    const char* name = (relink ? "relink.txt" : "link.txt");
    this->CreateLinkScript(name, real_link_commands, commands1, depends);
  } else {
    // No link script.  Just use the link rule directly.
    commands1 = real_link_commands;
  }
  this->LocalGenerator->CreateCDCommand(
    commands1, this->Makefile->GetCurrentBinaryDirectory(),
    this->LocalGenerator->GetBinaryDirectory());
  cm::append(commands, commands1);
  commands1.clear();

  // Add a rule to create necessary symlinks for the library.
  // Frameworks are handled by cmOSXBundleGenerator.
  if (targetOutPath != targetOutPathReal &&
      !this->GeneratorTarget->IsFrameworkOnApple()) {
    std::string symlink =
      cmStrCat("$(CMAKE_COMMAND) -E cmake_symlink_library ", targetOutPathReal,
               ' ', targetOutPathSO, ' ', targetOutPath);
    commands1.push_back(std::move(symlink));
    this->LocalGenerator->CreateCDCommand(
      commands1, this->Makefile->GetCurrentBinaryDirectory(),
      this->LocalGenerator->GetBinaryDirectory());
    cm::append(commands, commands1);
    commands1.clear();
  }

  // Add the post-build rules when building but not when relinking.
  if (!relink) {
    this->LocalGenerator->AppendCustomCommands(
      commands, this->GeneratorTarget->GetPostBuildCommands(),
      this->GeneratorTarget, this->LocalGenerator->GetBinaryDirectory());
  }

  // Compute the list of outputs.
  std::vector<std::string> outputs(1, targetFullPathReal);
  if (this->TargetNames.SharedObject != this->TargetNames.Real) {
    outputs.push_back(targetFullPathSO);
  }
  if (this->TargetNames.Output != this->TargetNames.SharedObject &&
      this->TargetNames.Output != this->TargetNames.Real) {
    outputs.push_back(targetFullPath);
  }

  // Write the build rule.
  this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
                      commands, false);

  // Write the main driver rule to build everything in this target.
  this->WriteTargetDriverRule(targetFullPath, relink);

  // Clean all the possible library names and symlinks.
  this->CleanFiles.insert(libCleanFiles.begin(), libCleanFiles.end());
}
