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

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

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

#include "cmComputeLinkDepends.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOrderDirectories.h"
#include "cmPlaceholderExpander.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmValue.h"
#include "cmake.h"

//#define CM_COMPUTE_LINK_INFO_DEBUG

/*
Notes about linking on various platforms:

------------------------------------------------------------------------------

Linux, FreeBSD, macOS, Sun, Windows:

Linking to libraries using the full path works fine.

------------------------------------------------------------------------------

On AIX, more work is needed.

  The "-bnoipath" option is needed.  From "man ld":

    Note: If you specify a shared object, or an archive file
    containing a shared object, with an absolute or relative path
    name, instead of with the -lName flag, the path name is
    included in the import file ID string in the loader section of
    the output file. You can override this behavior with the
    -bnoipath option.

      noipath

        For shared objects listed on the command-line, rather than
        specified with the -l flag, use a null path component when
        listing the shared object in the loader section of the
        output file. A null path component is always used for
        shared objects specified with the -l flag. This option
        does not affect the specification of a path component by
        using a line beginning with #! in an import file. The
        default is the ipath option.

  This prevents the full path specified on the compile line from being
  compiled directly into the binary.

  By default the linker places -L paths in the embedded runtime path.
  In order to implement CMake's RPATH interface correctly, we need the
  -blibpath:Path option.  From "man ld":

      libpath:Path

        Uses Path as the library path when writing the loader section
        of the output file. Path is neither checked for validity nor
        used when searching for libraries specified by the -l flag.
        Path overrides any library paths generated when the -L flag is
        used.

        If you do not specify any -L flags, or if you specify the
        nolibpath option, the default library path information is
        written in the loader section of the output file. The default
        library path information is the value of the LIBPATH
        environment variable if it is defined, and /usr/lib:/lib,
        otherwise.

  We can pass -Wl,-blibpath:/usr/lib:/lib always to avoid the -L stuff
  and not break when the user sets LIBPATH.  Then if we want to add an
  rpath we insert it into the option before /usr/lib.

------------------------------------------------------------------------------

On HP-UX, more work is needed.  There are differences between
versions.

ld: 92453-07 linker linker ld B.10.33 990520

  Linking with a full path works okay for static and shared libraries.
  The linker seems to always put the full path to where the library
  was found in the binary whether using a full path or -lfoo syntax.
  Transitive link dependencies work just fine due to the full paths.

  It has the "-l:libfoo.sl" option.  The +nodefaultrpath is accepted
  but not documented and does not seem to do anything.  There is no
  +forceload option.

ld: 92453-07 linker ld HP Itanium(R) B.12.41  IPF/IPF

  Linking with a full path works okay for static libraries.

  Linking with a full path works okay for shared libraries.  However
  dependent (transitive) libraries of those linked directly must be
  either found with an rpath stored in the direct dependencies or
  found in -L paths as if they were specified with "-l:libfoo.sl"
  (really "-l:<soname>").  The search matches that of the dynamic
  loader but only with -L paths.  In other words, if we have an
  executable that links to shared library bar which links to shared
  library foo, the link line for the exe must contain

    /dir/with/bar/libbar.sl -L/dir/with/foo

  It does not matter whether the exe wants to link to foo directly or
  whether /dir/with/foo/libfoo.sl is listed.  The -L path must still
  be present.  It should match the runtime path computed for the
  executable taking all directly and transitively linked libraries
  into account.

  The "+nodefaultrpath" option should be used to avoid getting -L
  paths in the rpath unless we add our own rpath with +b.  This means
  that skip-build-rpath should use this option.

  See documentation in "man ld", "man dld.so", and
  http://docs.hp.com/en/B2355-90968/creatingandusinglibraries.htm

    +[no]defaultrpath
      +defaultrpath is the default.  Include any paths that are
      specified with -L in the embedded path, unless you specify the
      +b option.  If you use +b, only the path list specified by +b is
      in the embedded path.

      The +nodefaultrpath option removes all library paths that were
      specified with the -L option from the embedded path.  The linker
      searches the library paths specified by the -L option at link
      time.  At run time, the only library paths searched are those
      specified by the environment variables LD_LIBRARY_PATH and
      SHLIB_PATH, library paths specified by the +b linker option, and
      finally the default library paths.

    +rpathfirst
      This option will cause the paths specified in RPATH (embedded
      path) to be used before the paths specified in LD_LIBRARY_PATH
      or SHLIB_PATH, in searching for shared libraries.  This changes
      the default search order of LD_LIBRARY_PATH, SHLIB_PATH, and
      RPATH (embedded path).

------------------------------------------------------------------------------
Notes about dependent (transitive) shared libraries:

On non-Windows systems shared libraries may have transitive
dependencies.  In order to support LINK_INTERFACE_LIBRARIES we must
support linking to a shared library without listing all the libraries
to which it links.  Some linkers want to be able to find the
transitive dependencies (dependent libraries) of shared libraries
listed on the command line.

  - On Windows, DLLs are not directly linked, and the import libraries
    have no transitive dependencies.

  - On Mac OS X 10.5 and above transitive dependencies are not needed.

  - On Mac OS X 10.4 and below we need to actually list the dependencies.
    Otherwise when using -isysroot for universal binaries it cannot
    find the dependent libraries.  Listing them on the command line
    tells the linker where to find them, but unfortunately also links
    the library.

  - On HP-UX, the linker wants to find the transitive dependencies of
    shared libraries in the -L paths even if the dependent libraries
    are given on the link line.

  - On AIX the transitive dependencies are not needed.

  - On SGI, the linker wants to find the transitive dependencies of
    shared libraries in the -L paths if they are not given on the link
    line.  Transitive linking can be disabled using the options

      -no_transitive_link -Wl,-no_transitive_link

    which disable it.  Both options must be given when invoking the
    linker through the compiler.

  - On Sun, the linker wants to find the transitive dependencies of
    shared libraries in the -L paths if they are not given on the link
    line.

  - On Linux, FreeBSD, and QNX:

    The linker wants to find the transitive dependencies of shared
    libraries in the "-rpath-link" paths option if they have not been
    given on the link line.  The option is like rpath but just for
    link time:

      -Wl,-rpath-link,"/path1:/path2"

For -rpath-link, we need a separate runtime path ordering pass
including just the dependent libraries that are not linked.

For -L paths on non-HP, we can do the same thing as with rpath-link
but put the results in -L paths.  The paths should be listed at the
end to avoid conflicting with user search paths (?).

For -L paths on HP, we should do a runtime path ordering pass with
all libraries, both linked and non-linked.  Even dependent
libraries that are also linked need to be listed in -L paths.

In our implementation we add all dependent libraries to the runtime
path computation.  Then the auto-generated RPATH will find everything.

------------------------------------------------------------------------------
Notes about shared libraries with not builtin soname:

Some UNIX shared libraries may be created with no builtin soname.  On
some platforms such libraries cannot be linked using the path to their
location because the linker will copy the path into the field used to
find the library at runtime.

  Apple:    ../libfoo.dylib  ==>  libfoo.dylib  # ok, uses install_name
  SGI:      ../libfoo.so     ==>  libfoo.so     # ok
  AIX:      ../libfoo.so     ==>  libfoo.so     # ok
  Linux:    ../libfoo.so     ==>  ../libfoo.so  # bad
  HP-UX:    ../libfoo.so     ==>  ../libfoo.so  # bad
  Sun:      ../libfoo.so     ==>  ../libfoo.so  # bad
  FreeBSD:  ../libfoo.so     ==>  ../libfoo.so  # bad

In order to link these libraries we need to use the old-style split
into -L.. and -lfoo options.  This should be fairly safe because most
problems with -lfoo options were related to selecting shared libraries
instead of static but in this case we want the shared lib.  Link
directory ordering needs to be done to make sure these shared
libraries are found first.  There should be very few restrictions
because this need be done only for shared libraries without soname-s.

*/

