/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmComputeLinkInformation.h"

#include "cmComputeLinkDepends.h"
#include "cmOrderDirectories.h"

#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmState.h"
#include "cmOutputConverter.h"
#include "cmMakefile.h"
#include "cmTarget.h"
#include "cmGeneratorTarget.h"
#include "cmake.h"
#include "cmAlgorithms.h"

#include <ctype.h>

//#define CM_COMPUTE_LINK_INFO_DEBUG

/*
Notes about linking on various platforms:

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

Linux, FreeBSD, Mac OS X, IRIX, 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.
  this->Target = target;
  this->Makefile = this->Target->Target->GetMakefile();
  this->GlobalGenerator =
      this->Target->GetLocalGenerator()->GetGlobalGenerator();
  this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();

  // Check whether to recognize OpenBSD-style library versioned names.
  this->OpenBSD = this->Makefile->GetState()
            ->GetGlobalPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");

  // The configuration being linked.
  this->Config = config;

  // Allocate internals.
  this->OrderLinkerSearchPath =
    new cmOrderDirectories(this->GlobalGenerator, target,
                           "linker search path");
  this->OrderRuntimeSearchPath =
    new cmOrderDirectories(this->GlobalGenerator, target,
                           "runtime search path");
  this->OrderDependentRPath = 0;

  // 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->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;

  // Check whether we should skip dependencies on shared library files.
  this->LinkDependsNoShared =
    this->Target->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 = 0;
  if(!this->UseImportLibrary &&
     this->Target->Target->GetType() == cmTarget::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->Target->GetType() != cmTarget::STATIC_LIBRARY)
    {
    const char* tType =
      ((this->Target->Target->GetType() == cmTarget::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.
  this->OrderLinkerSearchPath
    ->AddUserDirectories(this->Target->Target->GetLinkDirectories());
  this->OrderRuntimeSearchPath
    ->AddUserDirectories(this->Target->Target->GetLinkDirectories());

  // 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->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
  if(this->OldLinkDirMode)
    {
    // Construct a mask to not bother with this behavior for link
    // directories already specified by the user.
    std::vector<std::string> const& dirs =
        this->Target->Target->GetLinkDirectories();
    this->OldLinkDirMask.insert(dirs.begin(), dirs.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()
{
  return this->Items;
}

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

//----------------------------------------------------------------------------
std::string cmComputeLinkInformation::GetRPathLinkString()
{
  // 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.
  return cmJoin(this->OrderDependentRPath->GetOrderedDirectories(), ":");
}

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

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

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

//----------------------------------------------------------------------------
bool cmComputeLinkInformation::Compute()
{
  // Skip targets that do not link.
  if(!(this->Target->GetType() == cmTarget::EXECUTABLE ||
       this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
       this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
       this->Target->GetType() == cmTarget::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().c_str());
    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::EntryVector::const_iterator
        lei = linkEntries.begin();
      lei != linkEntries.end(); ++lei)
    {
    if(lei->IsSharedDep)
      {
      this->AddSharedDepItem(lei->Item, lei->Target);
      }
    else
      {
      this->AddItem(lei->Item, lei->Target);
      }
    }

  // Restore the target link type so the correct system runtime
  // libraries are found.
  const char* lss =
      this->Target->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<cmTarget const*> const& wrongItems = cld.GetOldWrongConfigItems();
    for(std::set<cmTarget const*>::const_iterator i = wrongItems.begin();
        i != wrongItems.end(); ++i)
      {
      cmTarget const* tgt = *i;
      cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
      bool implib =
        (this->UseImportLibrary &&
         (tgt->GetType() == cmTarget::SHARED_LIBRARY));
      std::string lib = gtgt->GetFullPath(this->Config , implib, true);
      this->OldLinkDirItems.push_back(lib);
      }
    }

  // 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;
    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."
      ;
    this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
                                      this->Target->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::vector<std::string>::const_iterator li = lc->Languages.begin();
      li != lc->Languages.end(); ++li)
    {
    // 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::vector<std::string>::const_iterator i = libsVec.begin();
        i != libsVec.end(); ++i)
      {
      if(this->ImplicitLinkLibs.find(*i) == this->ImplicitLinkLibs.end())
        {
        this->AddItem(*i, 0);
        }
      }
    }

  // 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,
                                       cmTarget 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())
    {
    cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
    // 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;

      std::string exe = gtgt->GetFullPath(config, this->UseImportLibrary,
                                         true);
      linkItem += exe;
      this->Items.push_back(Item(linkItem, true, tgt));
      this->Depends.push_back(exe);
      }
    else if(tgt->GetType() == cmTarget::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.push_back(Item(std::string(), true, tgt));
      }
    else
      {
      // Decide whether to use an import library.
      bool implib =
        (this->UseImportLibrary &&
         (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));

      // Pass the full path to the target file.
      std::string lib = gtgt->GetFullPath(config, implib, true);
      if(!this->LinkDependsNoShared ||
         tgt->GetType() != cmTarget::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.c_str()))
      {
      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,
                                                cmTarget const* 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() != cmTarget::SHARED_LIBRARY)
      {
      return;
      }
    }
  else
    {
    // Skip items that are not full paths.  We will not be able to
    // reliably specify them.
    if(!cmSystemTools::FileIsFullPath(item.c_str()))
      {
      return;
      }

    // Get the name of the library from the file name.
    std::string file = cmSystemTools::GetFilenameName(item);
    if(!this->ExtractSharedLibraryName.find(file.c_str()))
      {
      // 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;
    }

  cmGeneratorTarget *gtgt = 0;

  // 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)
    {
    gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);

    lib = gtgt->GetFullPath(this->Config, this->UseImportLibrary);
    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 = 0;
  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(gtgt)
      {
      std::string soName = gtgt->GetSOName(this->Config);
      const char* soname = soName.empty()? 0 : 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 = 0;
  const char* shared_link_type_flag = 0;
  const char* target_type_str = 0;
  switch(this->Target->GetType())
    {
    case cmTarget::EXECUTABLE:     target_type_str = "EXE"; break;
    case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
    case cmTarget::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->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::vector<std::string>::iterator i = linkSuffixVec.begin();
        i != linkSuffixVec.end(); ++i)
      {
      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::vector<std::string>::iterator i = sharedSuffixVec.begin();
        i != sharedSuffixVec.end(); ++i)
      {
      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::set<std::string>::iterator p = this->LinkPrefixes.begin();
      p != this->LinkPrefixes.end(); ++p)
    {
    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.push_back(e);
      }
    if(type == LinkShared)
      {
      this->SharedLinkExtensions.push_back(e);
      }
    this->LinkExtensions.push_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::vector<std::string>::const_iterator i = exts.begin();
      i != exts.end(); ++i)
    {
    // 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 version component.
  if(this->OpenBSD)
    {
    libext += "(\\.[0-9]+\\.[0-9]+)?";
    }
  else if(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.push_back(Item(this->StaticLinkTypeFlag, false));
          break;
        case LinkShared:
          this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
          break;
        default:
          break;
        }
      }
    }
}

//----------------------------------------------------------------------------
void cmComputeLinkInformation::AddTargetItem(std::string const& item,
                                             cmTarget 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() != cmTarget::STATIC_LIBRARY)
    {
    this->SetCurrentLinkType(LinkShared);
    }

  // Keep track of shared library targets linked.
  if(target->GetType() == cmTarget::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.push_back(Item(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.push_back(Item(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->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
     (generator.find("Visual Studio") != generator.npos ||
      generator.find("Xcode") != generator.npos))
    {
    std::string file = cmSystemTools::GetFilenameName(item);
    if(!this->ExtractAnyLibraryName.find(file.c_str()))
      {
      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.push_back(Item(this->LibLinkFileFlag, false));
    }

  // Now add the full path to the library.
  this->Items.push_back(Item(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->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.push_back(Item(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.push_back(Item(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.c_str()))
    {
    std::ostringstream e;
    e << "Could not parse framework path \"" << item << "\" "
      << "linked by target " << this->Target->GetName() << ".";
    cmSystemTools::Error(e.str().c_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.push_back(Item("-framework", false));
  cmOutputConverter converter(this->Makefile->GetStateSnapshot());
  fw = converter.EscapeForShell(fw);
  this->Items.push_back(Item(fw, false));
}

//----------------------------------------------------------------------------
void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
{
  if(this->Makefile->IsOn("APPLE")
     && cmSystemTools::IsPathToFramework(item.c_str()))
    {
    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().c_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->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;
        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.";
        this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
                                        this->Target->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;
      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.";
      this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
                                        this->Target->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->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(cmake::AUTHOR_WARNING, w.str(),
                                        this->Target->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(cmake::FATAL_ERROR, e.str(),
                                        this->Target->Target->GetBacktrace());
      return false;
      }
    }

  // Add the link directories for full path items.
  for(std::vector<std::string>::const_iterator
        i = this->OldLinkDirItems.begin();
      i != this->OldLinkDirItems.end(); ++i)
    {
    this->OrderLinkerSearchPath->AddLinkLibrary(*i);
    }
  return true;
}

//----------------------------------------------------------------------------
void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
{
  // Tell the user what to do.
  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).  ";

  // 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::vector<std::string>::const_iterator
        i = this->OldUserFlagItems.begin();
      i != this->OldUserFlagItems.end(); ++i)
    {
    // 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 = "";
      }
    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::vector<std::string>::const_iterator
        i = this->OldLinkDirItems.begin();
      i != this->OldLinkDirItems.end(); ++i)
    {
    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::vector<std::string>::const_iterator i = implicitDirVec.begin();
         i != implicitDirVec.end(); ++i)
      {
      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::vector<std::string>::const_iterator i = implicitLibVec.begin();
      i != implicitLibVec.end(); ++i)
    {
    // Items starting in '-' but not '-l' are flags, not libraries,
    // and should not be filtered by this implicit list.
    std::string const& item = *i;
    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()
{
  return this->OrderRuntimeSearchPath->GetOrderedDirectories();
}

//----------------------------------------------------------------------------
void
cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
                                                cmTarget 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() == cmTarget::UNKNOWN_LIBRARY)
    {
    this->AddLibraryRuntimeInfo(fullPath);
    return;
    }

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

  // Try to get the soname of the library.  Only files with this name
  // could possibly conflict.
  cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
  std::string soName = gtgt->GetSOName(this->Config);
  const char* soname = soName.empty()? 0 : 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.c_str()))
        {
        // 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::vector<std::string>::iterator i = tmp.begin(); i != tmp.end(); ++i)
    {
    if(emitted.insert(*i).second)
      {
      out.push_back(*i);
      }
    }
}

//----------------------------------------------------------------------------
void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
                                        bool for_install)
{
  // 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->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
  bool use_install_rpath =
    (outputRuntime && this->Target->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->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");

  // Construct the RPATH.
  std::set<std::string> emitted;
  if(use_install_rpath)
    {
    const char* install_rpath =
        this->Target->Target->GetProperty("INSTALL_RPATH");
    cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
    }
  if(use_build_rpath || use_link_rpath)
    {
    std::string rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
    const char *stagePath
                  = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
    const char *installPrefix
                  = this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
    cmSystemTools::ConvertToUnixSlashes(rootPath);
    std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
    for(std::vector<std::string>::const_iterator ri = rdirs.begin();
        ri != rdirs.end(); ++ri)
      {
      // 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);
          }
        if(emitted.insert(d).second)
          {
          runtimeDirs.push_back(d);
          }
        }
      else if(use_link_rpath)
        {
        // Do not add any path inside the source or build tree.
        const char* topSourceDir = this->Makefile->GetHomeDirectory();
        const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
        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(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::vector<std::string>::const_iterator li = lc->Languages.begin();
      li != lc->Languages.end(); ++li)
    {
    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)
{
  // 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()
{
  if(!this->RuntimeUseChrpath)
    {
    return "";
    }

  return this->GetRPathString(true);
}
