/* 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 "cmAlgorithms.h"
#include "cmComputeLinkDepends.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOrderDirectories.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"

#include <algorithm>
#include <ctype.h>
#include <sstream>
#include <string.h>
#include <utility>

//#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 = new cmOrderDirectories(
    this->GlobalGenerator, target, "linker search path");
  this->OrderRuntimeSearchPath = new cmOrderDirectories(
    this->GlobalGenerator, target, "runtime search path");
  this->OrderDependentRPath = nullptr;

  // 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 use an import library for linking a target.
  this->UseImportLibrary =
    this->Makefile->IsDefinitionSet("CMAKE_IMPORT_LIBRARY_SUFFIX");

  // 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.
  this->LoaderFlag = nullptr;
  if (!this->UseImportLibrary &&
      this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) {
    std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
    loader_flag_var += this->LinkLanguage;
    loader_flag_var += "_FLAG";
    this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var);
  }

  // Get options needed to link libraries.
  this->LibLinkFlag =
    this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
  this->LibLinkFileFlag =
    this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
  this->LibLinkSuffix =
    this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");

  // 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 = "CMAKE_";
    rtVar += tType;
    rtVar += "_RUNTIME_";
    rtVar += this->LinkLanguage;
    rtVar += "_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 = "CMAKE_";
    rlVar += tType;
    rlVar += "_RPATH_LINK_";
    rlVar += this->LinkLanguage;
    rlVar += "_FLAG";
    this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar);
  }

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

  // 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 = new 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()
{
  delete this->OrderLinkerSearchPath;
  delete this->OrderRuntimeSearchPath;
  delete this->OrderDependentRPath;
}

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

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

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;
}

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);
  cld.SetOldLinkDirMode(this->OldLinkDirMode);
  cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();

  // Add the link line items.
  for (cmComputeLinkDepends::LinkEntry const& linkEntry : linkEntries) {
    if (linkEntry.IsSharedDep) {
      this->AddSharedDepItem(linkEntry.Item, linkEntry.Target);
    } else {
      this->AddItem(linkEntry.Item, linkEntry.Target);
    }
  }

  // Restore the target link type so the correct system runtime
  // libraries are found.
  const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
  if (cmSystemTools::IsOn(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) {
      bool implib = (this->UseImportLibrary &&
                     (tgt->GetType() == cmStateEnums::SHARED_LIBRARY));
      cmStateEnums::ArtifactType artifact = implib
        ? 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;
}

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

void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
{
  // Add libraries for this language that are not implied by the
  // linker language.
  std::string libVar = "CMAKE_";
  libVar += lang;
  libVar += "_IMPLICIT_LINK_LIBRARIES";
  if (const char* libs = this->Makefile->GetDefinition(libVar)) {
    std::vector<std::string> libsVec;
    cmSystemTools::ExpandListArgument(libs, libsVec);
    for (std::string const& i : libsVec) {
      if (this->ImplicitLinkLibs.find(i) == this->ImplicitLinkLibs.end()) {
        this->AddItem(i, nullptr);
      }
    }
  }

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

void cmComputeLinkInformation::AddItem(std::string const& item,
                                       cmGeneratorTarget const* tgt)
{
  // Compute the proper name to use to link this library.
  const std::string& config = this->Config;
  bool impexe = (tgt && tgt->IsExecutableWithExports());
  if (impexe && !this->UseImportLibrary && !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.
      std::string linkItem;
      linkItem = this->LoaderFlag;
      cmStateEnums::ArtifactType artifact = this->UseImportLibrary
        ? cmStateEnums::ImportLibraryArtifact
        : cmStateEnums::RuntimeBinaryArtifact;

      std::string exe = tgt->GetFullPath(config, artifact, true);
      linkItem += exe;
      this->Items.emplace_back(linkItem, true, tgt);
      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(), false, 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(libName, nullptr);
      }
    } 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.
      bool implib =
        (this->UseImportLibrary &&
         (impexe || tgt->GetType() == cmStateEnums::SHARED_LIBRARY));
      cmStateEnums::ArtifactType artifact = implib
        ? cmStateEnums::ImportLibraryArtifact
        : cmStateEnums::RuntimeBinaryArtifact;

      // Pass the full path to the target file.
      std::string lib = tgt->GetFullPath(config, artifact, true);
      if (!this->LinkDependsNoShared ||
          tgt->GetType() != cmStateEnums::SHARED_LIBRARY) {
        this->Depends.push_back(lib);
      }

      this->AddTargetItem(lib, tgt);
      this->AddLibraryRuntimeInfo(lib, tgt);
    }
  } else {
    // This is not a CMake target.  Use the name given.
    if (cmSystemTools::FileIsFullPath(item)) {
      if (cmSystemTools::FileIsDirectory(item)) {
        // This is a directory.
        this->AddDirectoryItem(item);
      } else {
        // Use the full path given to the library file.
        this->Depends.push_back(item);
        this->AddFullItem(item);
        this->AddLibraryRuntimeInfo(item);
      }
    } else {
      // This is a library or option specified by the user.
      this->AddUserItem(item, true);
    }
  }
}

void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
                                                const cmGeneratorTarget* 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)) {
      return;
    }

    // Get the name of the library from the file name.
    std::string file = cmSystemTools::GetFilenameName(item);
    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(item, tgt);
    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 = this->UseImportLibrary
      ? cmStateEnums::ImportLibraryArtifact
      : cmStateEnums::RuntimeBinaryArtifact;
    lib = tgt->GetFullPath(this->Config, artifact);
    this->AddLibraryRuntimeInfo(lib, tgt);
  } else {
    lib = item;
    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;
  } else if (this->SharedDependencyMode == SharedDepModeDir) {
    // Add the item to the separate dependent library search path.
    order = this->OrderDependentRPath;
  }
  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::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.
  const char* static_link_type_flag = nullptr;
  const char* 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 = "CMAKE_";
    static_link_type_flag_var += target_type_str;
    static_link_type_flag_var += "_LINK_STATIC_";
    static_link_type_flag_var += this->LinkLanguage;
    static_link_type_flag_var += "_FLAGS";
    static_link_type_flag =
      this->Makefile->GetDefinition(static_link_type_flag_var);

    std::string shared_link_type_flag_var = "CMAKE_";
    shared_link_type_flag_var += target_type_str;
    shared_link_type_flag_var += "_LINK_DYNAMIC_";
    shared_link_type_flag_var += this->LinkLanguage;
    shared_link_type_flag_var += "_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 (static_link_type_flag && *static_link_type_flag &&
      shared_link_type_flag && *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?).
  const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
  this->StartLinkType = cmSystemTools::IsOn(lss) ? LinkStatic : LinkShared;
  this->CurrentLinkType = this->StartLinkType;
}

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

  // Import library names should be matched and treated as shared
  // libraries for the purposes of linking.
  this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
                         LinkShared);
  this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
                         LinkStatic);
  this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
                         LinkShared);
  this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
                         LinkUnknown);
  if (const char* linkSuffixes =
        mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
    std::vector<std::string> linkSuffixVec;
    cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
    for (std::string const& i : linkSuffixVec) {
      this->AddLinkExtension(i.c_str(), LinkUnknown);
    }
  }
  if (const char* sharedSuffixes =
        mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
    std::vector<std::string> sharedSuffixVec;
    cmSystemTools::ExpandListArgument(sharedSuffixes, sharedSuffixVec);
    for (std::string const& i : sharedSuffixVec) {
      this->AddLinkExtension(i.c_str(), 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 = reg;
  reg_any += libext;
#ifdef CM_COMPUTE_LINK_INFO_DEBUG
  fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
#endif
  this->ExtractAnyLibraryName.compile(reg_any.c_str());

  // Create a regex to match static library names.
  if (!this->StaticLinkExtensions.empty()) {
    std::string reg_static = reg;
    reg_static +=
      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.c_str());
  }

  // 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.c_str());
  }
}

void cmComputeLinkInformation::AddLinkPrefix(const char* p)
{
  if (p && *p) {
    this->LinkPrefixes.insert(p);
  }
}

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

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.c_str());
#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(const char* str)
{
  std::string ret;
  const char* s = str;
  while (*s) {
    if (*s == '.') {
      ret += *s;
    } else {
      ret += "[";
      ret += static_cast<char>(tolower(*s));
      ret += static_cast<char>(toupper(*s));
      ret += "]";
    }
    s++;
  }
  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, false);
          break;
        case LinkShared:
          this->Items.emplace_back(this->SharedLinkTypeFlag, false);
          break;
        default:
          break;
      }
    }
  }
}

void cmComputeLinkInformation::AddTargetItem(std::string const& item,
                                             cmGeneratorTarget const* target)
{
  // 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.
  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(item);
    return;
  }

  // If this platform wants a flag before the full path, add it.
  if (!this->LibLinkFileFlag.empty()) {
    this->Items.emplace_back(this->LibLinkFileFlag, false);
  }

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

  // Now add the full path to the library.
  this->Items.emplace_back(item, true, target);
}

void cmComputeLinkInformation::AddFullItem(std::string const& item)
{
  // Check for the implicit link directory special case.
  if (this->CheckImplicitDirItem(item)) {
    return;
  }

  // Check for case of shared library with no builtin soname.
  if (this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item)) {
    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);
    if (!this->ExtractAnyLibraryName.find(file)) {
      this->HandleBadFullItem(item, 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);
    if (this->ExtractSharedLibraryName.find(name)) {
      this->SetCurrentLinkType(LinkShared);
    } else if (!this->ExtractStaticLibraryName.find(item)) {
      // 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 &&
      this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
        this->OldLinkDirMask.end()) {
    this->OldLinkDirItems.push_back(item);
  }

  // If this platform wants a flag before the full path, add it.
  if (!this->LibLinkFileFlag.empty()) {
    this->Items.emplace_back(this->LibLinkFileFlag, false);
  }

  // Now add the full path to the library.
  this->Items.emplace_back(item, true);
}

bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& 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);
  if (this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end()) {
    // 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);
  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;
        if (!this->CMakeInstance->GetPropertyAsBool(wid)) {
          this->CMakeInstance->SetProperty(wid, "1");
          this->CMP0060WarnItems.insert(item);
        }
      }
    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.
  this->AddUserItem(file, false);

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

  return true;
}

void cmComputeLinkInformation::AddUserItem(std::string const& item,
                                           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

  // Pass flags through untouched.
  if (item[0] == '-' || item[0] == '$' || item[0] == '`') {
    // 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 (item.find("-l") == 0 || item.find("-Wl,-l") == 0) {
      // This is a linker option provided by the user.
      this->OldUserFlagItems.push_back(item);
    }

    // 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, false);
    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)) {
// 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)) {
// 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)) {
// 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);
    }

    // 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;
  }

  // Create an option to ask the linker to search for the library.
  std::string out = this->LibLinkFlag;
  out += lib;
  out += this->LibLinkSuffix;
  this->Items.emplace_back(out, false);

  // 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(std::string const& item)
{
  // Try to separate the framework name and path.
  if (!this->SplitFramework.find(item)) {
    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 = this->SplitFramework.match(1);
  std::string fw = this->SplitFramework.match(2);
  std::string full_fw = fw_path;
  full_fw += "/";
  full_fw += fw;
  full_fw += ".framework";
  full_fw += "/";
  full_fw += fw;

  // Add the directory portion to the framework search path.
  this->AddFrameworkPath(fw_path);

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

  // Add the item using the -framework option.
  this->Items.emplace_back("-framework", false);
  cmOutputConverter converter(this->Makefile->GetStateSnapshot());
  fw = converter.EscapeForShell(fw);
  this->Items.emplace_back(fw, false);
}

void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
{
  if (this->Makefile->IsOn("APPLE") &&
      cmSystemTools::IsPathToFramework(item)) {
    this->AddFrameworkItem(item);
  } else {
    this->DropDirectoryItem(item);
  }
}

void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
{
  // A full path to a directory was found as a link item.  Warn the
  // user.
  std::ostringstream e;
  e << "WARNING: Target \"" << this->Target->GetName()
    << "\" requests linking to directory \"" << item << "\".  "
    << "Targets may link only to libraries.  "
    << "CMake is dropping the item.";
  cmSystemTools::Message(e.str());
}

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

  // Get platform-wide implicit directories.
  if (const char* implicitLinks = this->Makefile->GetDefinition(
        "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES")) {
    cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
  }

  // Get language-specific implicit directories.
  std::string implicitDirVar = "CMAKE_";
  implicitDirVar += this->LinkLanguage;
  implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
  if (const char* implicitDirs =
        this->Makefile->GetDefinition(implicitDirVar)) {
    cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
  }

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

  // Regular expression to extract a framework path and name.
  this->SplitFramework.compile("(.*)/(.*)\\.framework$");
}

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

bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
{
  // 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(item);
  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(item, soname)) {
      this->AddSharedLibNoSOName(item);
      return true;
    }
  }
  return false;
}

void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
{
  // 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.
  std::string file = cmSystemTools::GetFilenameName(item);
  this->AddUserItem(file, false);

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

void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
                                                 std::string const& file)
{
  // Do not depend on things that do not exist.
  std::vector<std::string>::iterator 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).
  this->AddUserItem(file, 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 = "CMP0008-WARNING-GIVEN-";
      wid += 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());
      }
    }
    case cmPolicies::OLD:
      // 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());
      }
    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.
  if (const char* implicitLinks = (this->Makefile->GetDefinition(
        "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES"))) {
    cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
  }

  // Append library architecture to all implicit platform directories
  // and add them to the set
  if (const char* 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 = "CMAKE_";
  implicitDirVar += this->LinkLanguage;
  implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
  if (const char* implicitDirs =
        this->Makefile->GetDefinition(implicitDirVar)) {
    cmSystemTools::ExpandListArgument(implicitDirs, 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 = "CMAKE_";
  implicitLibVar += this->LinkLanguage;
  implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
  if (const char* implicitLibs =
        this->Makefile->GetDefinition(implicitLibVar)) {
    cmSystemTools::ExpandListArgument(implicitLibs, 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
  if (const char* rpathDirs =
        (this->Makefile->GetDefinition("CMAKE_PLATFORM_RUNTIME_PATH"))) {
    cmSystemTools::ExpandListArgument(rpathDirs, 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(const char* str,
                                   std::vector<std::string>& out,
                                   std::set<std::string>& emitted)
{
  std::vector<std::string> tmp;
  cmSystemTools::ExpandListArgument(str, tmp);
  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() &&
     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) {
    const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
    cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
  }
  if (use_build_rpath) {
    // Add directories explicitly specified by user
    if (const char* build_rpath = this->Target->GetProperty("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 (const char* sysrootLink =
          this->Makefile->GetDefinition("CMAKE_SYSROOT_LINK")) {
      rootPath = sysrootLink;
    } else {
      rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
    }
    const char* 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() && d.find(rootPath) == 0) {
          d = d.substr(rootPath.size());
        } else if (stagePath && *stagePath && d.find(stagePath) == 0) {
          std::string suffix = d.substr(strlen(stagePath));
          d = installPrefix;
          d += "/";
          d += suffix;
          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 = 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() && d.find(rootPath) == 0) {
            d = d.substr(rootPath.size());
          } else if (stagePath && *stagePath && d.find(stagePath) == 0) {
            std::string suffix = d.substr(strlen(stagePath));
            d = installPrefix;
            d += "/";
            d += suffix;
            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 (const char* 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.c_str(), 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);
}