cmComputeLinkInformation::cmComputeLinkInformation(
  const cmGeneratorTarget* target, const std::string& config)
  // Store context information.
  : Target(target)
  , Makefile(target->Target->GetMakefile())
  , GlobalGenerator(target->GetLocalGenerator()->GetGlobalGenerator())
  , CMakeInstance(this->GlobalGenerator->GetCMakeInstance())
  // The configuration being linked.
  , Config(config)
{
  // Check whether to recognize OpenBSD-style library versioned names.
  this->OpenBSD = this->Makefile->GetState()->GetGlobalPropertyAsBool(
    "FIND_LIBRARY_USE_OPENBSD_VERSIONING");

  // Allocate internals.
  this->OrderLinkerSearchPath = cm::make_unique<cmOrderDirectories>(
    this->GlobalGenerator, target, "linker search path");
  this->OrderRuntimeSearchPath = cm::make_unique<cmOrderDirectories>(
    this->GlobalGenerator, target, "runtime search path");

  // Get the language used for linking this target.
  this->LinkLanguage = this->Target->GetLinkerLanguage(config);
  if (this->LinkLanguage.empty()) {
    // The Compute method will do nothing, so skip the rest of the
    // initialization.
    return;
  }

  // Check whether we should skip dependencies on shared library files.
  this->LinkDependsNoShared =
    this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");

  // On platforms without import libraries there may be a special flag
  // to use when creating a plugin (module) that obtains symbols from
  // the program that will load it.
  if (!this->Target->IsDLLPlatform() &&
      this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) {
    std::string loader_flag_var =
      cmStrCat("CMAKE_SHARED_MODULE_LOADER_", this->LinkLanguage, "_FLAG");
    this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var);
  }

  // Get options needed to link libraries.
  if (cmValue flag = this->Makefile->GetDefinition(
        "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_FLAG")) {
    this->LibLinkFlag = *flag;
  } else {
    this->LibLinkFlag =
      this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
  }
  if (cmValue flag = this->Makefile->GetDefinition(
        "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_FILE_FLAG")) {
    this->LibLinkFileFlag = *flag;
  } else {
    this->LibLinkFileFlag =
      this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
  }
  if (cmValue suffix = this->Makefile->GetDefinition(
        "CMAKE_" + this->LinkLanguage + "_LINK_LIBRARY_SUFFIX")) {
    this->LibLinkSuffix = *suffix;
  } else {
    this->LibLinkSuffix =
      this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
  }
  if (cmValue flag = this->Makefile->GetDefinition(
        "CMAKE_" + this->LinkLanguage + "_LINK_OBJECT_FILE_FLAG")) {
    this->ObjLinkFileFlag = *flag;
  } else {
    this->ObjLinkFileFlag =
      this->Makefile->GetSafeDefinition("CMAKE_LINK_OBJECT_FILE_FLAG");
  }

  // Get options needed to specify RPATHs.
  this->RuntimeUseChrpath = false;
  if (this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) {
    const char* tType = ((this->Target->GetType() == cmStateEnums::EXECUTABLE)
                           ? "EXECUTABLE"
                           : "SHARED_LIBRARY");
    std::string rtVar =
      cmStrCat("CMAKE_", tType, "_RUNTIME_", this->LinkLanguage, "_FLAG");
    std::string rtSepVar = rtVar + "_SEP";
    this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar);
    this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar);
    this->RuntimeAlways = (this->Makefile->GetSafeDefinition(
      "CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));

    this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);

    // Get options needed to help find dependent libraries.
    std::string rlVar =
      cmStrCat("CMAKE_", tType, "_RPATH_LINK_", this->LinkLanguage, "_FLAG");
    this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar);
  }

  // Check if we need to include the runtime search path at link time.
  {
    std::string var = cmStrCat("CMAKE_SHARED_LIBRARY_LINK_",
                               this->LinkLanguage, "_WITH_RUNTIME_PATH");
    this->LinkWithRuntimePath = this->Makefile->IsOn(var);
  }

  // Define some Feature descriptors to handle standard library and object link
  if (!this->GetLibLinkFileFlag().empty()) {
    this->LibraryFeatureDescriptors.emplace(
      "__CMAKE_LINK_LIBRARY",
      LibraryFeatureDescriptor{
        "__CMAKE_LINK_LIBRARY",
        cmStrCat(this->GetLibLinkFileFlag(), "<LIBRARY>") });
  }
  if (!this->GetObjLinkFileFlag().empty()) {
    this->LibraryFeatureDescriptors.emplace(
      "__CMAKE_LINK_OBJECT",
      LibraryFeatureDescriptor{
        "__CMAKE_LINK_OBJECT",
        cmStrCat(this->GetObjLinkFileFlag(), "<LIBRARY>") });
  }
  if (!this->LoaderFlag->empty()) {
    // Define a Feature descriptor for the link of an executable with exports
    this->LibraryFeatureDescriptors.emplace(
      "__CMAKE_LINK_EXECUTABLE",
      LibraryFeatureDescriptor{ "__CMAKE_LINK_EXECUTABLE",
                                cmStrCat(this->LoaderFlag, "<LIBRARY>") });
  }

  // Check the platform policy for missing soname case.
  this->NoSONameUsesPath =
    this->Makefile->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");

  // Get link type information.
  this->ComputeLinkTypeInfo();

  // Setup the link item parser.
  this->ComputeItemParserInfo();

  // Setup framework support.
  this->ComputeFrameworkInfo();

  // Choose a mode for dealing with shared library dependencies.
  this->SharedDependencyMode = SharedDepModeNone;
  if (this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES")) {
    this->SharedDependencyMode = SharedDepModeLink;
  } else if (this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS")) {
    this->SharedDependencyMode = SharedDepModeLibDir;
  } else if (!this->RPathLinkFlag.empty()) {
    this->SharedDependencyMode = SharedDepModeDir;
    this->OrderDependentRPath = cm::make_unique<cmOrderDirectories>(
      this->GlobalGenerator, target, "dependent library path");
  }

  // Add the search path entries requested by the user to path ordering.
  std::vector<std::string> directories;
  this->Target->GetLinkDirectories(directories, config, this->LinkLanguage);
  this->OrderLinkerSearchPath->AddUserDirectories(directories);
  this->OrderRuntimeSearchPath->AddUserDirectories(directories);

  // Set up the implicit link directories.
  this->LoadImplicitLinkInfo();
  this->OrderLinkerSearchPath->SetImplicitDirectories(this->ImplicitLinkDirs);
  this->OrderRuntimeSearchPath->SetImplicitDirectories(this->ImplicitLinkDirs);
  if (this->OrderDependentRPath) {
    this->OrderDependentRPath->SetImplicitDirectories(this->ImplicitLinkDirs);
    this->OrderDependentRPath->AddLanguageDirectories(this->RuntimeLinkDirs);
  }

  // Decide whether to enable compatible library search path mode.
  // There exists code that effectively does
  //
  //    /path/to/libA.so -lB
  //
  // where -lB is meant to link to /path/to/libB.so.  This is broken
  // because it specified -lB without specifying a link directory (-L)
  // in which to search for B.  This worked in CMake 2.4 and below
  // because -L/path/to would be added by the -L/-l split for A.  In
  // order to support such projects we need to add the directories
  // containing libraries linked with a full path to the -L path.
  this->OldLinkDirMode =
    this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
  if (this->OldLinkDirMode) {
    // Construct a mask to not bother with this behavior for link
    // directories already specified by the user.
    this->OldLinkDirMask.insert(directories.begin(), directories.end());
  }

  this->CMP0060Warn = this->Makefile->PolicyOptionalWarningEnabled(
    "CMAKE_POLICY_WARNING_CMP0060");
}

cmComputeLinkInformation::~cmComputeLinkInformation() = default;

namespace {
const std::string& DEFAULT = cmComputeLinkDepends::LinkEntry::DEFAULT;
}

void cmComputeLinkInformation::AppendValues(
  std::string& result, std::vector<BT<std::string>>& values)
{
  for (BT<std::string>& p : values) {
    if (result.empty()) {
      result.append(" ");
    }

    result.append(p.Value);
  }
}

cmComputeLinkInformation::ItemVector const&
cmComputeLinkInformation::GetItems() const
{
  return this->Items;
}

std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
  const
{
  return this->OrderLinkerSearchPath->GetOrderedDirectories();
}

std::vector<BT<std::string>>
cmComputeLinkInformation::GetDirectoriesWithBacktraces()
{
  std::vector<BT<std::string>> directoriesWithBacktraces;

  std::vector<BT<std::string>> targetLinkDirectores =
    this->Target->GetLinkDirectories(this->Config, this->LinkLanguage);

  const std::vector<std::string>& orderedDirectories = this->GetDirectories();
  for (const std::string& dir : orderedDirectories) {
    auto result =
      std::find(targetLinkDirectores.begin(), targetLinkDirectores.end(), dir);
    if (result != targetLinkDirectores.end()) {
      directoriesWithBacktraces.emplace_back(std::move(*result));
    } else {
      directoriesWithBacktraces.emplace_back(dir);
    }
  }

  return directoriesWithBacktraces;
}

std::string cmComputeLinkInformation::GetRPathLinkString() const
{
  // If there is no separate linker runtime search flag (-rpath-link)
  // there is no reason to compute a string.
  if (!this->OrderDependentRPath) {
    return "";
  }

  // Construct the linker runtime search path. These MUST NOT contain tokens
  // such as $ORIGIN, see https://sourceware.org/bugzilla/show_bug.cgi?id=16936
  return cmJoin(this->OrderDependentRPath->GetOrderedDirectories(), ":");
}

std::vector<std::string> const& cmComputeLinkInformation::GetDepends() const
{
  return this->Depends;
}

std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
  const
{
  return this->FrameworkPaths;
}

std::set<std::string> const&
cmComputeLinkInformation::GetFrameworkPathsEmitted() const
{
  return this->FrameworkPathsEmitted;
}

const std::set<const cmGeneratorTarget*>&
cmComputeLinkInformation::GetSharedLibrariesLinked() const
{
  return this->SharedLibrariesLinked;
}

bool cmComputeLinkInformation::Compute()
{
  // Skip targets that do not link.
  if (!(this->Target->GetType() == cmStateEnums::EXECUTABLE ||
        this->Target->GetType() == cmStateEnums::SHARED_LIBRARY ||
        this->Target->GetType() == cmStateEnums::MODULE_LIBRARY ||
        this->Target->GetType() == cmStateEnums::STATIC_LIBRARY)) {
    return false;
  }

  // We require a link language for the target.
  if (this->LinkLanguage.empty()) {
    cmSystemTools::Error(
      "CMake can not determine linker language for target: " +
      this->Target->GetName());
    return false;
  }

  // Compute the ordered link line items.
  cmComputeLinkDepends cld(this->Target, this->Config, this->LinkLanguage);
  cld.SetOldLinkDirMode(this->OldLinkDirMode);
  cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
  FeatureDescriptor const* currentFeature = nullptr;

  // Add the link line items.
  for (cmComputeLinkDepends::LinkEntry const& linkEntry : linkEntries) {
    if (linkEntry.Kind == cmComputeLinkDepends::LinkEntry::Group) {
      const auto& groupFeature = this->GetGroupFeature(linkEntry.Feature);
      if (groupFeature.Supported) {
        this->Items.emplace_back(
          BT<std::string>{ linkEntry.Item.Value == "<LINK_GROUP>"
                             ? groupFeature.Prefix
                             : groupFeature.Suffix,
                           linkEntry.Item.Backtrace },
          ItemIsPath::No);
      }
      continue;
    }

    if (currentFeature != nullptr &&
        linkEntry.Feature != currentFeature->Name) {
      // emit feature suffix, if any
      if (!currentFeature->Suffix.empty()) {
        this->Items.emplace_back(
          BT<std::string>{ currentFeature->Suffix,
                           this->Items.back().Value.Backtrace },
          ItemIsPath::No);
      }
      currentFeature = nullptr;
    }

    if (linkEntry.Feature != DEFAULT &&
        (currentFeature == nullptr ||
         linkEntry.Feature != currentFeature->Name)) {
      if (!this->AddLibraryFeature(linkEntry.Feature)) {
        continue;
      }
      currentFeature = this->FindLibraryFeature(linkEntry.Feature);
      // emit feature prefix, if any
      if (!currentFeature->Prefix.empty()) {
        this->Items.emplace_back(
          BT<std::string>{ currentFeature->Prefix, linkEntry.Item.Backtrace },
          ItemIsPath::No);
      }
    }

    if (linkEntry.Kind == cmComputeLinkDepends::LinkEntry::SharedDep) {
      this->AddSharedDepItem(linkEntry);
    } else {
      this->AddItem(linkEntry);
    }
  }

  if (currentFeature != nullptr) {
    // emit feature suffix, if any
    if (!currentFeature->Suffix.empty()) {
      this->Items.emplace_back(
        BT<std::string>{ currentFeature->Suffix,
                         this->Items.back().Value.Backtrace },
        ItemIsPath::No);
    }
  }

  // Restore the target link type so the correct system runtime
  // libraries are found.
  cmValue lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
  if (cmIsOn(lss)) {
    this->SetCurrentLinkType(LinkStatic);
  } else {
    this->SetCurrentLinkType(this->StartLinkType);
  }

  // Finish listing compatibility paths.
  if (this->OldLinkDirMode) {
    // For CMake 2.4 bug-compatibility we need to consider the output
    // directories of targets linked in another configuration as link
    // directories.
    std::set<cmGeneratorTarget const*> const& wrongItems =
      cld.GetOldWrongConfigItems();
    for (cmGeneratorTarget const* tgt : wrongItems) {
      cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(this->Config)
        ? cmStateEnums::ImportLibraryArtifact
        : cmStateEnums::RuntimeBinaryArtifact;
      this->OldLinkDirItems.push_back(
        tgt->GetFullPath(this->Config, artifact, true));
    }
  }

  // Finish setting up linker search directories.
  if (!this->FinishLinkerSearchDirectories()) {
    return false;
  }

  // Add implicit language runtime libraries and directories.
  this->AddImplicitLinkInfo();

  if (!this->CMP0060WarnItems.empty()) {
    std::ostringstream w;
    /* clang-format off */
    w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0060) << "\n"
      "Some library files are in directories implicitly searched by "
      "the linker when invoked for " << this->LinkLanguage << ":\n"
      " " << cmJoin(this->CMP0060WarnItems, "\n ") << "\n"
      "For compatibility with older versions of CMake, the generated "
      "link line will ask the linker to search for these by library "
      "name."
      ;
    /* clang-format on */
    this->CMakeInstance->IssueMessage(MessageType::AUTHOR_WARNING, w.str(),
                                      this->Target->GetBacktrace());
  }

  return true;
}

