packaging: Initial packaging
[platform/upstream/cmake.git] / Source / cmComputeLinkInformation.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmComputeLinkInformation.h"
13
14 #include "cmComputeLinkDepends.h"
15 #include "cmOrderDirectories.h"
16
17 #include "cmGlobalGenerator.h"
18 #include "cmLocalGenerator.h"
19 #include "cmMakefile.h"
20 #include "cmTarget.h"
21 #include "cmake.h"
22
23 #include <ctype.h>
24
25 //#define CM_COMPUTE_LINK_INFO_DEBUG
26
27 /*
28 Notes about linking on various platforms:
29
30 ------------------------------------------------------------------------------
31
32 Linux, FreeBSD, Mac OS X, IRIX, Sun, Windows:
33
34 Linking to libraries using the full path works fine.
35
36 ------------------------------------------------------------------------------
37
38 On AIX, more work is needed.
39
40   The "-bnoipath" option is needed.  From "man ld":
41
42     Note: If you specify a shared object, or an archive file
43     containing a shared object, with an absolute or relative path
44     name, instead of with the -lName flag, the path name is
45     included in the import file ID string in the loader section of
46     the output file. You can override this behavior with the
47     -bnoipath option.
48
49       noipath
50
51         For shared objects listed on the command-line, rather than
52         specified with the -l flag, use a null path component when
53         listing the shared object in the loader section of the
54         output file. A null path component is always used for
55         shared objects specified with the -l flag. This option
56         does not affect the specification of a path component by
57         using a line beginning with #! in an import file. The
58         default is the ipath option.
59
60   This prevents the full path specified on the compile line from being
61   compiled directly into the binary.
62
63   By default the linker places -L paths in the embedded runtime path.
64   In order to implement CMake's RPATH interface correctly, we need the
65   -blibpath:Path option.  From "man ld":
66
67       libpath:Path
68
69         Uses Path as the library path when writing the loader section
70         of the output file. Path is neither checked for validity nor
71         used when searching for libraries specified by the -l flag.
72         Path overrides any library paths generated when the -L flag is
73         used.
74
75         If you do not specify any -L flags, or if you specify the
76         nolibpath option, the default library path information is
77         written in the loader section of the output file. The default
78         library path information is the value of the LIBPATH
79         environment variable if it is defined, and /usr/lib:/lib,
80         otherwise.
81
82   We can pass -Wl,-blibpath:/usr/lib:/lib always to avoid the -L stuff
83   and not break when the user sets LIBPATH.  Then if we want to add an
84   rpath we insert it into the option before /usr/lib.
85
86 ------------------------------------------------------------------------------
87
88 On HP-UX, more work is needed.  There are differences between
89 versions.
90
91 ld: 92453-07 linker linker ld B.10.33 990520
92
93   Linking with a full path works okay for static and shared libraries.
94   The linker seems to always put the full path to where the library
95   was found in the binary whether using a full path or -lfoo syntax.
96   Transitive link dependencies work just fine due to the full paths.
97
98   It has the "-l:libfoo.sl" option.  The +nodefaultrpath is accepted
99   but not documented and does not seem to do anything.  There is no
100   +forceload option.
101
102 ld: 92453-07 linker ld HP Itanium(R) B.12.41  IPF/IPF
103
104   Linking with a full path works okay for static libraries.
105
106   Linking with a full path works okay for shared libraries.  However
107   dependent (transitive) libraries of those linked directly must be
108   either found with an rpath stored in the direct dependencies or
109   found in -L paths as if they were specified with "-l:libfoo.sl"
110   (really "-l:<soname>").  The search matches that of the dynamic
111   loader but only with -L paths.  In other words, if we have an
112   executable that links to shared library bar which links to shared
113   library foo, the link line for the exe must contain
114
115     /dir/with/bar/libbar.sl -L/dir/with/foo
116
117   It does not matter whether the exe wants to link to foo directly or
118   whether /dir/with/foo/libfoo.sl is listed.  The -L path must still
119   be present.  It should match the runtime path computed for the
120   executable taking all directly and transitively linked libraries
121   into account.
122
123   The "+nodefaultrpath" option should be used to avoid getting -L
124   paths in the rpath unless we add our own rpath with +b.  This means
125   that skip-build-rpath should use this option.
126
127   See documentation in "man ld", "man dld.so", and
128   http://docs.hp.com/en/B2355-90968/creatingandusinglibraries.htm
129
130     +[no]defaultrpath
131       +defaultrpath is the default.  Include any paths that are
132       specified with -L in the embedded path, unless you specify the
133       +b option.  If you use +b, only the path list specified by +b is
134       in the embedded path.
135
136       The +nodefaultrpath option removes all library paths that were
137       specified with the -L option from the embedded path.  The linker
138       searches the library paths specified by the -L option at link
139       time.  At run time, the only library paths searched are those
140       specified by the environment variables LD_LIBRARY_PATH and
141       SHLIB_PATH, library paths specified by the +b linker option, and
142       finally the default library paths.
143
144     +rpathfirst
145       This option will cause the paths specified in RPATH (embedded
146       path) to be used before the paths specified in LD_LIBRARY_PATH
147       or SHLIB_PATH, in searching for shared libraries.  This changes
148       the default search order of LD_LIBRARY_PATH, SHLIB_PATH, and
149       RPATH (embedded path).
150
151 ------------------------------------------------------------------------------
152 Notes about dependent (transitive) shared libraries:
153
154 On non-Windows systems shared libraries may have transitive
155 dependencies.  In order to support LINK_INTERFACE_LIBRARIES we must
156 support linking to a shared library without listing all the libraries
157 to which it links.  Some linkers want to be able to find the
158 transitive dependencies (dependent libraries) of shared libraries
159 listed on the command line.
160
161   - On Windows, DLLs are not directly linked, and the import libraries
162     have no transitive dependencies.
163
164   - On Mac OS X 10.5 and above transitive dependencies are not needed.
165
166   - On Mac OS X 10.4 and below we need to actually list the dependencies.
167     Otherwise when using -isysroot for universal binaries it cannot
168     find the dependent libraries.  Listing them on the command line
169     tells the linker where to find them, but unfortunately also links
170     the library.
171
172   - On HP-UX, the linker wants to find the transitive dependencies of
173     shared libraries in the -L paths even if the dependent libraries
174     are given on the link line.
175
176   - On AIX the transitive dependencies are not needed.
177
178   - On SGI, the linker wants to find the transitive dependencies of
179     shared libraries in the -L paths if they are not given on the link
180     line.  Transitive linking can be disabled using the options
181
182       -no_transitive_link -Wl,-no_transitive_link
183
184     which disable it.  Both options must be given when invoking the
185     linker through the compiler.
186
187   - On Sun, the linker wants to find the transitive dependencies of
188     shared libraries in the -L paths if they are not given on the link
189     line.
190
191   - On Linux, FreeBSD, and QNX:
192
193     The linker wants to find the transitive dependencies of shared
194     libraries in the "-rpath-link" paths option if they have not been
195     given on the link line.  The option is like rpath but just for
196     link time:
197
198       -Wl,-rpath-link,"/path1:/path2"
199
200 For -rpath-link, we need a separate runtime path ordering pass
201 including just the dependent libraries that are not linked.
202
203 For -L paths on non-HP, we can do the same thing as with rpath-link
204 but put the results in -L paths.  The paths should be listed at the
205 end to avoid conflicting with user search paths (?).
206
207 For -L paths on HP, we should do a runtime path ordering pass with
208 all libraries, both linked and non-linked.  Even dependent
209 libraries that are also linked need to be listed in -L paths.
210
211 In our implementation we add all dependent libraries to the runtime
212 path computation.  Then the auto-generated RPATH will find everything.
213
214 ------------------------------------------------------------------------------
215 Notes about shared libraries with not builtin soname:
216
217 Some UNIX shared libraries may be created with no builtin soname.  On
218 some platforms such libraries cannot be linked using the path to their
219 location because the linker will copy the path into the field used to
220 find the library at runtime.
221
222   Apple:    ../libfoo.dylib  ==>  libfoo.dylib  # ok, uses install_name
223   SGI:      ../libfoo.so     ==>  libfoo.so     # ok
224   AIX:      ../libfoo.so     ==>  libfoo.so     # ok
225   Linux:    ../libfoo.so     ==>  ../libfoo.so  # bad
226   HP-UX:    ../libfoo.so     ==>  ../libfoo.so  # bad
227   Sun:      ../libfoo.so     ==>  ../libfoo.so  # bad
228   FreeBSD:  ../libfoo.so     ==>  ../libfoo.so  # bad
229
230 In order to link these libraries we need to use the old-style split
231 into -L.. and -lfoo options.  This should be fairly safe because most
232 problems with -lfoo options were related to selecting shared libraries
233 instead of static but in this case we want the shared lib.  Link
234 directory ordering needs to be done to make sure these shared
235 libraries are found first.  There should be very few restrictions
236 because this need be done only for shared libraries without soname-s.
237
238 */
239
240 //----------------------------------------------------------------------------
241 cmComputeLinkInformation
242 ::cmComputeLinkInformation(cmTarget* target, const char* config,
243                            cmTarget *headTarget)
244 {
245   // Store context information.
246   this->Target = target;
247   this->HeadTarget = headTarget;
248   this->Makefile = this->Target->GetMakefile();
249   this->LocalGenerator = this->Makefile->GetLocalGenerator();
250   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
251   this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
252
253   // Check whether to recognize OpenBSD-style library versioned names.
254   this->OpenBSD = this->Makefile->GetCMakeInstance()
255     ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
256
257   // The configuration being linked.
258   this->Config = config;
259
260   // Allocate internals.
261   this->OrderLinkerSearchPath =
262     new cmOrderDirectories(this->GlobalGenerator, target,
263                            "linker search path");
264   this->OrderRuntimeSearchPath =
265     new cmOrderDirectories(this->GlobalGenerator, target,
266                            "runtime search path");
267   this->OrderDependentRPath = 0;
268
269   // Get the language used for linking this target.
270   this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
271   if(!this->LinkLanguage)
272     {
273     // The Compute method will do nothing, so skip the rest of the
274     // initialization.
275     return;
276     }
277
278   // Check whether we should use an import library for linking a target.
279   this->UseImportLibrary =
280     this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
281
282   // Check whether we should skip dependencies on shared library files.
283   this->LinkDependsNoShared =
284     this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
285
286   // On platforms without import libraries there may be a special flag
287   // to use when creating a plugin (module) that obtains symbols from
288   // the program that will load it.
289   this->LoaderFlag = 0;
290   if(!this->UseImportLibrary &&
291      this->Target->GetType() == cmTarget::MODULE_LIBRARY)
292     {
293     std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
294     loader_flag_var += this->LinkLanguage;
295     loader_flag_var += "_FLAG";
296     this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var.c_str());
297     }
298
299   // Get options needed to link libraries.
300   this->LibLinkFlag =
301     this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
302   this->LibLinkFileFlag =
303     this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
304   this->LibLinkSuffix =
305     this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
306
307   // Get options needed to specify RPATHs.
308   this->RuntimeUseChrpath = false;
309   if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
310     {
311     const char* tType =
312       ((this->Target->GetType() == cmTarget::EXECUTABLE)?
313        "EXECUTABLE" : "SHARED_LIBRARY");
314     std::string rtVar = "CMAKE_";
315     rtVar += tType;
316     rtVar += "_RUNTIME_";
317     rtVar += this->LinkLanguage;
318     rtVar += "_FLAG";
319     std::string rtSepVar = rtVar + "_SEP";
320     this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar.c_str());
321     this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar.c_str());
322     this->RuntimeAlways =
323       (this->Makefile->
324        GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
325     this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);
326
327     // Get options needed to help find dependent libraries.
328     std::string rlVar = "CMAKE_";
329     rlVar += tType;
330     rlVar += "_RPATH_LINK_";
331     rlVar += this->LinkLanguage;
332     rlVar += "_FLAG";
333     this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar.c_str());
334     }
335
336   // Check if we need to include the runtime search path at link time.
337   {
338   std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
339   var += this->LinkLanguage;
340   var += "_WITH_RUNTIME_PATH";
341   this->LinkWithRuntimePath = this->Makefile->IsOn(var.c_str());
342   }
343
344   // Check the platform policy for missing soname case.
345   this->NoSONameUsesPath =
346     this->Makefile->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
347
348   // Get link type information.
349   this->ComputeLinkTypeInfo();
350
351   // Setup the link item parser.
352   this->ComputeItemParserInfo();
353
354   // Setup framework support.
355   this->ComputeFrameworkInfo();
356
357   // Choose a mode for dealing with shared library dependencies.
358   this->SharedDependencyMode = SharedDepModeNone;
359   if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES"))
360     {
361     this->SharedDependencyMode = SharedDepModeLink;
362     }
363   else if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS"))
364     {
365     this->SharedDependencyMode = SharedDepModeLibDir;
366     }
367   else if(!this->RPathLinkFlag.empty())
368     {
369     this->SharedDependencyMode = SharedDepModeDir;
370     this->OrderDependentRPath =
371       new cmOrderDirectories(this->GlobalGenerator, target,
372                              "dependent library path");
373     }
374
375   // Add the search path entries requested by the user to path ordering.
376   this->OrderLinkerSearchPath
377     ->AddUserDirectories(this->Target->GetLinkDirectories());
378   this->OrderRuntimeSearchPath
379     ->AddUserDirectories(this->Target->GetLinkDirectories());
380
381   // Set up the implicit link directories.
382   this->LoadImplicitLinkInfo();
383   this->OrderLinkerSearchPath
384     ->SetImplicitDirectories(this->ImplicitLinkDirs);
385   this->OrderRuntimeSearchPath
386     ->SetImplicitDirectories(this->ImplicitLinkDirs);
387   if(this->OrderDependentRPath)
388     {
389     this->OrderDependentRPath
390       ->SetImplicitDirectories(this->ImplicitLinkDirs);
391     this->OrderDependentRPath
392       ->AddLanguageDirectories(this->RuntimeLinkDirs);
393     }
394
395   // Decide whether to enable compatible library search path mode.
396   // There exists code that effectively does
397   //
398   //    /path/to/libA.so -lB
399   //
400   // where -lB is meant to link to /path/to/libB.so.  This is broken
401   // because it specified -lB without specifying a link directory (-L)
402   // in which to search for B.  This worked in CMake 2.4 and below
403   // because -L/path/to would be added by the -L/-l split for A.  In
404   // order to support such projects we need to add the directories
405   // containing libraries linked with a full path to the -L path.
406   this->OldLinkDirMode =
407     this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
408   if(this->OldLinkDirMode)
409     {
410     // Construct a mask to not bother with this behavior for link
411     // directories already specified by the user.
412     std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
413     for(std::vector<std::string>::const_iterator di = dirs.begin();
414         di != dirs.end(); ++di)
415       {
416       this->OldLinkDirMask.insert(*di);
417       }
418     }
419 }
420
421 //----------------------------------------------------------------------------
422 cmComputeLinkInformation::~cmComputeLinkInformation()
423 {
424   delete this->OrderLinkerSearchPath;
425   delete this->OrderRuntimeSearchPath;
426   delete this->OrderDependentRPath;
427 }
428
429 //----------------------------------------------------------------------------
430 cmComputeLinkInformation::ItemVector const&
431 cmComputeLinkInformation::GetItems()
432 {
433   return this->Items;
434 }
435
436 //----------------------------------------------------------------------------
437 std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
438 {
439   return this->OrderLinkerSearchPath->GetOrderedDirectories();
440 }
441
442 //----------------------------------------------------------------------------
443 std::string cmComputeLinkInformation::GetRPathLinkString()
444 {
445   // If there is no separate linker runtime search flag (-rpath-link)
446   // there is no reason to compute a string.
447   if(!this->OrderDependentRPath)
448     {
449     return "";
450     }
451
452   // Construct the linker runtime search path.
453   std::string rpath_link;
454   const char* sep = "";
455   std::vector<std::string> const& dirs =
456     this->OrderDependentRPath->GetOrderedDirectories();
457   for(std::vector<std::string>::const_iterator di = dirs.begin();
458       di != dirs.end(); ++di)
459     {
460     rpath_link += sep;
461     sep = ":";
462     rpath_link += *di;
463     }
464   return rpath_link;
465 }
466
467 //----------------------------------------------------------------------------
468 std::vector<std::string> const& cmComputeLinkInformation::GetDepends()
469 {
470   return this->Depends;
471 }
472
473 //----------------------------------------------------------------------------
474 std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
475 {
476   return this->FrameworkPaths;
477 }
478
479 //----------------------------------------------------------------------------
480 std::set<cmTarget*> const&
481 cmComputeLinkInformation::GetSharedLibrariesLinked()
482 {
483   return this->SharedLibrariesLinked;
484 }
485
486 //----------------------------------------------------------------------------
487 bool cmComputeLinkInformation::Compute()
488 {
489   // Skip targets that do not link.
490   if(!(this->Target->GetType() == cmTarget::EXECUTABLE ||
491        this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
492        this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
493        this->Target->GetType() == cmTarget::STATIC_LIBRARY))
494     {
495     return false;
496     }
497
498   // We require a link language for the target.
499   if(!this->LinkLanguage)
500     {
501     cmSystemTools::
502       Error("CMake can not determine linker language for target: ",
503             this->Target->GetName());
504     return false;
505     }
506
507   // Compute the ordered link line items.
508   cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
509   cld.SetOldLinkDirMode(this->OldLinkDirMode);
510   cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
511
512   // Add the link line items.
513   for(cmComputeLinkDepends::EntryVector::const_iterator
514         lei = linkEntries.begin();
515       lei != linkEntries.end(); ++lei)
516     {
517     if(lei->IsSharedDep)
518       {
519       this->AddSharedDepItem(lei->Item, lei->Target);
520       }
521     else
522       {
523       this->AddItem(lei->Item, lei->Target);
524       }
525     }
526
527   // Restore the target link type so the correct system runtime
528   // libraries are found.
529   const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
530   if(cmSystemTools::IsOn(lss))
531     {
532     this->SetCurrentLinkType(LinkStatic);
533     }
534   else
535     {
536     this->SetCurrentLinkType(this->StartLinkType);
537     }
538
539   // Finish listing compatibility paths.
540   if(this->OldLinkDirMode)
541     {
542     // For CMake 2.4 bug-compatibility we need to consider the output
543     // directories of targets linked in another configuration as link
544     // directories.
545     std::set<cmTarget*> const& wrongItems = cld.GetOldWrongConfigItems();
546     for(std::set<cmTarget*>::const_iterator i = wrongItems.begin();
547         i != wrongItems.end(); ++i)
548       {
549       cmTarget* tgt = *i;
550       bool implib =
551         (this->UseImportLibrary &&
552          (tgt->GetType() == cmTarget::SHARED_LIBRARY));
553       std::string lib = tgt->GetFullPath(this->Config , implib, true);
554       this->OldLinkDirItems.push_back(lib);
555       }
556     }
557
558   // Finish setting up linker search directories.
559   if(!this->FinishLinkerSearchDirectories())
560     {
561     return false;
562     }
563
564   // Add implicit language runtime libraries and directories.
565   this->AddImplicitLinkInfo();
566
567   return true;
568 }
569
570 //----------------------------------------------------------------------------
571 void cmComputeLinkInformation::AddImplicitLinkInfo()
572 {
573   // The link closure lists all languages whose implicit info is needed.
574   cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
575                                                           this->HeadTarget);
576   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
577       li != lc->Languages.end(); ++li)
578     {
579     // Skip those of the linker language.  They are implicit.
580     if(*li != this->LinkLanguage)
581       {
582       this->AddImplicitLinkInfo(*li);
583       }
584     }
585 }
586
587 //----------------------------------------------------------------------------
588 void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
589 {
590   // Add libraries for this language that are not implied by the
591   // linker language.
592   std::string libVar = "CMAKE_";
593   libVar += lang;
594   libVar += "_IMPLICIT_LINK_LIBRARIES";
595   if(const char* libs = this->Makefile->GetDefinition(libVar.c_str()))
596     {
597     std::vector<std::string> libsVec;
598     cmSystemTools::ExpandListArgument(libs, libsVec);
599     for(std::vector<std::string>::const_iterator i = libsVec.begin();
600         i != libsVec.end(); ++i)
601       {
602       if(this->ImplicitLinkLibs.find(*i) == this->ImplicitLinkLibs.end())
603         {
604         this->AddItem(i->c_str(), 0);
605         }
606       }
607     }
608
609   // Add linker search paths for this language that are not
610   // implied by the linker language.
611   std::string dirVar = "CMAKE_";
612   dirVar += lang;
613   dirVar += "_IMPLICIT_LINK_DIRECTORIES";
614   if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
615     {
616     std::vector<std::string> dirsVec;
617     cmSystemTools::ExpandListArgument(dirs, dirsVec);
618     this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
619     }
620 }
621
622 //----------------------------------------------------------------------------
623 void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
624 {
625   // Compute the proper name to use to link this library.
626   const char* config = this->Config;
627   bool impexe = (tgt && tgt->IsExecutableWithExports());
628   if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
629     {
630     // Skip linking to executables on platforms with no import
631     // libraries or loader flags.
632     return;
633     }
634
635   if(tgt && tgt->IsLinkable())
636     {
637     // This is a CMake target.  Ask the target for its real name.
638     if(impexe && this->LoaderFlag)
639       {
640       // This link item is an executable that may provide symbols
641       // used by this target.  A special flag is needed on this
642       // platform.  Add it now.
643       std::string linkItem;
644       linkItem = this->LoaderFlag;
645       std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
646                                          true);
647       linkItem += exe;
648       this->Items.push_back(Item(linkItem, true, tgt));
649       this->Depends.push_back(exe);
650       }
651     else
652       {
653       // Decide whether to use an import library.
654       bool implib =
655         (this->UseImportLibrary &&
656          (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
657
658       // Pass the full path to the target file.
659       std::string lib = tgt->GetFullPath(config, implib, true);
660       if(!this->LinkDependsNoShared ||
661          tgt->GetType() != cmTarget::SHARED_LIBRARY)
662         {
663         this->Depends.push_back(lib);
664         }
665
666       this->AddTargetItem(lib, tgt);
667       this->AddLibraryRuntimeInfo(lib, tgt);
668       }
669     }
670   else
671     {
672     // This is not a CMake target.  Use the name given.
673     if(cmSystemTools::FileIsFullPath(item.c_str()))
674       {
675       if(cmSystemTools::FileIsDirectory(item.c_str()))
676         {
677         // This is a directory.
678         this->AddDirectoryItem(item);
679         }
680       else
681         {
682         // Use the full path given to the library file.
683         this->Depends.push_back(item);
684         this->AddFullItem(item);
685         this->AddLibraryRuntimeInfo(item);
686         }
687       }
688     else
689       {
690       // This is a library or option specified by the user.
691       this->AddUserItem(item, true);
692       }
693     }
694 }
695
696 //----------------------------------------------------------------------------
697 void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
698                                                 cmTarget* tgt)
699 {
700   // If dropping shared library dependencies, ignore them.
701   if(this->SharedDependencyMode == SharedDepModeNone)
702     {
703     return;
704     }
705
706   // The user may have incorrectly named an item.  Skip items that are
707   // not full paths to shared libraries.
708   if(tgt)
709     {
710     // The target will provide a full path.  Make sure it is a shared
711     // library.
712     if(tgt->GetType() != cmTarget::SHARED_LIBRARY)
713       {
714       return;
715       }
716     }
717   else
718     {
719     // Skip items that are not full paths.  We will not be able to
720     // reliably specify them.
721     if(!cmSystemTools::FileIsFullPath(item.c_str()))
722       {
723       return;
724       }
725
726     // Get the name of the library from the file name.
727     std::string file = cmSystemTools::GetFilenameName(item);
728     if(!this->ExtractSharedLibraryName.find(file.c_str()))
729       {
730       // This is not the name of a shared library.
731       return;
732       }
733     }
734
735   // If in linking mode, just link to the shared library.
736   if(this->SharedDependencyMode == SharedDepModeLink)
737     {
738     this->AddItem(item, tgt);
739     return;
740     }
741
742   // Get a full path to the dependent shared library.
743   // Add it to the runtime path computation so that the target being
744   // linked will be able to find it.
745   std::string lib;
746   if(tgt)
747     {
748     lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
749     this->AddLibraryRuntimeInfo(lib, tgt);
750     }
751   else
752     {
753     lib = item;
754     this->AddLibraryRuntimeInfo(lib);
755     }
756
757   // Check if we need to include the dependent shared library in other
758   // path ordering.
759   cmOrderDirectories* order = 0;
760   if(this->SharedDependencyMode == SharedDepModeLibDir &&
761      !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */)
762     {
763     // Add the item to the linker search path.
764     order = this->OrderLinkerSearchPath;
765     }
766   else if(this->SharedDependencyMode == SharedDepModeDir)
767     {
768     // Add the item to the separate dependent library search path.
769     order = this->OrderDependentRPath;
770     }
771   if(order)
772     {
773     if(tgt)
774       {
775       std::string soName = tgt->GetSOName(this->Config);
776       const char* soname = soName.empty()? 0 : soName.c_str();
777       order->AddRuntimeLibrary(lib, soname);
778       }
779     else
780       {
781       order->AddRuntimeLibrary(lib);
782       }
783     }
784 }
785
786 //----------------------------------------------------------------------------
787 void cmComputeLinkInformation::ComputeLinkTypeInfo()
788 {
789   // Check whether archives may actually be shared libraries.
790   this->ArchivesMayBeShared =
791     this->CMakeInstance->GetPropertyAsBool(
792       "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
793
794   // First assume we cannot do link type stuff.
795   this->LinkTypeEnabled = false;
796
797   // Lookup link type selection flags.
798   const char* static_link_type_flag = 0;
799   const char* shared_link_type_flag = 0;
800   const char* target_type_str = 0;
801   switch(this->Target->GetType())
802     {
803     case cmTarget::EXECUTABLE:     target_type_str = "EXE"; break;
804     case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
805     case cmTarget::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
806     default: break;
807     }
808   if(target_type_str)
809     {
810     std::string static_link_type_flag_var = "CMAKE_";
811     static_link_type_flag_var += target_type_str;
812     static_link_type_flag_var += "_LINK_STATIC_";
813     static_link_type_flag_var += this->LinkLanguage;
814     static_link_type_flag_var += "_FLAGS";
815     static_link_type_flag =
816       this->Makefile->GetDefinition(static_link_type_flag_var.c_str());
817
818     std::string shared_link_type_flag_var = "CMAKE_";
819     shared_link_type_flag_var += target_type_str;
820     shared_link_type_flag_var += "_LINK_DYNAMIC_";
821     shared_link_type_flag_var += this->LinkLanguage;
822     shared_link_type_flag_var += "_FLAGS";
823     shared_link_type_flag =
824       this->Makefile->GetDefinition(shared_link_type_flag_var.c_str());
825     }
826
827   // We can support link type switching only if all needed flags are
828   // known.
829   if(static_link_type_flag && *static_link_type_flag &&
830      shared_link_type_flag && *shared_link_type_flag)
831     {
832     this->LinkTypeEnabled = true;
833     this->StaticLinkTypeFlag = static_link_type_flag;
834     this->SharedLinkTypeFlag = shared_link_type_flag;
835     }
836
837   // Lookup the starting link type from the target (linked statically?).
838   const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
839   this->StartLinkType = cmSystemTools::IsOn(lss)? LinkStatic : LinkShared;
840   this->CurrentLinkType = this->StartLinkType;
841 }
842
843 //----------------------------------------------------------------------------
844 void cmComputeLinkInformation::ComputeItemParserInfo()
845 {
846   // Get possible library name prefixes.
847   cmMakefile* mf = this->Makefile;
848   this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
849   this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
850
851   // Import library names should be matched and treated as shared
852   // libraries for the purposes of linking.
853   this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
854                          LinkShared);
855   this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
856                          LinkStatic);
857   this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
858                          LinkShared);
859   this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
860                          LinkUnknown);
861   if(const char* linkSuffixes =
862      mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
863     {
864     std::vector<std::string> linkSuffixVec;
865     cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
866     for(std::vector<std::string>::iterator i = linkSuffixVec.begin();
867         i != linkSuffixVec.end(); ++i)
868       {
869       this->AddLinkExtension(i->c_str(), LinkUnknown);
870       }
871     }
872   if(const char* sharedSuffixes =
873      mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES"))
874     {
875     std::vector<std::string> sharedSuffixVec;
876     cmSystemTools::ExpandListArgument(sharedSuffixes, sharedSuffixVec);
877     for(std::vector<std::string>::iterator i = sharedSuffixVec.begin();
878         i != sharedSuffixVec.end(); ++i)
879       {
880       this->AddLinkExtension(i->c_str(), LinkShared);
881       }
882     }
883
884   // Compute a regex to match link extensions.
885   std::string libext = this->CreateExtensionRegex(this->LinkExtensions,
886                                                   LinkUnknown);
887
888   // Create regex to remove any library extension.
889   std::string reg("(.*)");
890   reg += libext;
891   this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
892                                                     reg);
893
894   // Create a regex to match a library name.  Match index 1 will be
895   // the prefix if it exists and empty otherwise.  Match index 2 will
896   // be the library name.  Match index 3 will be the library
897   // extension.
898   reg = "^(";
899   for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
900       p != this->LinkPrefixes.end(); ++p)
901     {
902     reg += *p;
903     reg += "|";
904     }
905   reg += ")";
906   reg += "([^/:]*)";
907
908   // Create a regex to match any library name.
909   std::string reg_any = reg;
910   reg_any += libext;
911 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
912   fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
913 #endif
914   this->ExtractAnyLibraryName.compile(reg_any.c_str());
915
916   // Create a regex to match static library names.
917   if(!this->StaticLinkExtensions.empty())
918     {
919     std::string reg_static = reg;
920     reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions,
921                                              LinkStatic);
922 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
923   fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
924 #endif
925     this->ExtractStaticLibraryName.compile(reg_static.c_str());
926     }
927
928   // Create a regex to match shared library names.
929   if(!this->SharedLinkExtensions.empty())
930     {
931     std::string reg_shared = reg;
932     this->SharedRegexString =
933       this->CreateExtensionRegex(this->SharedLinkExtensions, LinkShared);
934     reg_shared += this->SharedRegexString;
935 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
936   fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
937 #endif
938     this->ExtractSharedLibraryName.compile(reg_shared.c_str());
939     }
940 }
941
942 //----------------------------------------------------------------------------
943 void cmComputeLinkInformation::AddLinkPrefix(const char* p)
944 {
945   if(p && *p)
946     {
947     this->LinkPrefixes.insert(p);
948     }
949 }
950
951 //----------------------------------------------------------------------------
952 void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
953 {
954   if(e && *e)
955     {
956     if(type == LinkStatic)
957       {
958       this->StaticLinkExtensions.push_back(e);
959       }
960     if(type == LinkShared)
961       {
962       this->SharedLinkExtensions.push_back(e);
963       }
964     this->LinkExtensions.push_back(e);
965     }
966 }
967
968 //----------------------------------------------------------------------------
969 std::string
970 cmComputeLinkInformation
971 ::CreateExtensionRegex(std::vector<std::string> const& exts, LinkType type)
972 {
973   // Build a list of extension choices.
974   std::string libext = "(";
975   const char* sep = "";
976   for(std::vector<std::string>::const_iterator i = exts.begin();
977       i != exts.end(); ++i)
978     {
979     // Separate this choice from the previous one.
980     libext += sep;
981     sep = "|";
982
983     // Store this extension choice with the "." escaped.
984     libext += "\\";
985 #if defined(_WIN32) && !defined(__CYGWIN__)
986     libext += this->NoCaseExpression(i->c_str());
987 #else
988     libext += *i;
989 #endif
990     }
991
992   // Finish the list.
993   libext += ")";
994
995   // Add an optional OpenBSD version component.
996   if(this->OpenBSD)
997     {
998     libext += "(\\.[0-9]+\\.[0-9]+)?";
999     }
1000   else if(type == LinkShared)
1001     {
1002     libext += "(\\.[0-9]+)?";
1003     }
1004
1005   libext += "$";
1006   return libext;
1007 }
1008
1009 //----------------------------------------------------------------------------
1010 std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
1011 {
1012   std::string ret;
1013   const char* s = str;
1014   while(*s)
1015     {
1016     if(*s == '.')
1017       {
1018       ret += *s;
1019       }
1020     else
1021       {
1022       ret += "[";
1023       ret += static_cast<char>(tolower(*s));
1024       ret += static_cast<char>(toupper(*s));
1025       ret += "]";
1026       }
1027     s++;
1028     }
1029   return ret;
1030 }
1031
1032 //-------------------------------------------------------------------
1033 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
1034 {
1035   // If we are changing the current link type add the flag to tell the
1036   // linker about it.
1037   if(this->CurrentLinkType != lt)
1038     {
1039     this->CurrentLinkType = lt;
1040
1041     if(this->LinkTypeEnabled)
1042       {
1043       switch(this->CurrentLinkType)
1044         {
1045         case LinkStatic:
1046           this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
1047           break;
1048         case LinkShared:
1049           this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
1050           break;
1051         default:
1052           break;
1053         }
1054       }
1055     }
1056 }
1057
1058 //----------------------------------------------------------------------------
1059 void cmComputeLinkInformation::AddTargetItem(std::string const& item,
1060                                              cmTarget* target)
1061 {
1062   // This is called to handle a link item that is a full path to a target.
1063   // If the target is not a static library make sure the link type is
1064   // shared.  This is because dynamic-mode linking can handle both
1065   // shared and static libraries but static-mode can handle only
1066   // static libraries.  If a previous user item changed the link type
1067   // to static we need to make sure it is back to shared.
1068   if(target->GetType() != cmTarget::STATIC_LIBRARY)
1069     {
1070     this->SetCurrentLinkType(LinkShared);
1071     }
1072
1073   // Keep track of shared library targets linked.
1074   if(target->GetType() == cmTarget::SHARED_LIBRARY)
1075     {
1076     this->SharedLibrariesLinked.insert(target);
1077     }
1078
1079   // Handle case of an imported shared library with no soname.
1080   if(this->NoSONameUsesPath &&
1081      target->IsImportedSharedLibWithoutSOName(this->Config))
1082     {
1083     this->AddSharedLibNoSOName(item);
1084     return;
1085     }
1086
1087   // If this platform wants a flag before the full path, add it.
1088   if(!this->LibLinkFileFlag.empty())
1089     {
1090     this->Items.push_back(Item(this->LibLinkFileFlag, false));
1091     }
1092
1093   // For compatibility with CMake 2.4 include the item's directory in
1094   // the linker search path.
1095   if(this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
1096      this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1097      this->OldLinkDirMask.end())
1098     {
1099     this->OldLinkDirItems.push_back(item);
1100     }
1101
1102   // Now add the full path to the library.
1103   this->Items.push_back(Item(item, true, target));
1104 }
1105
1106 //----------------------------------------------------------------------------
1107 void cmComputeLinkInformation::AddFullItem(std::string const& item)
1108 {
1109   // Check for the implicit link directory special case.
1110   if(this->CheckImplicitDirItem(item))
1111     {
1112     return;
1113     }
1114
1115   // Check for case of shared library with no builtin soname.
1116   if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
1117     {
1118     return;
1119     }
1120
1121   // Full path libraries should specify a valid library file name.
1122   // See documentation of CMP0008.
1123   if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
1124      (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
1125       strstr(this->GlobalGenerator->GetName(), "Xcode")))
1126     {
1127     std::string file = cmSystemTools::GetFilenameName(item);
1128     if(!this->ExtractAnyLibraryName.find(file.c_str()))
1129       {
1130       this->HandleBadFullItem(item, file);
1131       return;
1132       }
1133     }
1134
1135   // This is called to handle a link item that is a full path.
1136   // If the target is not a static library make sure the link type is
1137   // shared.  This is because dynamic-mode linking can handle both
1138   // shared and static libraries but static-mode can handle only
1139   // static libraries.  If a previous user item changed the link type
1140   // to static we need to make sure it is back to shared.
1141   if(this->LinkTypeEnabled)
1142     {
1143     std::string name = cmSystemTools::GetFilenameName(item);
1144     if(this->ExtractSharedLibraryName.find(name))
1145       {
1146       this->SetCurrentLinkType(LinkShared);
1147       }
1148     else if(!this->ExtractStaticLibraryName.find(item))
1149       {
1150       // We cannot determine the type.  Assume it is the target's
1151       // default type.
1152       this->SetCurrentLinkType(this->StartLinkType);
1153       }
1154     }
1155
1156   // For compatibility with CMake 2.4 include the item's directory in
1157   // the linker search path.
1158   if(this->OldLinkDirMode &&
1159      this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1160      this->OldLinkDirMask.end())
1161     {
1162     this->OldLinkDirItems.push_back(item);
1163     }
1164
1165   // If this platform wants a flag before the full path, add it.
1166   if(!this->LibLinkFileFlag.empty())
1167     {
1168     this->Items.push_back(Item(this->LibLinkFileFlag, false));
1169     }
1170
1171   // Now add the full path to the library.
1172   this->Items.push_back(Item(item, true));
1173 }
1174
1175 //----------------------------------------------------------------------------
1176 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
1177 {
1178   // We only switch to a pathless item if the link type may be
1179   // enforced.  Fortunately only platforms that support link types
1180   // seem to have magic per-architecture implicit link directories.
1181   if(!this->LinkTypeEnabled)
1182     {
1183     return false;
1184     }
1185
1186   // Check if this item is in an implicit link directory.
1187   std::string dir = cmSystemTools::GetFilenamePath(item);
1188   if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
1189     {
1190     // Only libraries in implicit link directories are converted to
1191     // pathless items.
1192     return false;
1193     }
1194
1195   // Only apply the policy below if the library file is one that can
1196   // be found by the linker.
1197   std::string file = cmSystemTools::GetFilenameName(item);
1198   if(!this->ExtractAnyLibraryName.find(file))
1199     {
1200     return false;
1201     }
1202
1203   // Many system linkers support multiple architectures by
1204   // automatically selecting the implicit linker search path for the
1205   // current architecture.  If the library appears in an implicit link
1206   // directory then just report the file name without the directory
1207   // portion.  This will allow the system linker to locate the proper
1208   // library for the architecture at link time.
1209   this->AddUserItem(file, false);
1210
1211   // Make sure the link directory ordering will find the library.
1212   this->OrderLinkerSearchPath->AddLinkLibrary(item);
1213
1214   return true;
1215 }
1216
1217 //----------------------------------------------------------------------------
1218 void cmComputeLinkInformation::AddUserItem(std::string const& item,
1219                                            bool pathNotKnown)
1220 {
1221   // This is called to handle a link item that does not match a CMake
1222   // target and is not a full path.  We check here if it looks like a
1223   // library file name to automatically request the proper link type
1224   // from the linker.  For example:
1225   //
1226   //   foo       ==>  -lfoo
1227   //   libfoo.a  ==>  -Wl,-Bstatic -lfoo
1228
1229   // Pass flags through untouched.
1230   if(item[0] == '-' || item[0] == '$' || item[0] == '`')
1231     {
1232     // if this is a -l option then we might need to warn about
1233     // CMP0003 so put it in OldUserFlagItems, if it is not a -l
1234     // or -Wl,-l (-framework -pthread), then allow it without a
1235     // CMP0003 as -L will not affect those other linker flags
1236     if(item.find("-l") == 0 ||  item.find("-Wl,-l") == 0)
1237       {
1238       // This is a linker option provided by the user.
1239       this->OldUserFlagItems.push_back(item);
1240       }
1241
1242     // Restore the target link type since this item does not specify
1243     // one.
1244     this->SetCurrentLinkType(this->StartLinkType);
1245
1246     // Use the item verbatim.
1247     this->Items.push_back(Item(item, false));
1248     return;
1249     }
1250
1251   // Parse out the prefix, base, and suffix components of the
1252   // library name.  If the name matches that of a shared or static
1253   // library then set the link type accordingly.
1254   //
1255   // Search for shared library names first because some platforms
1256   // have shared libraries with names that match the static library
1257   // pattern.  For example cygwin and msys use the convention
1258   // libfoo.dll.a for import libraries and libfoo.a for static
1259   // libraries.  On AIX a library with the name libfoo.a can be
1260   // shared!
1261   std::string lib;
1262   if(this->ExtractSharedLibraryName.find(item))
1263     {
1264     // This matches a shared library file name.
1265 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1266     fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
1267             this->ExtractSharedLibraryName.match(1).c_str(),
1268             this->ExtractSharedLibraryName.match(2).c_str(),
1269             this->ExtractSharedLibraryName.match(3).c_str());
1270 #endif
1271     // Set the link type to shared.
1272     this->SetCurrentLinkType(LinkShared);
1273
1274     // Use just the library name so the linker will search.
1275     lib = this->ExtractSharedLibraryName.match(2);
1276     }
1277   else if(this->ExtractStaticLibraryName.find(item))
1278     {
1279     // This matches a static library file name.
1280 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1281     fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
1282             this->ExtractStaticLibraryName.match(1).c_str(),
1283             this->ExtractStaticLibraryName.match(2).c_str(),
1284             this->ExtractStaticLibraryName.match(3).c_str());
1285 #endif
1286     // Set the link type to static.
1287     this->SetCurrentLinkType(LinkStatic);
1288
1289     // Use just the library name so the linker will search.
1290     lib = this->ExtractStaticLibraryName.match(2);
1291     }
1292   else if(this->ExtractAnyLibraryName.find(item))
1293     {
1294     // This matches a library file name.
1295 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1296     fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
1297             this->ExtractAnyLibraryName.match(1).c_str(),
1298             this->ExtractAnyLibraryName.match(2).c_str(),
1299             this->ExtractAnyLibraryName.match(3).c_str());
1300 #endif
1301     // Restore the target link type since this item does not specify
1302     // one.
1303     this->SetCurrentLinkType(this->StartLinkType);
1304
1305     // Use just the library name so the linker will search.
1306     lib = this->ExtractAnyLibraryName.match(2);
1307     }
1308   else
1309     {
1310     // This is a name specified by the user.
1311     if(pathNotKnown)
1312       {
1313       this->OldUserFlagItems.push_back(item);
1314       }
1315
1316     // We must ask the linker to search for a library with this name.
1317     // Restore the target link type since this item does not specify
1318     // one.
1319     this->SetCurrentLinkType(this->StartLinkType);
1320     lib = item;
1321     }
1322
1323   // Create an option to ask the linker to search for the library.
1324   std::string out = this->LibLinkFlag;
1325   out += lib;
1326   out += this->LibLinkSuffix;
1327   this->Items.push_back(Item(out, false));
1328
1329   // Here we could try to find the library the linker will find and
1330   // add a runtime information entry for it.  It would probably not be
1331   // reliable and we want to encourage use of full paths for library
1332   // specification.
1333 }
1334
1335 //----------------------------------------------------------------------------
1336 void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
1337 {
1338   // Try to separate the framework name and path.
1339   if(!this->SplitFramework.find(item.c_str()))
1340     {
1341     cmOStringStream e;
1342     e << "Could not parse framework path \"" << item << "\" "
1343       << "linked by target " << this->Target->GetName() << ".";
1344     cmSystemTools::Error(e.str().c_str());
1345     return;
1346     }
1347
1348   std::string fw_path = this->SplitFramework.match(1);
1349   std::string fw = this->SplitFramework.match(2);
1350   std::string full_fw = fw_path;
1351   full_fw += "/";
1352   full_fw += fw;
1353   full_fw += ".framework";
1354   full_fw += "/";
1355   full_fw += fw;
1356
1357   // Add the directory portion to the framework search path.
1358   this->AddFrameworkPath(fw_path);
1359
1360   // add runtime information
1361   this->AddLibraryRuntimeInfo(full_fw);
1362
1363   // Add the item using the -framework option.
1364   this->Items.push_back(Item("-framework", false));
1365   fw = this->LocalGenerator->EscapeForShell(fw.c_str());
1366   this->Items.push_back(Item(fw, false));
1367 }
1368
1369 //----------------------------------------------------------------------------
1370 void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
1371 {
1372   if(this->Makefile->IsOn("APPLE")
1373      && cmSystemTools::IsPathToFramework(item.c_str()))
1374     {
1375     this->AddFrameworkItem(item);
1376     }
1377   else
1378     {
1379     this->DropDirectoryItem(item);
1380     }
1381 }
1382
1383 //----------------------------------------------------------------------------
1384 void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
1385 {
1386   // A full path to a directory was found as a link item.  Warn the
1387   // user.
1388   cmOStringStream e;
1389   e << "WARNING: Target \"" << this->Target->GetName()
1390     << "\" requests linking to directory \"" << item << "\".  "
1391     << "Targets may link only to libraries.  "
1392     << "CMake is dropping the item.";
1393   cmSystemTools::Message(e.str().c_str());
1394 }
1395
1396 //----------------------------------------------------------------------------
1397 void cmComputeLinkInformation::ComputeFrameworkInfo()
1398 {
1399   // Avoid adding implicit framework paths.
1400   std::vector<std::string> implicitDirVec;
1401
1402   // Get platform-wide implicit directories.
1403   if(const char* implicitLinks = this->Makefile->GetDefinition
1404      ("CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"))
1405     {
1406     cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1407     }
1408
1409   // Get language-specific implicit directories.
1410   std::string implicitDirVar = "CMAKE_";
1411   implicitDirVar += this->LinkLanguage;
1412   implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
1413   if(const char* implicitDirs =
1414      this->Makefile->GetDefinition(implicitDirVar.c_str()))
1415     {
1416     cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1417     }
1418
1419   for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1420       i != implicitDirVec.end(); ++i)
1421     {
1422     this->FrameworkPathsEmmitted.insert(*i);
1423     }
1424
1425   // Regular expression to extract a framework path and name.
1426   this->SplitFramework.compile("(.*)/(.*)\\.framework$");
1427 }
1428
1429 //----------------------------------------------------------------------------
1430 void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
1431 {
1432   if(this->FrameworkPathsEmmitted.insert(p).second)
1433     {
1434     this->FrameworkPaths.push_back(p);
1435     }
1436 }
1437
1438 //----------------------------------------------------------------------------
1439 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
1440 {
1441   // This platform will use the path to a library as its soname if the
1442   // library is given via path and was not built with an soname.  If
1443   // this is a shared library that might be the case.
1444   std::string file = cmSystemTools::GetFilenameName(item);
1445   if(this->ExtractSharedLibraryName.find(file))
1446     {
1447     // If we can guess the soname fairly reliably then assume the
1448     // library has one.  Otherwise assume the library has no builtin
1449     // soname.
1450     std::string soname;
1451     if(!cmSystemTools::GuessLibrarySOName(item, soname))
1452       {
1453       this->AddSharedLibNoSOName(item);
1454       return true;
1455       }
1456     }
1457   return false;
1458 }
1459
1460 //----------------------------------------------------------------------------
1461 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
1462 {
1463   // We have a full path to a shared library with no soname.  We need
1464   // to ask the linker to locate the item because otherwise the path
1465   // we give to it will be embedded in the target linked.  Then at
1466   // runtime the dynamic linker will search for the library using the
1467   // path instead of just the name.
1468   std::string file = cmSystemTools::GetFilenameName(item);
1469   this->AddUserItem(file, false);
1470
1471   // Make sure the link directory ordering will find the library.
1472   this->OrderLinkerSearchPath->AddLinkLibrary(item);
1473 }
1474
1475 //----------------------------------------------------------------------------
1476 void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
1477                                                  std::string const& file)
1478 {
1479   // Do not depend on things that do not exist.
1480   std::vector<std::string>::iterator i =
1481     std::find(this->Depends.begin(), this->Depends.end(), item);
1482   if(i != this->Depends.end())
1483     {
1484     this->Depends.erase(i);
1485     }
1486
1487   // Tell the linker to search for the item and provide the proper
1488   // path for it.  Do not contribute to any CMP0003 warning (do not
1489   // put in OldLinkDirItems or OldUserFlagItems).
1490   this->AddUserItem(file, false);
1491   this->OrderLinkerSearchPath->AddLinkLibrary(item);
1492
1493   // Produce any needed message.
1494   switch(this->Target->GetPolicyStatusCMP0008())
1495     {
1496     case cmPolicies::WARN:
1497       {
1498       // Print the warning at most once for this item.
1499       std::string wid = "CMP0008-WARNING-GIVEN-";
1500       wid += item;
1501       if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
1502         {
1503         this->CMakeInstance->SetProperty(wid.c_str(), "1");
1504         cmOStringStream w;
1505         w << (this->Makefile->GetPolicies()
1506               ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n"
1507           << "Target \"" << this->Target->GetName() << "\" links to item\n"
1508           << "  " << item << "\n"
1509           << "which is a full-path but not a valid library file name.";
1510         this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1511                                           this->Target->GetBacktrace());
1512         }
1513       }
1514     case cmPolicies::OLD:
1515       // OLD behavior does not warn.
1516       break;
1517     case cmPolicies::NEW:
1518       // NEW behavior will not get here.
1519       break;
1520     case cmPolicies::REQUIRED_IF_USED:
1521     case cmPolicies::REQUIRED_ALWAYS:
1522       {
1523       cmOStringStream e;
1524       e << (this->Makefile->GetPolicies()->
1525             GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n"
1526           << "Target \"" << this->Target->GetName() << "\" links to item\n"
1527           << "  " << item << "\n"
1528           << "which is a full-path but not a valid library file name.";
1529       this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1530                                         this->Target->GetBacktrace());
1531       }
1532       break;
1533     }
1534 }
1535
1536 //----------------------------------------------------------------------------
1537 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1538 {
1539   // Support broken projects if necessary.
1540   if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
1541      !this->OldLinkDirMode)
1542     {
1543     return true;
1544     }
1545
1546   // Enforce policy constraints.
1547   switch(this->Target->GetPolicyStatusCMP0003())
1548     {
1549     case cmPolicies::WARN:
1550       if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1551         {
1552         this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
1553         cmOStringStream w;
1554         this->PrintLinkPolicyDiagnosis(w);
1555         this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1556                                           this->Target->GetBacktrace());
1557         }
1558     case cmPolicies::OLD:
1559       // OLD behavior is to add the paths containing libraries with
1560       // known full paths as link directories.
1561       break;
1562     case cmPolicies::NEW:
1563       // Should never happen due to assignment of OldLinkDirMode
1564       return true;
1565     case cmPolicies::REQUIRED_IF_USED:
1566     case cmPolicies::REQUIRED_ALWAYS:
1567       {
1568       cmOStringStream e;
1569       e << (this->Makefile->GetPolicies()->
1570             GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
1571       this->PrintLinkPolicyDiagnosis(e);
1572       this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1573                                         this->Target->GetBacktrace());
1574       return false;
1575       }
1576     }
1577
1578   // Add the link directories for full path items.
1579   for(std::vector<std::string>::const_iterator
1580         i = this->OldLinkDirItems.begin();
1581       i != this->OldLinkDirItems.end(); ++i)
1582     {
1583     this->OrderLinkerSearchPath->AddLinkLibrary(*i);
1584     }
1585   return true;
1586 }
1587
1588 //----------------------------------------------------------------------------
1589 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
1590 {
1591   // Tell the user what to do.
1592   os << "Policy CMP0003 should be set before this line.  "
1593      << "Add code such as\n"
1594      << "  if(COMMAND cmake_policy)\n"
1595      << "    cmake_policy(SET CMP0003 NEW)\n"
1596      << "  endif(COMMAND cmake_policy)\n"
1597      << "as early as possible but after the most recent call to "
1598      << "cmake_minimum_required or cmake_policy(VERSION).  ";
1599
1600   // List the items that might need the old-style paths.
1601   os << "This warning appears because target \""
1602      << this->Target->GetName() << "\" "
1603      << "links to some libraries for which the linker must search:\n";
1604   {
1605   // Format the list of unknown items to be as short as possible while
1606   // still fitting in the allowed width (a true solution would be the
1607   // bin packing problem if we were allowed to change the order).
1608   std::string::size_type max_size = 76;
1609   std::string line;
1610   const char* sep = "  ";
1611   for(std::vector<std::string>::const_iterator
1612         i = this->OldUserFlagItems.begin();
1613       i != this->OldUserFlagItems.end(); ++i)
1614     {
1615     // If the addition of another item will exceed the limit then
1616     // output the current line and reset it.  Note that the separator
1617     // is either " " or ", " which is always 2 characters.
1618     if(!line.empty() && (line.size() + i->size() + 2) > max_size)
1619       {
1620       os << line << "\n";
1621       sep = "  ";
1622       line = "";
1623       }
1624     line += sep;
1625     line += *i;
1626     // Convert to the other separator.
1627     sep = ", ";
1628     }
1629   if(!line.empty())
1630     {
1631     os << line << "\n";
1632     }
1633   }
1634
1635   // List the paths old behavior is adding.
1636   os << "and other libraries with known full path:\n";
1637   std::set<cmStdString> emitted;
1638   for(std::vector<std::string>::const_iterator
1639         i = this->OldLinkDirItems.begin();
1640       i != this->OldLinkDirItems.end(); ++i)
1641     {
1642     if(emitted.insert(cmSystemTools::GetFilenamePath(*i)).second)
1643       {
1644       os << "  " << *i << "\n";
1645       }
1646     }
1647
1648   // Explain.
1649   os << "CMake is adding directories in the second list to the linker "
1650      << "search path in case they are needed to find libraries from the "
1651      << "first list (for backwards compatibility with CMake 2.4).  "
1652      << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1653      << "behavior explicitly.  "
1654      << "Run \"cmake --help-policy CMP0003\" for more information.";
1655 }
1656
1657 //----------------------------------------------------------------------------
1658 void cmComputeLinkInformation::LoadImplicitLinkInfo()
1659 {
1660   std::vector<std::string> implicitDirVec;
1661
1662   // Get platform-wide implicit directories.
1663   if(const char* implicitLinks =
1664      (this->Makefile->GetDefinition
1665       ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
1666     {
1667     cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1668     }
1669
1670   // Append library architecture to all implicit platform directories
1671   // and add them to the set
1672   if(const char* libraryArch =
1673      this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
1674     {
1675     for (std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1676          i != implicitDirVec.end(); ++i)
1677       {
1678       this->ImplicitLinkDirs.insert(*i + "/" + libraryArch);
1679       }
1680     }
1681
1682   // Get language-specific implicit directories.
1683   std::string implicitDirVar = "CMAKE_";
1684   implicitDirVar += this->LinkLanguage;
1685   implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
1686   if(const char* implicitDirs =
1687      this->Makefile->GetDefinition(implicitDirVar.c_str()))
1688     {
1689     cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1690     }
1691
1692   // Store implicit link directories.
1693   for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1694       i != implicitDirVec.end(); ++i)
1695     {
1696     this->ImplicitLinkDirs.insert(*i);
1697     }
1698
1699   // Get language-specific implicit libraries.
1700   std::vector<std::string> implicitLibVec;
1701   std::string implicitLibVar = "CMAKE_";
1702   implicitLibVar += this->LinkLanguage;
1703   implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
1704   if(const char* implicitLibs =
1705      this->Makefile->GetDefinition(implicitLibVar.c_str()))
1706     {
1707     cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec);
1708     }
1709
1710   // Store implicit link libraries.
1711   for(std::vector<std::string>::const_iterator i = implicitLibVec.begin();
1712       i != implicitLibVec.end(); ++i)
1713     {
1714     // Items starting in '-' but not '-l' are flags, not libraries,
1715     // and should not be filtered by this implicit list.
1716     std::string const& item = *i;
1717     if(item[0] != '-' || item[1] == 'l')
1718       {
1719       this->ImplicitLinkLibs.insert(item);
1720       }
1721     }
1722
1723   // Get platform specific rpath link directories
1724   if(const char *rpathDirs =
1725      (this->Makefile->GetDefinition
1726       ("CMAKE_PLATFORM_RUNTIME_PATH")))
1727     {
1728     cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs);
1729     }
1730 }
1731
1732 //----------------------------------------------------------------------------
1733 std::vector<std::string> const&
1734 cmComputeLinkInformation::GetRuntimeSearchPath()
1735 {
1736   return this->OrderRuntimeSearchPath->GetOrderedDirectories();
1737 }
1738
1739 //----------------------------------------------------------------------------
1740 void
1741 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
1742                                                 cmTarget* target)
1743 {
1744   // Ignore targets on Apple where install_name is not @rpath.
1745   // The dependenty library can be found with other means such as
1746   // @loader_path or full paths.
1747   if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
1748     {
1749     if(!target->HasMacOSXRpath(this->Config))
1750       {
1751       return;
1752       }
1753     }
1754
1755   // Libraries with unknown type must be handled using just the file
1756   // on disk.
1757   if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
1758     {
1759     this->AddLibraryRuntimeInfo(fullPath);
1760     return;
1761     }
1762
1763   // Skip targets that are not shared libraries (modules cannot be linked).
1764   if(target->GetType() != cmTarget::SHARED_LIBRARY)
1765     {
1766     return;
1767     }
1768
1769   // Try to get the soname of the library.  Only files with this name
1770   // could possibly conflict.
1771   std::string soName = target->GetSOName(this->Config);
1772   const char* soname = soName.empty()? 0 : soName.c_str();
1773
1774   // Include this library in the runtime path ordering.
1775   this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
1776   if(this->LinkWithRuntimePath)
1777     {
1778     this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
1779     }
1780 }
1781
1782 //----------------------------------------------------------------------------
1783 void
1784 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
1785 {
1786   // Get the name of the library from the file name.
1787   bool is_shared_library = false;
1788   std::string file = cmSystemTools::GetFilenameName(fullPath);
1789
1790   if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
1791     {
1792     // Check that @rpath is part of the install name.
1793     // If it isn't, return.
1794     std::string soname;
1795     if(!cmSystemTools::GuessLibraryInstallName(fullPath, soname))
1796       {
1797       return;
1798       }
1799
1800     if(soname.find("@rpath") == std::string::npos)
1801       {
1802       return;
1803       }
1804     }
1805
1806   is_shared_library = this->ExtractSharedLibraryName.find(file.c_str());
1807
1808   if(!is_shared_library)
1809     {
1810     // On some platforms (AIX) a shared library may look static.
1811     if(this->ArchivesMayBeShared)
1812       {
1813       if(this->ExtractStaticLibraryName.find(file.c_str()))
1814         {
1815         // This is the name of a shared library or archive.
1816         is_shared_library = true;
1817         }
1818       }
1819     }
1820
1821   // It could be an Apple framework
1822   if(!is_shared_library)
1823     {
1824     if(fullPath.find(".framework") != std::string::npos)
1825       {
1826       cmsys::RegularExpression splitFramework;
1827       splitFramework.compile("^(.*)/(.*).framework/(.*)$");
1828       if(splitFramework.find(fullPath) &&
1829         (std::string::npos !=
1830          splitFramework.match(3).find(splitFramework.match(2))))
1831         {
1832         is_shared_library = true;
1833         }
1834       }
1835     }
1836
1837   if(!is_shared_library)
1838     {
1839     return;
1840     }
1841
1842   // Include this library in the runtime path ordering.
1843   this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
1844   if(this->LinkWithRuntimePath)
1845     {
1846     this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
1847     }
1848 }
1849
1850 //----------------------------------------------------------------------------
1851 static void cmCLI_ExpandListUnique(const char* str,
1852                                    std::vector<std::string>& out,
1853                                    std::set<cmStdString>& emitted)
1854 {
1855   std::vector<std::string> tmp;
1856   cmSystemTools::ExpandListArgument(str, tmp);
1857   for(std::vector<std::string>::iterator i = tmp.begin(); i != tmp.end(); ++i)
1858     {
1859     if(emitted.insert(*i).second)
1860       {
1861       out.push_back(*i);
1862       }
1863     }
1864 }
1865
1866 //----------------------------------------------------------------------------
1867 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
1868                                         bool for_install)
1869 {
1870   // Select whether to generate runtime search directories.
1871   bool outputRuntime =
1872     !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
1873
1874   // Select whether to generate an rpath for the install tree or the
1875   // build tree.
1876   bool linking_for_install =
1877     (for_install ||
1878      this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1879   bool use_install_rpath =
1880     (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
1881      linking_for_install);
1882   bool use_build_rpath =
1883     (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
1884      !linking_for_install);
1885   bool use_link_rpath =
1886     outputRuntime && linking_for_install &&
1887     !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
1888     this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1889
1890   // Construct the RPATH.
1891   std::set<cmStdString> emitted;
1892   if(use_install_rpath)
1893     {
1894     const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
1895     cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
1896     }
1897   if(use_build_rpath || use_link_rpath)
1898     {
1899     std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
1900     for(std::vector<std::string>::const_iterator ri = rdirs.begin();
1901         ri != rdirs.end(); ++ri)
1902       {
1903       // Put this directory in the rpath if using build-tree rpath
1904       // support or if using the link path as an rpath.
1905       if(use_build_rpath)
1906         {
1907         if(emitted.insert(*ri).second)
1908           {
1909           runtimeDirs.push_back(*ri);
1910           }
1911         }
1912       else if(use_link_rpath)
1913         {
1914         // Do not add any path inside the source or build tree.
1915         const char* topSourceDir = this->Makefile->GetHomeDirectory();
1916         const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
1917         if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
1918            !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
1919            !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
1920            !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
1921           {
1922           if(emitted.insert(*ri).second)
1923             {
1924             runtimeDirs.push_back(*ri);
1925             }
1926           }
1927         }
1928       }
1929     }
1930
1931   // Add runtime paths required by the languages to always be
1932   // present.  This is done even when skipping rpath support.
1933   {
1934   cmTarget::LinkClosure const* lc =
1935     this->Target->GetLinkClosure(this->Config, this->HeadTarget);
1936   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
1937       li != lc->Languages.end(); ++li)
1938     {
1939     std::string useVar = "CMAKE_" + *li +
1940       "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
1941     if(this->Makefile->IsOn(useVar.c_str()))
1942       {
1943       std::string dirVar = "CMAKE_" + *li +
1944         "_IMPLICIT_LINK_DIRECTORIES";
1945       if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
1946         {
1947         cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
1948         }
1949       }
1950     }
1951   }
1952
1953   // Add runtime paths required by the platform to always be
1954   // present.  This is done even when skipping rpath support.
1955   cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
1956 }
1957
1958 //----------------------------------------------------------------------------
1959 std::string cmComputeLinkInformation::GetRPathString(bool for_install)
1960 {
1961   // Get the directories to use.
1962   std::vector<std::string> runtimeDirs;
1963   this->GetRPath(runtimeDirs, for_install);
1964
1965   // Concatenate the paths.
1966   std::string rpath;
1967   const char* sep = "";
1968   for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
1969       ri != runtimeDirs.end(); ++ri)
1970     {
1971     // Separate from previous path.
1972     rpath += sep;
1973     sep = this->GetRuntimeSep().c_str();
1974
1975     // Add this path.
1976     rpath += *ri;
1977     }
1978
1979   // If the rpath will be replaced at install time, prepare space.
1980   if(!for_install && this->RuntimeUseChrpath)
1981     {
1982     if(!rpath.empty())
1983       {
1984       // Add one trailing separator so the linker does not re-use the
1985       // rpath .dynstr entry for a symbol name that happens to match
1986       // the end of the rpath string.
1987       rpath += this->GetRuntimeSep();
1988       }
1989
1990     // Make sure it is long enough to hold the replacement value.
1991     std::string::size_type minLength = this->GetChrpathString().length();
1992     while(rpath.length() < minLength)
1993       {
1994       rpath += this->GetRuntimeSep();
1995       }
1996     }
1997
1998   return rpath;
1999 }
2000
2001 //----------------------------------------------------------------------------
2002 std::string cmComputeLinkInformation::GetChrpathString()
2003 {
2004   if(!this->RuntimeUseChrpath)
2005     {
2006     return "";
2007     }
2008
2009   return this->GetRPathString(true);
2010 }