namespace {
void FinalizeFeatureFormat(std::string& format, const std::string& activeTag,
                           const std::string& otherTag)
{
  auto pos = format.find(otherTag);
  if (pos != std::string::npos) {
    format.erase(pos, format.find('}', pos) - pos + 1);
  }
  pos = format.find(activeTag);
  if (pos != std::string::npos) {
    format.erase(pos, activeTag.length());
    pos = format.find('}', pos);
    if (pos != std::string::npos) {
      format.erase(pos, 1);
    }
  }
}

bool IsValidFeatureFormat(const std::string& format)
{
  return format.find("<LIBRARY>") != std::string::npos ||
    format.find("<LIB_ITEM>") != std::string::npos ||
    format.find("<LINK_ITEM>") != std::string::npos;
}

class FeaturePlaceHolderExpander : public cmPlaceholderExpander
{
public:
  FeaturePlaceHolderExpander(const std::string* library,
                             const std::string* libItem = nullptr,
                             const std::string* linkItem = nullptr)
    : Library(library)
    , LibItem(libItem)
    , LinkItem(linkItem)
  {
  }

private:
  std::string ExpandVariable(std::string const& variable) override
  {
    if (this->Library != nullptr && variable == "LIBRARY") {
      return *this->Library;
    }
    if (this->LibItem != nullptr && variable == "LIB_ITEM") {
      return *this->LibItem;
    }
    if (this->LinkItem != nullptr && variable == "LINK_ITEM") {
      return *this->LinkItem;
    }

    return variable;
  }

  const std::string* Library = nullptr;
  const std::string* LibItem = nullptr;
  const std::string* LinkItem = nullptr;
};
}

cmComputeLinkInformation::FeatureDescriptor::FeatureDescriptor(
  std::string name, std::string itemFormat)
  : Name(std::move(name))
  , Supported(true)
  , ItemPathFormat(std::move(itemFormat))
  , ItemNameFormat(this->ItemPathFormat)
{
}
cmComputeLinkInformation::FeatureDescriptor::FeatureDescriptor(
  std::string name, std::string itemPathFormat, std::string itemNameFormat)
  : Name(std::move(name))
  , Supported(true)
  , ItemPathFormat(std::move(itemPathFormat))
  , ItemNameFormat(std::move(itemNameFormat))
{
}
cmComputeLinkInformation::FeatureDescriptor::FeatureDescriptor(
  std::string name, std::string prefix, std::string itemPathFormat,
  std::string itemNameFormat, std::string suffix)
  : Name(std::move(name))
  , Supported(true)
  , Prefix(std::move(prefix))
  , Suffix(std::move(suffix))
  , ItemPathFormat(std::move(itemPathFormat))
  , ItemNameFormat(std::move(itemNameFormat))
{
}
cmComputeLinkInformation::FeatureDescriptor::FeatureDescriptor(
  std::string name, std::string prefix, std::string suffix, bool)
  : Name(std::move(name))
  , Supported(true)
  , Prefix(std::move(prefix))
  , Suffix(std::move(suffix))
{
}

std::string cmComputeLinkInformation::FeatureDescriptor::GetDecoratedItem(
  std::string const& library, ItemIsPath isPath) const
{
  auto format =
    isPath == ItemIsPath::Yes ? this->ItemPathFormat : this->ItemNameFormat;

  // replace <LIBRARY>, <LIB_ITEM> and <LINK_ITEM> patterns with library path
  FeaturePlaceHolderExpander expander(&library, &library, &library);
  return expander.ExpandVariables(format);
}
std::string cmComputeLinkInformation::FeatureDescriptor::GetDecoratedItem(
  std::string const& library, std::string const& libItem,
  std::string const& linkItem, ItemIsPath isPath) const
{
  auto format =
    isPath == ItemIsPath::Yes ? this->ItemPathFormat : this->ItemNameFormat;

  // replace <LIBRARY>, <LIB_ITEM> and <LINK_ITEM> patterns
  FeaturePlaceHolderExpander expander(&library, &libItem, &linkItem);
  return expander.ExpandVariables(format);
}

cmComputeLinkInformation::LibraryFeatureDescriptor::LibraryFeatureDescriptor(
  std::string name, std::string itemFormat)
  : FeatureDescriptor(std::move(name), std::move(itemFormat))
{
}
cmComputeLinkInformation::LibraryFeatureDescriptor::LibraryFeatureDescriptor(
  std::string name, std::string itemPathFormat, std::string itemNameFormat)
  : FeatureDescriptor(std::move(name), std::move(itemPathFormat),
                      std::move(itemNameFormat))
{
}
cmComputeLinkInformation::LibraryFeatureDescriptor::LibraryFeatureDescriptor(
  std::string name, std::string prefix, std::string itemPathFormat,
  std::string itemNameFormat, std::string suffix)
  : FeatureDescriptor(std::move(name), std::move(prefix),
                      std::move(itemPathFormat), std::move(itemNameFormat),
                      std::move(suffix))
{
}

bool cmComputeLinkInformation::AddLibraryFeature(std::string const& feature)
{
  auto it = this->LibraryFeatureDescriptors.find(feature);
  if (it != this->LibraryFeatureDescriptors.end()) {
    return it->second.Supported;
  }

  auto featureName =
    cmStrCat("CMAKE_", this->LinkLanguage, "_LINK_LIBRARY_USING_", feature);
  cmValue featureSupported =
    this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
  if (!featureSupported) {
    // language specific variable is not defined, fallback to the more generic
    // one
    featureName = cmStrCat("CMAKE_LINK_LIBRARY_USING_", feature);
    featureSupported =
      this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
  }
  if (!featureSupported.IsOn()) {
    this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});

    this->CMakeInstance->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat(
        "Feature '", feature,
        "', specified through generator-expression '$<LINK_LIBRARY>' to "
        "link target '",
        this->Target->GetName(), "', is not supported for the '",
        this->LinkLanguage, "' link language."),
      this->Target->GetBacktrace());

    return false;
  }

  cmValue langFeature = this->Makefile->GetDefinition(featureName);
  if (!langFeature) {
    this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});

    this->CMakeInstance->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat(
        "Feature '", feature,
        "', specified through generator-expression '$<LINK_LIBRARY>' to "
        "link target '",
        this->Target->GetName(), "', is not defined for the '",
        this->LinkLanguage, "' link language."),
      this->Target->GetBacktrace());

    return false;
  }

  auto items =
    cmExpandListWithBacktrace(langFeature, this->Target->GetBacktrace(), true);

  if ((items.size() == 1 && !IsValidFeatureFormat(items.front().Value)) ||
      (items.size() == 3 && !IsValidFeatureFormat(items[1].Value))) {
    this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
    this->CMakeInstance->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("Feature '", feature, "', specified by variable '", featureName,
               "', is malformed (\"<LIBRARY>\", \"<LIB_ITEM>\", or "
               "\"<LINK_ITEM>\" patterns "
               "are missing) and cannot be used to link target '",
               this->Target->GetName(), "'."),
      this->Target->GetBacktrace());

    return false;
  }

  // now, handle possible "PATH{}" and "NAME{}" patterns
  if (items.size() == 1) {
    items.push_back(items.front());
    FinalizeFeatureFormat(items[0].Value, "PATH{", "NAME{");
    FinalizeFeatureFormat(items[1].Value, "NAME{", "PATH{");
  } else if (items.size() == 3) {
    items.insert(items.begin() + 1, items[1]);
    FinalizeFeatureFormat(items[1].Value, "PATH{", "NAME{");
    FinalizeFeatureFormat(items[2].Value, "NAME{", "PATH{");
  } else {
    this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
    this->CMakeInstance->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("Feature '", feature, "', specified by variable '", featureName,
               "', is malformed (wrong number of elements) and cannot be used "
               "to link target '",
               this->Target->GetName(), "'."),
      this->Target->GetBacktrace());

    return false;
  }
  if ((items.size() == 2 && !IsValidFeatureFormat(items[0].Value)) ||
      (items.size() == 4 && !IsValidFeatureFormat(items[1].Value))) {
    // PATH{} has wrong format
    this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
    this->CMakeInstance->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("Feature '", feature, "', specified by variable '", featureName,
               "', is malformed (\"<LIBRARY>\", \"<LIB_ITEM>\", or "
               "\"<LINK_ITEM>\" patterns "
               "are missing for \"PATH{}\" alternative) and cannot be used to "
               "link target '",
               this->Target->GetName(), "'."),
      this->Target->GetBacktrace());

    return false;
  }
  if ((items.size() == 2 && !IsValidFeatureFormat(items[1].Value)) ||
      (items.size() == 4 && !IsValidFeatureFormat(items[2].Value))) {
    // NAME{} has wrong format
    this->LibraryFeatureDescriptors.emplace(feature, FeatureDescriptor{});
    this->CMakeInstance->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("Feature '", feature, "', specified by variable '", featureName,
               "', is malformed (\"<LIBRARY>\", \"<LIB_ITEM>\", or "
               "\"<LINK_ITEM>\" patterns "
               "are missing for \"NAME{}\" alternative) and cannot be used to "
               "link target '",
               this->Target->GetName(), "'."),
      this->Target->GetBacktrace());

    return false;
  }

  // replace LINKER: pattern
  this->Target->ResolveLinkerWrapper(items, this->LinkLanguage, true);

  if (items.size() == 2) {
    this->LibraryFeatureDescriptors.emplace(
      feature,
      LibraryFeatureDescriptor{ feature, items[0].Value, items[1].Value });
  } else {
    this->LibraryFeatureDescriptors.emplace(
      feature,
      LibraryFeatureDescriptor{ feature, items[0].Value, items[1].Value,
                                items[2].Value, items[3].Value });
  }

  return true;
}

cmComputeLinkInformation::FeatureDescriptor const&
cmComputeLinkInformation::GetLibraryFeature(std::string const& feature) const
{
  return this->LibraryFeatureDescriptors.find(feature)->second;
}
cmComputeLinkInformation::FeatureDescriptor const*
cmComputeLinkInformation::FindLibraryFeature(std::string const& feature) const
{
  auto it = this->LibraryFeatureDescriptors.find(feature);
  if (it == this->LibraryFeatureDescriptors.end()) {
    return nullptr;
  }

  return &it->second;
}

cmComputeLinkInformation::GroupFeatureDescriptor::GroupFeatureDescriptor(
  std::string name, std::string prefix, std::string suffix)
  : FeatureDescriptor(std::move(name), std::move(prefix), std::move(suffix),
                      true)
{
}

cmComputeLinkInformation::FeatureDescriptor const&
cmComputeLinkInformation::GetGroupFeature(std::string const& feature)
{
  auto it = this->GroupFeatureDescriptors.find(feature);
  if (it != this->GroupFeatureDescriptors.end()) {
    return it->second;
  }

  auto featureName =
    cmStrCat("CMAKE_", this->LinkLanguage, "_LINK_GROUP_USING_", feature);
  cmValue featureSupported =
    this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
  if (!featureSupported) {
    // language specific variable is not defined, fallback to the more generic
    // one
    featureName = cmStrCat("CMAKE_LINK_GROUP_USING_", feature);
    featureSupported =
      this->Makefile->GetDefinition(cmStrCat(featureName, "_SUPPORTED"));
  }
  if (!featureSupported.IsOn()) {
    this->CMakeInstance->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("Feature '", feature,
               "', specified through generator-expression '$<LINK_GROUP>' to "
               "link target '",
               this->Target->GetName(), "', is not supported for the '",
               this->LinkLanguage, "' link language."),
      this->Target->GetBacktrace());
    return this->GroupFeatureDescriptors.emplace(feature, FeatureDescriptor{})
      .first->second;
  }

  cmValue langFeature = this->Makefile->GetDefinition(featureName);
  if (!langFeature) {
    this->CMakeInstance->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("Feature '", feature,
               "', specified through generator-expression '$<LINK_GROUP>' to "
               "link target '",
               this->Target->GetName(), "', is not defined for the '",
               this->LinkLanguage, "' link language."),
      this->Target->GetBacktrace());
    return this->GroupFeatureDescriptors.emplace(feature, FeatureDescriptor{})
      .first->second;
  }

  auto items =
    cmExpandListWithBacktrace(langFeature, this->Target->GetBacktrace(), true);

  // replace LINKER: pattern
  this->Target->ResolveLinkerWrapper(items, this->LinkLanguage, true);

  if (items.size() == 2) {
    return this->GroupFeatureDescriptors
      .emplace(
        feature,
        GroupFeatureDescriptor{ feature, items[0].Value, items[1].Value })
      .first->second;
  }

  this->CMakeInstance->IssueMessage(
    MessageType::FATAL_ERROR,
    cmStrCat("Feature '", feature, "', specified by variable '", featureName,
             "', is malformed (wrong number of elements) and cannot be used "
             "to link target '",
             this->Target->GetName(), "'."),
    this->Target->GetBacktrace());
  return this->GroupFeatureDescriptors.emplace(feature, FeatureDescriptor{})
    .first->second;
}

void cmComputeLinkInformation::AddImplicitLinkInfo()
{
  // The link closure lists all languages whose implicit info is needed.
  cmGeneratorTarget::LinkClosure const* lc =
    this->Target->GetLinkClosure(this->Config);
  for (std::string const& li : lc->Languages) {

    if (li == "CUDA" || li == "HIP") {
      // These need to go before the other implicit link information
      // as they could require symbols from those other library
      // Currently restricted as CUDA and HIP are the only languages
      // we have documented runtime behavior controls for
      this->AddRuntimeLinkLibrary(li);
    }

    // Skip those of the linker language.  They are implicit.
    if (li != this->LinkLanguage) {
      this->AddImplicitLinkInfo(li);
    }
  }
}

void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
{
  std::string const& runtimeLibrary =
    this->Target->GetRuntimeLinkLibrary(lang, this->Config);
  if (runtimeLibrary.empty()) {
    return;
  }
  if (cmValue runtimeLinkOptions = this->Makefile->GetDefinition(
        "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" + runtimeLibrary)) {
    std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions);
    for (std::string const& i : libsVec) {
      if (!cm::contains(this->ImplicitLinkLibs, i)) {
        this->AddItem({ i });
      }
    }
  }
}

void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
{
  // Add libraries for this language that are not implied by the
  // linker language.
  std::string libVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_LIBRARIES");
  if (cmValue libs = this->Makefile->GetDefinition(libVar)) {
    std::vector<std::string> libsVec = cmExpandedList(*libs);
    for (std::string const& i : libsVec) {
      if (!cm::contains(this->ImplicitLinkLibs, i)) {
        this->AddItem({ i });
      }
    }
  }

  // Add linker search paths for this language that are not
  // implied by the linker language.
  std::string dirVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_DIRECTORIES");
  if (cmValue dirs = this->Makefile->GetDefinition(dirVar)) {
    std::vector<std::string> dirsVec = cmExpandedList(*dirs);
    this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
  }
}

void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
{
  cmGeneratorTarget const* tgt = entry.Target;
  BT<std::string> const& item = entry.Item;

  // Compute the proper name to use to link this library.
  const std::string& config = this->Config;
  bool impexe = (tgt && tgt->IsExecutableWithExports());
  if (impexe && !tgt->HasImportLibrary(config) && !this->LoaderFlag) {
    // Skip linking to executables on platforms with no import
    // libraries or loader flags.
    return;
  }

  if (tgt && tgt->IsLinkable()) {
    // This is a CMake target.  Ask the target for its real name.
    if (impexe && this->LoaderFlag) {
      // This link item is an executable that may provide symbols
      // used by this target.  A special flag is needed on this
      // platform.  Add it now using a special feature.
      cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
        ? cmStateEnums::ImportLibraryArtifact
        : cmStateEnums::RuntimeBinaryArtifact;
      std::string exe = tgt->GetFullPath(config, artifact, true);
      this->Items.emplace_back(
        BT<std::string>(exe, item.Backtrace), ItemIsPath::Yes, tgt,
        this->FindLibraryFeature(entry.Feature == DEFAULT
                                   ? "__CMAKE_LINK_EXECUTABLE"
                                   : entry.Feature));
      this->Depends.push_back(std::move(exe));
    } else if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
      // Add the interface library as an item so it can be considered as part
      // of COMPATIBLE_INTERFACE_ enforcement.  The generators will ignore
      // this for the actual link line.
      this->Items.emplace_back(std::string(), ItemIsPath::No, tgt);

      // Also add the item the interface specifies to be used in its place.
      std::string const& libName = tgt->GetImportedLibName(config);
      if (!libName.empty()) {
        this->AddItem(BT<std::string>(libName, item.Backtrace));
      }
    } else if (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) {
      // Ignore object library!
      // Its object-files should already have been extracted for linking.
    } else {
      // Decide whether to use an import library.
      cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
        ? cmStateEnums::ImportLibraryArtifact
        : cmStateEnums::RuntimeBinaryArtifact;

      // Pass the full path to the target file.
      BT<std::string> lib = BT<std::string>(
        tgt->GetFullPath(config, artifact, true), item.Backtrace);
      if (tgt->Target->IsAIX() && cmHasLiteralSuffix(lib.Value, "-NOTFOUND") &&
          artifact == cmStateEnums::ImportLibraryArtifact) {
        // This is an imported executable on AIX that has ENABLE_EXPORTS
        // but not IMPORTED_IMPLIB.  CMake used to produce and accept such
        // imported executables on AIX before we taught it to use linker
        // import files.  For compatibility, simply skip linking to this
        // executable as we did before.  It works with runtime linking.
        return;
      }
      if (!this->LinkDependsNoShared ||
          tgt->GetType() != cmStateEnums::SHARED_LIBRARY) {
        this->Depends.push_back(lib.Value);
      }

      LinkEntry libEntry{ entry };
      libEntry.Item = lib;
      this->AddTargetItem(libEntry);
      this->AddLibraryRuntimeInfo(lib.Value, tgt);
      if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY &&
          this->Target->IsDLLPlatform()) {
        this->AddRuntimeDLL(tgt);
      }
    }
  } else {
    // This is not a CMake target.  Use the name given.
    if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s) ||
        (entry.Feature == DEFAULT &&
         cmSystemTools::IsPathToFramework(item.Value) &&
         this->Makefile->IsOn("APPLE"))) {
      // This is a framework.
      this->AddFrameworkItem(entry);
    } else if (cmSystemTools::FileIsFullPath(item.Value)) {
      if (cmSystemTools::FileIsDirectory(item.Value)) {
        // This is a directory.
        this->DropDirectoryItem(item);
      } else {
        // Use the full path given to the library file.
        this->Depends.push_back(item.Value);
        this->AddFullItem(entry);
        this->AddLibraryRuntimeInfo(item.Value);
      }
    } else {
      // This is a library or option specified by the user.
      this->AddUserItem(entry, true);
    }
  }
}

void cmComputeLinkInformation::AddSharedDepItem(LinkEntry const& entry)
{
  BT<std::string> const& item = entry.Item;
  const cmGeneratorTarget* tgt = entry.Target;

  // Record dependencies on DLLs.
  if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY &&
      this->Target->IsDLLPlatform() &&
      this->SharedDependencyMode != SharedDepModeLink) {
    this->AddRuntimeDLL(tgt);
  }

  // If dropping shared library dependencies, ignore them.
  if (this->SharedDependencyMode == SharedDepModeNone) {
    return;
  }

  // The user may have incorrectly named an item.  Skip items that are
  // not full paths to shared libraries.
  if (tgt) {
    // The target will provide a full path.  Make sure it is a shared
    // library.
    if (tgt->GetType() != cmStateEnums::SHARED_LIBRARY) {
      return;
    }
  } else {
    // Skip items that are not full paths.  We will not be able to
    // reliably specify them.
    if (!cmSystemTools::FileIsFullPath(item.Value)) {
      return;
    }

    // Get the name of the library from the file name.
    std::string file = cmSystemTools::GetFilenameName(item.Value);
    if (!this->ExtractSharedLibraryName.find(file)) {
      // This is not the name of a shared library.
      return;
    }
  }

  // If in linking mode, just link to the shared library.
  if (this->SharedDependencyMode == SharedDepModeLink) {
    this->AddItem(entry);
    return;
  }

  // Get a full path to the dependent shared library.
  // Add it to the runtime path computation so that the target being
  // linked will be able to find it.
  std::string lib;
  if (tgt) {
    cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(this->Config)
      ? cmStateEnums::ImportLibraryArtifact
      : cmStateEnums::RuntimeBinaryArtifact;
    lib = tgt->GetFullPath(this->Config, artifact);
    this->AddLibraryRuntimeInfo(lib, tgt);
  } else {
    lib = item.Value;
    this->AddLibraryRuntimeInfo(lib);
  }

  // Check if we need to include the dependent shared library in other
  // path ordering.
  cmOrderDirectories* order = nullptr;
  if (this->SharedDependencyMode == SharedDepModeLibDir &&
      !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */) {
    // Add the item to the linker search path.
    order = this->OrderLinkerSearchPath.get();
  } else if (this->SharedDependencyMode == SharedDepModeDir) {
    // Add the item to the separate dependent library search path.
    order = this->OrderDependentRPath.get();
  }
  if (order) {
    if (tgt) {
      std::string soName = tgt->GetSOName(this->Config);
      const char* soname = soName.empty() ? nullptr : soName.c_str();
      order->AddRuntimeLibrary(lib, soname);
    } else {
      order->AddRuntimeLibrary(lib);
    }
  }
}

void cmComputeLinkInformation::AddRuntimeDLL(cmGeneratorTarget const* tgt)
{
  if (std::find(this->RuntimeDLLs.begin(), this->RuntimeDLLs.end(), tgt) ==
      this->RuntimeDLLs.end()) {
    this->RuntimeDLLs.emplace_back(tgt);
  }
}

void cmComputeLinkInformation::ComputeLinkTypeInfo()
{
  // Check whether archives may actually be shared libraries.
  this->ArchivesMayBeShared =
    this->CMakeInstance->GetState()->GetGlobalPropertyAsBool(
      "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");

  // First assume we cannot do link type stuff.
  this->LinkTypeEnabled = false;

  // Lookup link type selection flags.
  cmValue static_link_type_flag = nullptr;
  cmValue shared_link_type_flag = nullptr;
  const char* target_type_str = nullptr;
  switch (this->Target->GetType()) {
    case cmStateEnums::EXECUTABLE:
      target_type_str = "EXE";
      break;
    case cmStateEnums::SHARED_LIBRARY:
      target_type_str = "SHARED_LIBRARY";
      break;
    case cmStateEnums::MODULE_LIBRARY:
      target_type_str = "SHARED_MODULE";
      break;
    default:
      break;
  }
  if (target_type_str) {
    std::string static_link_type_flag_var =
      cmStrCat("CMAKE_", target_type_str, "_LINK_STATIC_", this->LinkLanguage,
               "_FLAGS");
    static_link_type_flag =
      this->Makefile->GetDefinition(static_link_type_flag_var);

    std::string shared_link_type_flag_var =
      cmStrCat("CMAKE_", target_type_str, "_LINK_DYNAMIC_", this->LinkLanguage,
               "_FLAGS");
    shared_link_type_flag =
      this->Makefile->GetDefinition(shared_link_type_flag_var);
  }

  // We can support link type switching only if all needed flags are
  // known.
  if (cmNonempty(static_link_type_flag) && cmNonempty(shared_link_type_flag)) {
    this->LinkTypeEnabled = true;
    this->StaticLinkTypeFlag = *static_link_type_flag;
    this->SharedLinkTypeFlag = *shared_link_type_flag;
  }

  // Lookup the starting link type from the target (linked statically?).
  cmValue lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
  this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared;
  this->CurrentLinkType = this->StartLinkType;
}

void cmComputeLinkInformation::ComputeItemParserInfo()
{
  // Get possible library name prefixes.
  cmMakefile* mf = this->Makefile;
  this->AddLinkPrefix(mf->GetSafeDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
  this->AddLinkPrefix(mf->GetSafeDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));

  // Import library names should be matched and treated as shared
  // libraries for the purposes of linking.
  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
                         LinkShared);
  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
                         LinkStatic);
  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
                         LinkShared);
  this->AddLinkExtension(mf->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
                         LinkUnknown);
  if (cmValue linkSuffixes =
        mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
    std::vector<std::string> linkSuffixVec = cmExpandedList(*linkSuffixes);
    for (std::string const& i : linkSuffixVec) {
      this->AddLinkExtension(i, LinkUnknown);
    }
  }
  if (cmValue sharedSuffixes =
        mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
    std::vector<std::string> sharedSuffixVec = cmExpandedList(*sharedSuffixes);
    for (std::string const& i : sharedSuffixVec) {
      this->AddLinkExtension(i, LinkShared);
    }
  }

  // Compute a regex to match link extensions.
  std::string libext =
    this->CreateExtensionRegex(this->LinkExtensions, LinkUnknown);

  // Create regex to remove any library extension.
  std::string reg("(.*)");
  reg += libext;
  this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions, reg);

  // Create a regex to match a library name.  Match index 1 will be
  // the prefix if it exists and empty otherwise.  Match index 2 will
  // be the library name.  Match index 3 will be the library
  // extension.
  reg = "^(";
  for (std::string const& p : this->LinkPrefixes) {
    reg += p;
    reg += "|";
  }
  reg += ")";
  reg += "([^/:]*)";

  // Create a regex to match any library name.
  std::string reg_any = cmStrCat(reg, libext);
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
  fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
#endif
  this->ExtractAnyLibraryName.compile(reg_any);

  // Create a regex to match static library names.
  if (!this->StaticLinkExtensions.empty()) {
    std::string reg_static = cmStrCat(
      reg, this->CreateExtensionRegex(this->StaticLinkExtensions, LinkStatic));
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
    fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
#endif
    this->ExtractStaticLibraryName.compile(reg_static);
  }

  // Create a regex to match shared library names.
  if (!this->SharedLinkExtensions.empty()) {
    std::string reg_shared = reg;
    this->SharedRegexString =
      this->CreateExtensionRegex(this->SharedLinkExtensions, LinkShared);
    reg_shared += this->SharedRegexString;
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
    fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
#endif
    this->ExtractSharedLibraryName.compile(reg_shared);
  }
}

void cmComputeLinkInformation::AddLinkPrefix(std::string const& p)
{
  if (!p.empty()) {
    this->LinkPrefixes.insert(p);
  }
}

void cmComputeLinkInformation::AddLinkExtension(std::string const& e,
                                                LinkType type)
{
  if (!e.empty()) {
    if (type == LinkStatic) {
      this->StaticLinkExtensions.emplace_back(e);
    }
    if (type == LinkShared) {
      this->SharedLinkExtensions.emplace_back(e);
    }
    this->LinkExtensions.emplace_back(e);
  }
}

// XXX(clang-tidy): This method's const-ness is platform dependent, so we
// cannot make it `const` as `clang-tidy` wants us to.
// NOLINTNEXTLINE(readability-make-member-function-const)
std::string cmComputeLinkInformation::CreateExtensionRegex(
  std::vector<std::string> const& exts, LinkType type)
{
  // Build a list of extension choices.
  std::string libext = "(";
  const char* sep = "";
  for (std::string const& i : exts) {
    // Separate this choice from the previous one.
    libext += sep;
    sep = "|";

    // Store this extension choice with the "." escaped.
    libext += "\\";
#if defined(_WIN32) && !defined(__CYGWIN__)
    libext += this->NoCaseExpression(i);
#else
    libext += i;
#endif
  }

  // Finish the list.
  libext += ")";

  // Add an optional OpenBSD-style version or major.minor.version component.
  if (this->OpenBSD || type == LinkShared) {
    libext += "(\\.[0-9]+)*";
  }

  libext += "$";
  return libext;
}

std::string cmComputeLinkInformation::NoCaseExpression(std::string const& str)
{
  std::string ret;
  ret.reserve(str.size() * 4);
  for (char c : str) {
    if (c == '.') {
      ret += c;
    } else {
      ret += '[';
      ret += static_cast<char>(tolower(c));
      ret += static_cast<char>(toupper(c));
      ret += ']';
    }
  }
  return ret;
}

void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
{
  // If we are changing the current link type add the flag to tell the
  // linker about it.
  if (this->CurrentLinkType != lt) {
    this->CurrentLinkType = lt;

    if (this->LinkTypeEnabled) {
      switch (this->CurrentLinkType) {
        case LinkStatic:
          this->Items.emplace_back(this->StaticLinkTypeFlag, ItemIsPath::No);
          break;
        case LinkShared:
          this->Items.emplace_back(this->SharedLinkTypeFlag, ItemIsPath::No);
          break;
        default:
          break;
      }
    }
  }
}

void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
{
  // This is called to handle a link item that is a full path to a target.
  // If the target is not a static library make sure the link type is
  // shared.  This is because dynamic-mode linking can handle both
  // shared and static libraries but static-mode can handle only
  // static libraries.  If a previous user item changed the link type
  // to static we need to make sure it is back to shared.
  BT<std::string> const& item = entry.Item;
  cmGeneratorTarget const* target = entry.Target;

  if (target->GetType() != cmStateEnums::STATIC_LIBRARY) {
    this->SetCurrentLinkType(LinkShared);
  }

  // Keep track of shared library targets linked.
  if (target->GetType() == cmStateEnums::SHARED_LIBRARY) {
    this->SharedLibrariesLinked.insert(target);
  }

  // Handle case of an imported shared library with no soname.
  if (this->NoSONameUsesPath &&
      target->IsImportedSharedLibWithoutSOName(this->Config)) {
    this->AddSharedLibNoSOName(entry);
    return;
  }

  // For compatibility with CMake 2.4 include the item's directory in
  // the linker search path.
  if (this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
      !cm::contains(this->OldLinkDirMask,
                    cmSystemTools::GetFilenamePath(item.Value))) {
    this->OldLinkDirItems.push_back(item.Value);
  }

  if (target->IsFrameworkOnApple() && this->GlobalGenerator->IsXcode() &&
      entry.Feature == DEFAULT) {
    // ensure FRAMEWORK feature is loaded
    this->AddLibraryFeature("FRAMEWORK");
  }

  if (target->IsFrameworkOnApple() && !this->GlobalGenerator->IsXcode()) {
    // Add the framework directory and the framework item itself
    auto fwItems = this->GlobalGenerator->SplitFrameworkPath(item.Value, true);
    if (!fwItems) {
      this->CMakeInstance->IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat("Could not parse framework path \"", item.Value,
                 "\" linked by target ", this->Target->GetName(), '.'),
        item.Backtrace);
      return;
    }
    if (!fwItems->first.empty()) {
      // Add the directory portion to the framework search path.
      this->AddFrameworkPath(fwItems->first);
    }
    if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) {
      this->Items.emplace_back(fwItems->second, ItemIsPath::Yes, target,
                               this->FindLibraryFeature(entry.Feature));
    } else {
      this->Items.emplace_back(
        item, ItemIsPath::Yes, target,
        this->FindLibraryFeature(
          entry.Feature == DEFAULT ? "__CMAKE_LINK_LIBRARY" : entry.Feature));
    }
  } else {
    // Now add the full path to the library.
    this->Items.emplace_back(
      item, ItemIsPath::Yes, target,
      this->FindLibraryFeature(
        entry.Feature == DEFAULT
          ? (target->IsFrameworkOnApple() && this->GlobalGenerator->IsXcode()
               ? "FRAMEWORK"
               : "__CMAKE_LINK_LIBRARY")
          : entry.Feature));
  }
}

void cmComputeLinkInformation::AddFullItem(LinkEntry const& entry)
{
  BT<std::string> const& item = entry.Item;

  // Check for the implicit link directory special case.
  if (this->CheckImplicitDirItem(entry)) {
    return;
  }

  // Check for case of shared library with no builtin soname.
  if (this->NoSONameUsesPath && this->CheckSharedLibNoSOName(entry)) {
    return;
  }

  // Full path libraries should specify a valid library file name.
  // See documentation of CMP0008.
  std::string generator = this->GlobalGenerator->GetName();
  if (this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
      (generator.find("Visual Studio") != std::string::npos ||
       generator.find("Xcode") != std::string::npos)) {
    std::string file = cmSystemTools::GetFilenameName(item.Value);
    if (!this->ExtractAnyLibraryName.find(file)) {
      this->HandleBadFullItem(entry, file);
      return;
    }
  }

  // This is called to handle a link item that is a full path.
  // If the target is not a static library make sure the link type is
  // shared.  This is because dynamic-mode linking can handle both
  // shared and static libraries but static-mode can handle only
  // static libraries.  If a previous user item changed the link type
  // to static we need to make sure it is back to shared.
  if (this->LinkTypeEnabled) {
    std::string name = cmSystemTools::GetFilenameName(item.Value);
    if (this->ExtractSharedLibraryName.find(name)) {
      this->SetCurrentLinkType(LinkShared);
    } else if (!this->ExtractStaticLibraryName.find(item.Value)) {
      // We cannot determine the type.  Assume it is the target's
      // default type.
      this->SetCurrentLinkType(this->StartLinkType);
    }
  }

  // For compatibility with CMake 2.4 include the item's directory in
  // the linker search path.
  if (this->OldLinkDirMode &&
      !cm::contains(this->OldLinkDirMask,
                    cmSystemTools::GetFilenamePath(item.Value))) {
    this->OldLinkDirItems.push_back(item.Value);
  }

  // Now add the full path to the library.
  this->Items.emplace_back(
    item, ItemIsPath::Yes, nullptr,
    this->FindLibraryFeature(
      entry.Feature == DEFAULT
        ? (entry.Kind == cmComputeLinkDepends::LinkEntry::Object
             ? "__CMAKE_LINK_OBJECT"
             : "__CMAKE_LINK_LIBRARY")
        : entry.Feature));
}

bool cmComputeLinkInformation::CheckImplicitDirItem(LinkEntry const& entry)
{
  BT<std::string> const& item = entry.Item;

  // We only switch to a pathless item if the link type may be
  // enforced.  Fortunately only platforms that support link types
  // seem to have magic per-architecture implicit link directories.
  if (!this->LinkTypeEnabled) {
    return false;
  }

  // Check if this item is in an implicit link directory.
  std::string dir = cmSystemTools::GetFilenamePath(item.Value);
  if (!cm::contains(this->ImplicitLinkDirs, dir)) {
    // Only libraries in implicit link directories are converted to
    // pathless items.
    return false;
  }

  // Only apply the policy below if the library file is one that can
  // be found by the linker.
  std::string file = cmSystemTools::GetFilenameName(item.Value);
  if (!this->ExtractAnyLibraryName.find(file)) {
    return false;
  }

  // Check the policy for whether we should use the approach below.
  switch (this->Target->GetPolicyStatusCMP0060()) {
    case cmPolicies::WARN:
      if (this->CMP0060Warn) {
        // Print the warning at most once for this item.
        std::string const& wid = "CMP0060-WARNING-GIVEN-" + item.Value;
        if (!this->CMakeInstance->GetPropertyAsBool(wid)) {
          this->CMakeInstance->SetProperty(wid, "1");
          this->CMP0060WarnItems.insert(item.Value);
        }
      }
      CM_FALLTHROUGH;
    case cmPolicies::OLD:
      break;
    case cmPolicies::REQUIRED_ALWAYS:
    case cmPolicies::REQUIRED_IF_USED:
    case cmPolicies::NEW:
      return false;
  }

  // Many system linkers support multiple architectures by
  // automatically selecting the implicit linker search path for the
  // current architecture.  If the library appears in an implicit link
  // directory then just report the file name without the directory
  // portion.  This will allow the system linker to locate the proper
  // library for the architecture at link time.
  LinkEntry fileEntry{ entry };
  fileEntry.Item = file;
  this->AddUserItem(fileEntry, false);

  // Make sure the link directory ordering will find the library.
  this->OrderLinkerSearchPath->AddLinkLibrary(item.Value);

  return true;
}

void cmComputeLinkInformation::AddUserItem(LinkEntry const& entry,
                                           bool pathNotKnown)
{
  // This is called to handle a link item that does not match a CMake
  // target and is not a full path.  We check here if it looks like a
  // library file name to automatically request the proper link type
  // from the linker.  For example:
  //
  //   foo       ==>  -lfoo
  //   libfoo.a  ==>  -Wl,-Bstatic -lfoo

  BT<std::string> const& item = entry.Item;

  if (item.Value[0] == '-' || item.Value[0] == '$' || item.Value[0] == '`') {
    // Pass flags through untouched.
    // if this is a -l option then we might need to warn about
    // CMP0003 so put it in OldUserFlagItems, if it is not a -l
    // or -Wl,-l (-framework -pthread), then allow it without a
    // CMP0003 as -L will not affect those other linker flags
    if (cmHasLiteralPrefix(item.Value, "-l") ||
        cmHasLiteralPrefix(item.Value, "-Wl,-l")) {
      // This is a linker option provided by the user.
      this->OldUserFlagItems.push_back(item.Value);
    }

    // Restore the target link type since this item does not specify
    // one.
    this->SetCurrentLinkType(this->StartLinkType);

    // Use the item verbatim.
    this->Items.emplace_back(item, ItemIsPath::No);
    return;
  }

  // Parse out the prefix, base, and suffix components of the
  // library name.  If the name matches that of a shared or static
  // library then set the link type accordingly.
  //
  // Search for shared library names first because some platforms
  // have shared libraries with names that match the static library
  // pattern.  For example cygwin and msys use the convention
  // libfoo.dll.a for import libraries and libfoo.a for static
  // libraries.  On AIX a library with the name libfoo.a can be
  // shared!
  std::string lib;
  if (this->ExtractSharedLibraryName.find(item.Value)) {
// This matches a shared library file name.
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
    fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
            this->ExtractSharedLibraryName.match(1).c_str(),
            this->ExtractSharedLibraryName.match(2).c_str(),
            this->ExtractSharedLibraryName.match(3).c_str());
#endif
    // Set the link type to shared.
    this->SetCurrentLinkType(LinkShared);

    // Use just the library name so the linker will search.
    lib = this->ExtractSharedLibraryName.match(2);
  } else if (this->ExtractStaticLibraryName.find(item.Value)) {
// This matches a static library file name.
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
    fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
            this->ExtractStaticLibraryName.match(1).c_str(),
            this->ExtractStaticLibraryName.match(2).c_str(),
            this->ExtractStaticLibraryName.match(3).c_str());
#endif
    // Set the link type to static.
    this->SetCurrentLinkType(LinkStatic);

    // Use just the library name so the linker will search.
    lib = this->ExtractStaticLibraryName.match(2);
  } else if (this->ExtractAnyLibraryName.find(item.Value)) {
// This matches a library file name.
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
    fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
            this->ExtractAnyLibraryName.match(1).c_str(),
            this->ExtractAnyLibraryName.match(2).c_str(),
            this->ExtractAnyLibraryName.match(3).c_str());
#endif
    // Restore the target link type since this item does not specify
    // one.
    this->SetCurrentLinkType(this->StartLinkType);

    // Use just the library name so the linker will search.
    lib = this->ExtractAnyLibraryName.match(2);
  } else {
    // This is a name specified by the user.
    if (pathNotKnown) {
      this->OldUserFlagItems.push_back(item.Value);
    }

    // We must ask the linker to search for a library with this name.
    // Restore the target link type since this item does not specify
    // one.
    this->SetCurrentLinkType(this->StartLinkType);
    lib = item.Value;
  }

  // Create an option to ask the linker to search for the library.
  auto out = cmStrCat(this->LibLinkFlag, lib, this->LibLinkSuffix);

  if (entry.Feature != DEFAULT) {
    auto const& feature = this->GetLibraryFeature(entry.Feature);
    this->Items.emplace_back(
      BT<std::string>(
        feature.GetDecoratedItem(cmStrCat(lib, this->LibLinkSuffix),
                                 item.Value, out, ItemIsPath::No),
        item.Backtrace),
      ItemIsPath::No);
  } else {
    this->Items.emplace_back(BT<std::string>(out, item.Backtrace),
                             ItemIsPath::No);
  }

  // Here we could try to find the library the linker will find and
  // add a runtime information entry for it.  It would probably not be
  // reliable and we want to encourage use of full paths for library
  // specification.
}

void cmComputeLinkInformation::AddFrameworkItem(LinkEntry const& entry)
{
  std::string const& item = entry.Item.Value;

  // Try to separate the framework name and path.
  auto fwItems =
    this->GlobalGenerator->SplitFrameworkPath(item, entry.Feature != DEFAULT);
  if (!fwItems) {
    std::ostringstream e;
    e << "Could not parse framework path \"" << item << "\" "
      << "linked by target " << this->Target->GetName() << ".";
    cmSystemTools::Error(e.str());
    return;
  }

  std::string fw_path = std::move(fwItems->first);
  std::string fw = std::move(fwItems->second);
  std::string full_fw = cmStrCat(fw, ".framework/", fw);

  if (!fw_path.empty()) {
    full_fw = cmStrCat(fw_path, '/', full_fw);
    // Add the directory portion to the framework search path.
    this->AddFrameworkPath(fw_path);
  }

  // add runtime information
  this->AddLibraryRuntimeInfo(full_fw);

  if (entry.Feature == DEFAULT) {
    // ensure FRAMEWORK feature is loaded
    this->AddLibraryFeature("FRAMEWORK");
  }

  if (this->GlobalGenerator->IsXcode()) {
    // Add framework path - it will be handled by Xcode after it's added to
    // "Link Binary With Libraries" build phase
    this->Items.emplace_back(item, ItemIsPath::Yes, nullptr,
                             this->FindLibraryFeature(entry.Feature == DEFAULT
                                                        ? "FRAMEWORK"
                                                        : entry.Feature));
  } else {
    this->Items.emplace_back(fw, ItemIsPath::Yes, nullptr,
                             this->FindLibraryFeature(entry.Feature == DEFAULT
                                                        ? "FRAMEWORK"
                                                        : entry.Feature));
  }
}

void cmComputeLinkInformation::DropDirectoryItem(BT<std::string> const& item)
{
  // A full path to a directory was found as a link item.  Warn the
  // user.
  this->CMakeInstance->IssueMessage(
    MessageType::WARNING,
    cmStrCat("Target \"", this->Target->GetName(),
             "\" requests linking to directory \"", item.Value,
             "\".  Targets may link only to libraries.  CMake is dropping "
             "the item."),
    item.Backtrace);
}

void cmComputeLinkInformation::ComputeFrameworkInfo()
{
  // Avoid adding implicit framework paths.
  std::vector<std::string> implicitDirVec;

  // Get platform-wide implicit directories.
  this->Makefile->GetDefExpandList(
    "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", implicitDirVec);

  // Get language-specific implicit directories.
  std::string implicitDirVar = cmStrCat(
    "CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES");
  this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);

  this->FrameworkPathsEmitted.insert(implicitDirVec.begin(),
                                     implicitDirVec.end());
}

void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
{
  if (this->FrameworkPathsEmitted.insert(p).second) {
    this->FrameworkPaths.push_back(p);
  }
}

bool cmComputeLinkInformation::CheckSharedLibNoSOName(LinkEntry const& entry)
{
  // This platform will use the path to a library as its soname if the
  // library is given via path and was not built with an soname.  If
  // this is a shared library that might be the case.
  std::string file = cmSystemTools::GetFilenameName(entry.Item.Value);
  if (this->ExtractSharedLibraryName.find(file)) {
    // If we can guess the soname fairly reliably then assume the
    // library has one.  Otherwise assume the library has no builtin
    // soname.
    std::string soname;
    if (!cmSystemTools::GuessLibrarySOName(entry.Item.Value, soname)) {
      this->AddSharedLibNoSOName(entry);
      return true;
    }
  }
  return false;
}

void cmComputeLinkInformation::AddSharedLibNoSOName(LinkEntry const& entry)
{
  // We have a full path to a shared library with no soname.  We need
  // to ask the linker to locate the item because otherwise the path
  // we give to it will be embedded in the target linked.  Then at
  // runtime the dynamic linker will search for the library using the
  // path instead of just the name.
  LinkEntry fileEntry{ entry };
  fileEntry.Item = cmSystemTools::GetFilenameName(entry.Item.Value);
  this->AddUserItem(fileEntry, false);

  // Make sure the link directory ordering will find the library.
  this->OrderLinkerSearchPath->AddLinkLibrary(entry.Item.Value);
}

void cmComputeLinkInformation::HandleBadFullItem(LinkEntry const& entry,
                                                 std::string const& file)
{
  std::string const& item = entry.Item.Value;
  // Do not depend on things that do not exist.
  auto i = std::find(this->Depends.begin(), this->Depends.end(), item);
  if (i != this->Depends.end()) {
    this->Depends.erase(i);
  }

  // Tell the linker to search for the item and provide the proper
  // path for it.  Do not contribute to any CMP0003 warning (do not
  // put in OldLinkDirItems or OldUserFlagItems).
  LinkEntry fileEntry{ entry };
  fileEntry.Item = file;
  this->AddUserItem(fileEntry, false);
  this->OrderLinkerSearchPath->AddLinkLibrary(item);

  // Produce any needed message.
  switch (this->Target->GetPolicyStatusCMP0008()) {
    case cmPolicies::WARN: {
      // Print the warning at most once for this item.
      std::string wid = cmStrCat("CMP0008-WARNING-GIVEN-", item);
      if (!this->CMakeInstance->GetState()->GetGlobalPropertyAsBool(wid)) {
        this->CMakeInstance->GetState()->SetGlobalProperty(wid, "1");
        std::ostringstream w;
        /* clang-format off */
        w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0008) << "\n"
          << "Target \"" << this->Target->GetName() << "\" links to item\n"
          << "  " << item << "\n"
          << "which is a full-path but not a valid library file name.";
        /* clang-format on */
        this->CMakeInstance->IssueMessage(MessageType::AUTHOR_WARNING, w.str(),
                                          this->Target->GetBacktrace());
      }
    }
      CM_FALLTHROUGH;
    case cmPolicies::OLD: // NOLINT(bugprone-branch-clone)
      // OLD behavior does not warn.
      break;
    case cmPolicies::NEW:
      // NEW behavior will not get here.
      break;
    case cmPolicies::REQUIRED_IF_USED:
    case cmPolicies::REQUIRED_ALWAYS: {
      std::ostringstream e;
      /* clang-format off */
      e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0008) << "\n"
          << "Target \"" << this->Target->GetName() << "\" links to item\n"
          << "  " << item << "\n"
          << "which is a full-path but not a valid library file name.";
      /* clang-format on */
      this->CMakeInstance->IssueMessage(MessageType::FATAL_ERROR, e.str(),
                                        this->Target->GetBacktrace());
    } break;
  }
}

bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
{
  // Support broken projects if necessary.
  if (this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
      !this->OldLinkDirMode) {
    return true;
  }

  // Enforce policy constraints.
  switch (this->Target->GetPolicyStatusCMP0003()) {
    case cmPolicies::WARN:
      if (!this->CMakeInstance->GetState()->GetGlobalPropertyAsBool(
            "CMP0003-WARNING-GIVEN")) {
        this->CMakeInstance->GetState()->SetGlobalProperty(
          "CMP0003-WARNING-GIVEN", "1");
        std::ostringstream w;
        this->PrintLinkPolicyDiagnosis(w);
        this->CMakeInstance->IssueMessage(MessageType::AUTHOR_WARNING, w.str(),
                                          this->Target->GetBacktrace());
      }
      CM_FALLTHROUGH;
    case cmPolicies::OLD:
      // OLD behavior is to add the paths containing libraries with
      // known full paths as link directories.
      break;
    case cmPolicies::NEW:
      // Should never happen due to assignment of OldLinkDirMode
      return true;
    case cmPolicies::REQUIRED_IF_USED:
    case cmPolicies::REQUIRED_ALWAYS: {
      std::ostringstream e;
      e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0003) << "\n";
      this->PrintLinkPolicyDiagnosis(e);
      this->CMakeInstance->IssueMessage(MessageType::FATAL_ERROR, e.str(),
                                        this->Target->GetBacktrace());
      return false;
    }
  }

  // Add the link directories for full path items.
  for (std::string const& i : this->OldLinkDirItems) {
    this->OrderLinkerSearchPath->AddLinkLibrary(i);
  }
  return true;
}

void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
{
  // Tell the user what to do.
  /* clang-format off */
  os << "Policy CMP0003 should be set before this line.  "
     << "Add code such as\n"
     << "  if(COMMAND cmake_policy)\n"
     << "    cmake_policy(SET CMP0003 NEW)\n"
     << "  endif(COMMAND cmake_policy)\n"
     << "as early as possible but after the most recent call to "
     << "cmake_minimum_required or cmake_policy(VERSION).  ";
  /* clang-format on */

  // List the items that might need the old-style paths.
  os << "This warning appears because target \"" << this->Target->GetName()
     << "\" "
     << "links to some libraries for which the linker must search:\n";
  {
    // Format the list of unknown items to be as short as possible while
    // still fitting in the allowed width (a true solution would be the
    // bin packing problem if we were allowed to change the order).
    std::string::size_type max_size = 76;
    std::string line;
    const char* sep = "  ";
    for (std::string const& i : this->OldUserFlagItems) {
      // If the addition of another item will exceed the limit then
      // output the current line and reset it.  Note that the separator
      // is either " " or ", " which is always 2 characters.
      if (!line.empty() && (line.size() + i.size() + 2) > max_size) {
        os << line << "\n";
        sep = "  ";
        line.clear();
      }
      line += sep;
      line += i;
      // Convert to the other separator.
      sep = ", ";
    }
    if (!line.empty()) {
      os << line << "\n";
    }
  }

  // List the paths old behavior is adding.
  os << "and other libraries with known full path:\n";
  std::set<std::string> emitted;
  for (std::string const& i : this->OldLinkDirItems) {
    if (emitted.insert(cmSystemTools::GetFilenamePath(i)).second) {
      os << "  " << i << "\n";
    }
  }

  // Explain.
  os << "CMake is adding directories in the second list to the linker "
     << "search path in case they are needed to find libraries from the "
     << "first list (for backwards compatibility with CMake 2.4).  "
     << "Set policy CMP0003 to OLD or NEW to enable or disable this "
     << "behavior explicitly.  "
     << "Run \"cmake --help-policy CMP0003\" for more information.";
}

void cmComputeLinkInformation::LoadImplicitLinkInfo()
{
  std::vector<std::string> implicitDirVec;

  // Get platform-wide implicit directories.
  this->Makefile->GetDefExpandList("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES",
                                   implicitDirVec);

  // Append library architecture to all implicit platform directories
  // and add them to the set
  if (cmValue libraryArch =
        this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE")) {
    for (std::string const& i : implicitDirVec) {
      this->ImplicitLinkDirs.insert(i + "/" + *libraryArch);
    }
  }

  // Get language-specific implicit directories.
  std::string implicitDirVar =
    cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_DIRECTORIES");
  this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);

  // Store implicit link directories.
  this->ImplicitLinkDirs.insert(implicitDirVec.begin(), implicitDirVec.end());

  // Get language-specific implicit libraries.
  std::vector<std::string> implicitLibVec;
  std::string implicitLibVar =
    cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_LIBRARIES");
  this->Makefile->GetDefExpandList(implicitLibVar, implicitLibVec);

  // Store implicit link libraries.
  for (std::string const& item : implicitLibVec) {
    // Items starting in '-' but not '-l' are flags, not libraries,
    // and should not be filtered by this implicit list.
    if (item[0] != '-' || item[1] == 'l') {
      this->ImplicitLinkLibs.insert(item);
    }
  }

  // Get platform specific rpath link directories
  this->Makefile->GetDefExpandList("CMAKE_PLATFORM_RUNTIME_PATH",
                                   this->RuntimeLinkDirs);
}

std::vector<std::string> const&
cmComputeLinkInformation::GetRuntimeSearchPath() const
{
  return this->OrderRuntimeSearchPath->GetOrderedDirectories();
}

void cmComputeLinkInformation::AddLibraryRuntimeInfo(
  std::string const& fullPath, cmGeneratorTarget const* target)
{
  // Ignore targets on Apple where install_name is not @rpath.
  // The dependenty library can be found with other means such as
  // @loader_path or full paths.
  if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
    if (!target->HasMacOSXRpathInstallNameDir(this->Config)) {
      return;
    }
  }

  // Libraries with unknown type must be handled using just the file
  // on disk.
  if (target->GetType() == cmStateEnums::UNKNOWN_LIBRARY) {
    this->AddLibraryRuntimeInfo(fullPath);
    return;
  }

  // Skip targets that are not shared libraries (modules cannot be linked).
  if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
    return;
  }

  // Try to get the soname of the library.  Only files with this name
  // could possibly conflict.
  std::string soName = target->GetSOName(this->Config);
  const char* soname = soName.empty() ? nullptr : soName.c_str();

  // Include this library in the runtime path ordering.
  this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
  if (this->LinkWithRuntimePath) {
    this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
  }
}

void cmComputeLinkInformation::AddLibraryRuntimeInfo(
  std::string const& fullPath)
{
  // Get the name of the library from the file name.
  bool is_shared_library = false;
  std::string file = cmSystemTools::GetFilenameName(fullPath);

  if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
    // Check that @rpath is part of the install name.
    // If it isn't, return.
    std::string soname;
    if (!cmSystemTools::GuessLibraryInstallName(fullPath, soname)) {
      return;
    }

    if (soname.find("@rpath") == std::string::npos) {
      return;
    }
  }

  is_shared_library = this->ExtractSharedLibraryName.find(file);

  if (!is_shared_library) {
    // On some platforms (AIX) a shared library may look static.
    if (this->ArchivesMayBeShared) {
      if (this->ExtractStaticLibraryName.find(file)) {
        // This is the name of a shared library or archive.
        is_shared_library = true;
      }
    }
  }

  // It could be an Apple framework
  if (!is_shared_library) {
    if (fullPath.find(".framework") != std::string::npos) {
      static cmsys::RegularExpression splitFramework(
        "^(.*)/(.*).framework/(.*)$");
      if (splitFramework.find(fullPath) &&
          (std::string::npos !=
           splitFramework.match(3).find(splitFramework.match(2)))) {
        is_shared_library = true;
      }
    }
  }

  if (!is_shared_library) {
    return;
  }

  // Include this library in the runtime path ordering.
  this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
  if (this->LinkWithRuntimePath) {
    this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
  }
}

static void cmCLI_ExpandListUnique(std::string const& str,
                                   std::vector<std::string>& out,
                                   std::set<std::string>& emitted)
{
  std::vector<std::string> tmp = cmExpandedList(str);
  for (std::string const& i : tmp) {
    if (emitted.insert(i).second) {
      out.push_back(i);
    }
  }
}

void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
                                        bool for_install) const
{
  // Select whether to generate runtime search directories.
  bool outputRuntime =
    !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();

  // Select whether to generate an rpath for the install tree or the
  // build tree.
  bool linking_for_install =
    (for_install ||
     this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
  bool use_install_rpath =
    (outputRuntime && this->Target->HaveInstallTreeRPATH(this->Config) &&
     linking_for_install);
  bool use_build_rpath =
    (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
     !linking_for_install);
  bool use_link_rpath = outputRuntime && linking_for_install &&
    !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
    this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");

  // Select whether to use $ORIGIN in RPATHs for artifacts in the build tree.
  std::string const& originToken = this->Makefile->GetSafeDefinition(
    "CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN");
  std::string targetOutputDir = this->Target->GetDirectory(this->Config);
  bool use_relative_build_rpath =
    this->Target->GetPropertyAsBool("BUILD_RPATH_USE_ORIGIN") &&
    !originToken.empty() && !targetOutputDir.empty();

  // Construct the RPATH.
  std::set<std::string> emitted;
  if (use_install_rpath) {
    std::string install_rpath;
    this->Target->GetInstallRPATH(this->Config, install_rpath);
    cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
  }
  if (use_build_rpath) {
    // Add directories explicitly specified by user
    std::string build_rpath;
    if (this->Target->GetBuildRPATH(this->Config, build_rpath)) {
      // This will not resolve entries to use $ORIGIN, the user is expected
      // to do that if necessary.
      cmCLI_ExpandListUnique(build_rpath, runtimeDirs, emitted);
    }
  }
  if (use_build_rpath || use_link_rpath) {
    std::string rootPath;
    if (cmValue sysrootLink =
          this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK")) {
      rootPath = *sysrootLink;
    } else {
      rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
    }
    cmValue stagePath = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
    std::string const& installPrefix =
      this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
    cmSystemTools::ConvertToUnixSlashes(rootPath);
    std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
    std::string const& topBinaryDir =
      this->CMakeInstance->GetHomeOutputDirectory();
    for (std::string const& ri : rdirs) {
      // Put this directory in the rpath if using build-tree rpath
      // support or if using the link path as an rpath.
      if (use_build_rpath) {
        std::string d = ri;
        if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
          d.erase(0, rootPath.size());
        } else if (cmNonempty(stagePath) && cmHasPrefix(d, *stagePath)) {
          d.erase(0, (*stagePath).size());
          d = cmStrCat(installPrefix, '/', d);
          cmSystemTools::ConvertToUnixSlashes(d);
        } else if (use_relative_build_rpath) {
          // If expansion of the $ORIGIN token is supported and permitted per
          // policy, use relative paths in the RPATH.
          if (cmSystemTools::ComparePath(d, topBinaryDir) ||
              cmSystemTools::IsSubDirectory(d, topBinaryDir)) {
            d = cmSystemTools::RelativePath(targetOutputDir, d);
            if (!d.empty()) {
              d = cmStrCat(originToken, "/", d);
            } else {
              d = originToken;
            }
          }
        }
        if (emitted.insert(d).second) {
          runtimeDirs.push_back(std::move(d));
        }
      } else if (use_link_rpath) {
        // Do not add any path inside the source or build tree.
        std::string const& topSourceDir =
          this->CMakeInstance->GetHomeDirectory();
        if (!cmSystemTools::ComparePath(ri, topSourceDir) &&
            !cmSystemTools::ComparePath(ri, topBinaryDir) &&
            !cmSystemTools::IsSubDirectory(ri, topSourceDir) &&
            !cmSystemTools::IsSubDirectory(ri, topBinaryDir)) {
          std::string d = ri;
          if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
            d.erase(0, rootPath.size());
          } else if (cmNonempty(stagePath) && cmHasPrefix(d, *stagePath)) {
            d.erase(0, (*stagePath).size());
            d = cmStrCat(installPrefix, '/', d);
            cmSystemTools::ConvertToUnixSlashes(d);
          }
          if (emitted.insert(d).second) {
            runtimeDirs.push_back(std::move(d));
          }
        }
      }
    }
  }

  // Add runtime paths required by the languages to always be
  // present.  This is done even when skipping rpath support.
  {
    cmGeneratorTarget::LinkClosure const* lc =
      this->Target->GetLinkClosure(this->Config);
    for (std::string const& li : lc->Languages) {
      std::string useVar =
        "CMAKE_" + li + "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
      if (this->Makefile->IsOn(useVar)) {
        std::string dirVar = "CMAKE_" + li + "_IMPLICIT_LINK_DIRECTORIES";
        if (cmValue dirs = this->Makefile->GetDefinition(dirVar)) {
          cmCLI_ExpandListUnique(*dirs, runtimeDirs, emitted);
        }
      }
    }
  }

  // Add runtime paths required by the platform to always be
  // present.  This is done even when skipping rpath support.
  cmCLI_ExpandListUnique(this->RuntimeAlways, runtimeDirs, emitted);
}

std::string cmComputeLinkInformation::GetRPathString(bool for_install) const
{
  // Get the directories to use.
  std::vector<std::string> runtimeDirs;
  this->GetRPath(runtimeDirs, for_install);

  // Concatenate the paths.
  std::string rpath = cmJoin(runtimeDirs, this->GetRuntimeSep());

  // If the rpath will be replaced at install time, prepare space.
  if (!for_install && this->RuntimeUseChrpath) {
    if (!rpath.empty()) {
      // Add one trailing separator so the linker does not re-use the
      // rpath .dynstr entry for a symbol name that happens to match
      // the end of the rpath string.
      rpath += this->GetRuntimeSep();
    }

    // Make sure it is long enough to hold the replacement value.
    std::string::size_type minLength = this->GetChrpathString().length();
    while (rpath.length() < minLength) {
      rpath += this->GetRuntimeSep();
    }
  }

  return rpath;
}

std::string cmComputeLinkInformation::GetChrpathString() const
{
  if (!this->RuntimeUseChrpath) {
    return "";
  }

  return this->GetRPathString(true);
}
