896b50aa5affad45c9e4d2781a1e521189df346b
[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
887   // Create regex to remove any library extension.
888   std::string reg("(.*)");
889   reg += libext;
890   this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
891                                                     reg);
892
893   // Create a regex to match a library name.  Match index 1 will be
894   // the prefix if it exists and empty otherwise.  Match index 2 will
895   // be the library name.  Match index 3 will be the library
896   // extension.
897   reg = "^(";
898   for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
899       p != this->LinkPrefixes.end(); ++p)
900     {
901     reg += *p;
902     reg += "|";
903     }
904   reg += ")";
905   reg += "([^/:]*)";
906
907   // Create a regex to match any library name.
908   std::string reg_any = reg;
909   reg_any += libext;
910 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
911   fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
912 #endif
913   this->ExtractAnyLibraryName.compile(reg_any.c_str());
914
915   // Create a regex to match static library names.
916   if(!this->StaticLinkExtensions.empty())
917     {
918     std::string reg_static = reg;
919     reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
920 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
921   fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
922 #endif
923     this->ExtractStaticLibraryName.compile(reg_static.c_str());
924     }
925
926   // Create a regex to match shared library names.
927   if(!this->SharedLinkExtensions.empty())
928     {
929     std::string reg_shared = reg;
930     this->SharedRegexString =
931       this->CreateExtensionRegex(this->SharedLinkExtensions);
932     reg_shared += this->SharedRegexString;
933 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
934   fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
935 #endif
936     this->ExtractSharedLibraryName.compile(reg_shared.c_str());
937     }
938 }
939
940 //----------------------------------------------------------------------------
941 void cmComputeLinkInformation::AddLinkPrefix(const char* p)
942 {
943   if(p && *p)
944     {
945     this->LinkPrefixes.insert(p);
946     }
947 }
948
949 //----------------------------------------------------------------------------
950 void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
951 {
952   if(e && *e)
953     {
954     if(type == LinkStatic)
955       {
956       this->StaticLinkExtensions.push_back(e);
957       }
958     if(type == LinkShared)
959       {
960       this->SharedLinkExtensions.push_back(e);
961       }
962     this->LinkExtensions.push_back(e);
963     }
964 }
965
966 //----------------------------------------------------------------------------
967 std::string
968 cmComputeLinkInformation
969 ::CreateExtensionRegex(std::vector<std::string> const& exts)
970 {
971   // Build a list of extension choices.
972   std::string libext = "(";
973   const char* sep = "";
974   for(std::vector<std::string>::const_iterator i = exts.begin();
975       i != exts.end(); ++i)
976     {
977     // Separate this choice from the previous one.
978     libext += sep;
979     sep = "|";
980
981     // Store this extension choice with the "." escaped.
982     libext += "\\";
983 #if defined(_WIN32) && !defined(__CYGWIN__)
984     libext += this->NoCaseExpression(i->c_str());
985 #else
986     libext += *i;
987 #endif
988     }
989
990   // Finish the list.
991   libext += ")";
992
993   // Add an optional OpenBSD version component.
994   if(this->OpenBSD)
995     {
996     libext += "(\\.[0-9]+\\.[0-9]+)?";
997     }
998
999   libext += "$";
1000   return libext;
1001 }
1002
1003 //----------------------------------------------------------------------------
1004 std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
1005 {
1006   std::string ret;
1007   const char* s = str;
1008   while(*s)
1009     {
1010     if(*s == '.')
1011       {
1012       ret += *s;
1013       }
1014     else
1015       {
1016       ret += "[";
1017       ret += static_cast<char>(tolower(*s));
1018       ret += static_cast<char>(toupper(*s));
1019       ret += "]";
1020       }
1021     s++;
1022     }
1023   return ret;
1024 }
1025
1026 //-------------------------------------------------------------------
1027 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
1028 {
1029   // If we are changing the current link type add the flag to tell the
1030   // linker about it.
1031   if(this->CurrentLinkType != lt)
1032     {
1033     this->CurrentLinkType = lt;
1034
1035     if(this->LinkTypeEnabled)
1036       {
1037       switch(this->CurrentLinkType)
1038         {
1039         case LinkStatic:
1040           this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
1041           break;
1042         case LinkShared:
1043           this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
1044           break;
1045         default:
1046           break;
1047         }
1048       }
1049     }
1050 }
1051
1052 //----------------------------------------------------------------------------
1053 void cmComputeLinkInformation::AddTargetItem(std::string const& item,
1054                                              cmTarget* target)
1055 {
1056   // This is called to handle a link item that is a full path to a target.
1057   // If the target is not a static library make sure the link type is
1058   // shared.  This is because dynamic-mode linking can handle both
1059   // shared and static libraries but static-mode can handle only
1060   // static libraries.  If a previous user item changed the link type
1061   // to static we need to make sure it is back to shared.
1062   if(target->GetType() != cmTarget::STATIC_LIBRARY)
1063     {
1064     this->SetCurrentLinkType(LinkShared);
1065     }
1066
1067   // Keep track of shared library targets linked.
1068   if(target->GetType() == cmTarget::SHARED_LIBRARY)
1069     {
1070     this->SharedLibrariesLinked.insert(target);
1071     }
1072
1073   // Handle case of an imported shared library with no soname.
1074   if(this->NoSONameUsesPath &&
1075      target->IsImportedSharedLibWithoutSOName(this->Config))
1076     {
1077     this->AddSharedLibNoSOName(item);
1078     return;
1079     }
1080
1081   // If this platform wants a flag before the full path, add it.
1082   if(!this->LibLinkFileFlag.empty())
1083     {
1084     this->Items.push_back(Item(this->LibLinkFileFlag, false));
1085     }
1086
1087   // For compatibility with CMake 2.4 include the item's directory in
1088   // the linker search path.
1089   if(this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
1090      this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1091      this->OldLinkDirMask.end())
1092     {
1093     this->OldLinkDirItems.push_back(item);
1094     }
1095
1096   // Now add the full path to the library.
1097   this->Items.push_back(Item(item, true, target));
1098 }
1099
1100 //----------------------------------------------------------------------------
1101 void cmComputeLinkInformation::AddFullItem(std::string const& item)
1102 {
1103   // Check for the implicit link directory special case.
1104   if(this->CheckImplicitDirItem(item))
1105     {
1106     return;
1107     }
1108
1109   // Check for case of shared library with no builtin soname.
1110   if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
1111     {
1112     return;
1113     }
1114
1115   // Full path libraries should specify a valid library file name.
1116   // See documentation of CMP0008.
1117   if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
1118      (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
1119       strstr(this->GlobalGenerator->GetName(), "Xcode")))
1120     {
1121     std::string file = cmSystemTools::GetFilenameName(item);
1122     if(!this->ExtractAnyLibraryName.find(file.c_str()))
1123       {
1124       this->HandleBadFullItem(item, file);
1125       return;
1126       }
1127     }
1128
1129   // This is called to handle a link item that is a full path.
1130   // If the target is not a static library make sure the link type is
1131   // shared.  This is because dynamic-mode linking can handle both
1132   // shared and static libraries but static-mode can handle only
1133   // static libraries.  If a previous user item changed the link type
1134   // to static we need to make sure it is back to shared.
1135   if(this->LinkTypeEnabled)
1136     {
1137     std::string name = cmSystemTools::GetFilenameName(item);
1138     if(this->ExtractSharedLibraryName.find(name))
1139       {
1140       this->SetCurrentLinkType(LinkShared);
1141       }
1142     else if(!this->ExtractStaticLibraryName.find(item))
1143       {
1144       // We cannot determine the type.  Assume it is the target's
1145       // default type.
1146       this->SetCurrentLinkType(this->StartLinkType);
1147       }
1148     }
1149
1150   // For compatibility with CMake 2.4 include the item's directory in
1151   // the linker search path.
1152   if(this->OldLinkDirMode &&
1153      this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1154      this->OldLinkDirMask.end())
1155     {
1156     this->OldLinkDirItems.push_back(item);
1157     }
1158
1159   // If this platform wants a flag before the full path, add it.
1160   if(!this->LibLinkFileFlag.empty())
1161     {
1162     this->Items.push_back(Item(this->LibLinkFileFlag, false));
1163     }
1164
1165   // Now add the full path to the library.
1166   this->Items.push_back(Item(item, true));
1167 }
1168
1169 //----------------------------------------------------------------------------
1170 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
1171 {
1172   // We only switch to a pathless item if the link type may be
1173   // enforced.  Fortunately only platforms that support link types
1174   // seem to have magic per-architecture implicit link directories.
1175   if(!this->LinkTypeEnabled)
1176     {
1177     return false;
1178     }
1179
1180   // Check if this item is in an implicit link directory.
1181   std::string dir = cmSystemTools::GetFilenamePath(item);
1182   if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
1183     {
1184     // Only libraries in implicit link directories are converted to
1185     // pathless items.
1186     return false;
1187     }
1188
1189   // Only apply the policy below if the library file is one that can
1190   // be found by the linker.
1191   std::string file = cmSystemTools::GetFilenameName(item);
1192   if(!this->ExtractAnyLibraryName.find(file))
1193     {
1194     return false;
1195     }
1196
1197   // Many system linkers support multiple architectures by
1198   // automatically selecting the implicit linker search path for the
1199   // current architecture.  If the library appears in an implicit link
1200   // directory then just report the file name without the directory
1201   // portion.  This will allow the system linker to locate the proper
1202   // library for the architecture at link time.
1203   this->AddUserItem(file, false);
1204
1205   // Make sure the link directory ordering will find the library.
1206   this->OrderLinkerSearchPath->AddLinkLibrary(item);
1207
1208   return true;
1209 }
1210
1211 //----------------------------------------------------------------------------
1212 void cmComputeLinkInformation::AddUserItem(std::string const& item,
1213                                            bool pathNotKnown)
1214 {
1215   // This is called to handle a link item that does not match a CMake
1216   // target and is not a full path.  We check here if it looks like a
1217   // library file name to automatically request the proper link type
1218   // from the linker.  For example:
1219   //
1220   //   foo       ==>  -lfoo
1221   //   libfoo.a  ==>  -Wl,-Bstatic -lfoo
1222
1223   // Pass flags through untouched.
1224   if(item[0] == '-' || item[0] == '$' || item[0] == '`')
1225     {
1226     // if this is a -l option then we might need to warn about
1227     // CMP0003 so put it in OldUserFlagItems, if it is not a -l
1228     // or -Wl,-l (-framework -pthread), then allow it without a
1229     // CMP0003 as -L will not affect those other linker flags
1230     if(item.find("-l") == 0 ||  item.find("-Wl,-l") == 0)
1231       {
1232       // This is a linker option provided by the user.
1233       this->OldUserFlagItems.push_back(item);
1234       }
1235
1236     // Restore the target link type since this item does not specify
1237     // one.
1238     this->SetCurrentLinkType(this->StartLinkType);
1239
1240     // Use the item verbatim.
1241     this->Items.push_back(Item(item, false));
1242     return;
1243     }
1244
1245   // Parse out the prefix, base, and suffix components of the
1246   // library name.  If the name matches that of a shared or static
1247   // library then set the link type accordingly.
1248   //
1249   // Search for shared library names first because some platforms
1250   // have shared libraries with names that match the static library
1251   // pattern.  For example cygwin and msys use the convention
1252   // libfoo.dll.a for import libraries and libfoo.a for static
1253   // libraries.  On AIX a library with the name libfoo.a can be
1254   // shared!
1255   std::string lib;
1256   if(this->ExtractSharedLibraryName.find(item))
1257     {
1258     // This matches a shared library file name.
1259 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1260     fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
1261             this->ExtractSharedLibraryName.match(1).c_str(),
1262             this->ExtractSharedLibraryName.match(2).c_str(),
1263             this->ExtractSharedLibraryName.match(3).c_str());
1264 #endif
1265     // Set the link type to shared.
1266     this->SetCurrentLinkType(LinkShared);
1267
1268     // Use just the library name so the linker will search.
1269     lib = this->ExtractSharedLibraryName.match(2);
1270     }
1271   else if(this->ExtractStaticLibraryName.find(item))
1272     {
1273     // This matches a static library file name.
1274 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1275     fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
1276             this->ExtractStaticLibraryName.match(1).c_str(),
1277             this->ExtractStaticLibraryName.match(2).c_str(),
1278             this->ExtractStaticLibraryName.match(3).c_str());
1279 #endif
1280     // Set the link type to static.
1281     this->SetCurrentLinkType(LinkStatic);
1282
1283     // Use just the library name so the linker will search.
1284     lib = this->ExtractStaticLibraryName.match(2);
1285     }
1286   else if(this->ExtractAnyLibraryName.find(item))
1287     {
1288     // This matches a library file name.
1289 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1290     fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
1291             this->ExtractAnyLibraryName.match(1).c_str(),
1292             this->ExtractAnyLibraryName.match(2).c_str(),
1293             this->ExtractAnyLibraryName.match(3).c_str());
1294 #endif
1295     // Restore the target link type since this item does not specify
1296     // one.
1297     this->SetCurrentLinkType(this->StartLinkType);
1298
1299     // Use just the library name so the linker will search.
1300     lib = this->ExtractAnyLibraryName.match(2);
1301     }
1302   else
1303     {
1304     // This is a name specified by the user.
1305     if(pathNotKnown)
1306       {
1307       this->OldUserFlagItems.push_back(item);
1308       }
1309
1310     // We must ask the linker to search for a library with this name.
1311     // Restore the target link type since this item does not specify
1312     // one.
1313     this->SetCurrentLinkType(this->StartLinkType);
1314     lib = item;
1315     }
1316
1317   // Create an option to ask the linker to search for the library.
1318   std::string out = this->LibLinkFlag;
1319   out += lib;
1320   out += this->LibLinkSuffix;
1321   this->Items.push_back(Item(out, false));
1322
1323   // Here we could try to find the library the linker will find and
1324   // add a runtime information entry for it.  It would probably not be
1325   // reliable and we want to encourage use of full paths for library
1326   // specification.
1327 }
1328
1329 //----------------------------------------------------------------------------
1330 void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
1331 {
1332   // Try to separate the framework name and path.
1333   if(!this->SplitFramework.find(item.c_str()))
1334     {
1335     cmOStringStream e;
1336     e << "Could not parse framework path \"" << item << "\" "
1337       << "linked by target " << this->Target->GetName() << ".";
1338     cmSystemTools::Error(e.str().c_str());
1339     return;
1340     }
1341
1342   // Add the directory portion to the framework search path.
1343   this->AddFrameworkPath(this->SplitFramework.match(1));
1344
1345   // Add the item using the -framework option.
1346   this->Items.push_back(Item("-framework", false));
1347   std::string fw = this->SplitFramework.match(2);
1348   fw = this->LocalGenerator->EscapeForShell(fw.c_str());
1349   this->Items.push_back(Item(fw, false));
1350 }
1351
1352 //----------------------------------------------------------------------------
1353 void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
1354 {
1355   if(this->Makefile->IsOn("APPLE")
1356      && cmSystemTools::IsPathToFramework(item.c_str()))
1357     {
1358     this->AddFrameworkItem(item);
1359     }
1360   else
1361     {
1362     this->DropDirectoryItem(item);
1363     }
1364 }
1365
1366 //----------------------------------------------------------------------------
1367 void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
1368 {
1369   // A full path to a directory was found as a link item.  Warn the
1370   // user.
1371   cmOStringStream e;
1372   e << "WARNING: Target \"" << this->Target->GetName()
1373     << "\" requests linking to directory \"" << item << "\".  "
1374     << "Targets may link only to libraries.  "
1375     << "CMake is dropping the item.";
1376   cmSystemTools::Message(e.str().c_str());
1377 }
1378
1379 //----------------------------------------------------------------------------
1380 void cmComputeLinkInformation::ComputeFrameworkInfo()
1381 {
1382   // Avoid adding implicit framework paths.
1383   std::vector<std::string> implicitDirVec;
1384
1385   // Get platform-wide implicit directories.
1386   if(const char* implicitLinks = this->Makefile->GetDefinition
1387      ("CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"))
1388     {
1389     cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1390     }
1391
1392   // Get language-specific implicit directories.
1393   std::string implicitDirVar = "CMAKE_";
1394   implicitDirVar += this->LinkLanguage;
1395   implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
1396   if(const char* implicitDirs =
1397      this->Makefile->GetDefinition(implicitDirVar.c_str()))
1398     {
1399     cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1400     }
1401
1402   for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1403       i != implicitDirVec.end(); ++i)
1404     {
1405     this->FrameworkPathsEmmitted.insert(*i);
1406     }
1407
1408   // Regular expression to extract a framework path and name.
1409   this->SplitFramework.compile("(.*)/(.*)\\.framework$");
1410 }
1411
1412 //----------------------------------------------------------------------------
1413 void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
1414 {
1415   if(this->FrameworkPathsEmmitted.insert(p).second)
1416     {
1417     this->FrameworkPaths.push_back(p);
1418     }
1419 }
1420
1421 //----------------------------------------------------------------------------
1422 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
1423 {
1424   // This platform will use the path to a library as its soname if the
1425   // library is given via path and was not built with an soname.  If
1426   // this is a shared library that might be the case.
1427   std::string file = cmSystemTools::GetFilenameName(item);
1428   if(this->ExtractSharedLibraryName.find(file))
1429     {
1430     // If we can guess the soname fairly reliably then assume the
1431     // library has one.  Otherwise assume the library has no builtin
1432     // soname.
1433     std::string soname;
1434     if(!cmSystemTools::GuessLibrarySOName(item, soname))
1435       {
1436       this->AddSharedLibNoSOName(item);
1437       return true;
1438       }
1439     }
1440   return false;
1441 }
1442
1443 //----------------------------------------------------------------------------
1444 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
1445 {
1446   // We have a full path to a shared library with no soname.  We need
1447   // to ask the linker to locate the item because otherwise the path
1448   // we give to it will be embedded in the target linked.  Then at
1449   // runtime the dynamic linker will search for the library using the
1450   // path instead of just the name.
1451   std::string file = cmSystemTools::GetFilenameName(item);
1452   this->AddUserItem(file, false);
1453
1454   // Make sure the link directory ordering will find the library.
1455   this->OrderLinkerSearchPath->AddLinkLibrary(item);
1456 }
1457
1458 //----------------------------------------------------------------------------
1459 void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
1460                                                  std::string const& file)
1461 {
1462   // Do not depend on things that do not exist.
1463   std::vector<std::string>::iterator i =
1464     std::find(this->Depends.begin(), this->Depends.end(), item);
1465   if(i != this->Depends.end())
1466     {
1467     this->Depends.erase(i);
1468     }
1469
1470   // Tell the linker to search for the item and provide the proper
1471   // path for it.  Do not contribute to any CMP0003 warning (do not
1472   // put in OldLinkDirItems or OldUserFlagItems).
1473   this->AddUserItem(file, false);
1474   this->OrderLinkerSearchPath->AddLinkLibrary(item);
1475
1476   // Produce any needed message.
1477   switch(this->Target->GetPolicyStatusCMP0008())
1478     {
1479     case cmPolicies::WARN:
1480       {
1481       // Print the warning at most once for this item.
1482       std::string wid = "CMP0008-WARNING-GIVEN-";
1483       wid += item;
1484       if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
1485         {
1486         this->CMakeInstance->SetProperty(wid.c_str(), "1");
1487         cmOStringStream w;
1488         w << (this->Makefile->GetPolicies()
1489               ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n"
1490           << "Target \"" << this->Target->GetName() << "\" links to item\n"
1491           << "  " << item << "\n"
1492           << "which is a full-path but not a valid library file name.";
1493         this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1494                                           this->Target->GetBacktrace());
1495         }
1496       }
1497     case cmPolicies::OLD:
1498       // OLD behavior does not warn.
1499       break;
1500     case cmPolicies::NEW:
1501       // NEW behavior will not get here.
1502       break;
1503     case cmPolicies::REQUIRED_IF_USED:
1504     case cmPolicies::REQUIRED_ALWAYS:
1505       {
1506       cmOStringStream e;
1507       e << (this->Makefile->GetPolicies()->
1508             GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n"
1509           << "Target \"" << this->Target->GetName() << "\" links to item\n"
1510           << "  " << item << "\n"
1511           << "which is a full-path but not a valid library file name.";
1512       this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1513                                         this->Target->GetBacktrace());
1514       }
1515       break;
1516     }
1517 }
1518
1519 //----------------------------------------------------------------------------
1520 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1521 {
1522   // Support broken projects if necessary.
1523   if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
1524      !this->OldLinkDirMode)
1525     {
1526     return true;
1527     }
1528
1529   // Enforce policy constraints.
1530   switch(this->Target->GetPolicyStatusCMP0003())
1531     {
1532     case cmPolicies::WARN:
1533       if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1534         {
1535         this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
1536         cmOStringStream w;
1537         this->PrintLinkPolicyDiagnosis(w);
1538         this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1539                                           this->Target->GetBacktrace());
1540         }
1541     case cmPolicies::OLD:
1542       // OLD behavior is to add the paths containing libraries with
1543       // known full paths as link directories.
1544       break;
1545     case cmPolicies::NEW:
1546       // Should never happen due to assignment of OldLinkDirMode
1547       return true;
1548     case cmPolicies::REQUIRED_IF_USED:
1549     case cmPolicies::REQUIRED_ALWAYS:
1550       {
1551       cmOStringStream e;
1552       e << (this->Makefile->GetPolicies()->
1553             GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
1554       this->PrintLinkPolicyDiagnosis(e);
1555       this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1556                                         this->Target->GetBacktrace());
1557       return false;
1558       }
1559     }
1560
1561   // Add the link directories for full path items.
1562   for(std::vector<std::string>::const_iterator
1563         i = this->OldLinkDirItems.begin();
1564       i != this->OldLinkDirItems.end(); ++i)
1565     {
1566     this->OrderLinkerSearchPath->AddLinkLibrary(*i);
1567     }
1568   return true;
1569 }
1570
1571 //----------------------------------------------------------------------------
1572 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
1573 {
1574   // Tell the user what to do.
1575   os << "Policy CMP0003 should be set before this line.  "
1576      << "Add code such as\n"
1577      << "  if(COMMAND cmake_policy)\n"
1578      << "    cmake_policy(SET CMP0003 NEW)\n"
1579      << "  endif(COMMAND cmake_policy)\n"
1580      << "as early as possible but after the most recent call to "
1581      << "cmake_minimum_required or cmake_policy(VERSION).  ";
1582
1583   // List the items that might need the old-style paths.
1584   os << "This warning appears because target \""
1585      << this->Target->GetName() << "\" "
1586      << "links to some libraries for which the linker must search:\n";
1587   {
1588   // Format the list of unknown items to be as short as possible while
1589   // still fitting in the allowed width (a true solution would be the
1590   // bin packing problem if we were allowed to change the order).
1591   std::string::size_type max_size = 76;
1592   std::string line;
1593   const char* sep = "  ";
1594   for(std::vector<std::string>::const_iterator
1595         i = this->OldUserFlagItems.begin();
1596       i != this->OldUserFlagItems.end(); ++i)
1597     {
1598     // If the addition of another item will exceed the limit then
1599     // output the current line and reset it.  Note that the separator
1600     // is either " " or ", " which is always 2 characters.
1601     if(!line.empty() && (line.size() + i->size() + 2) > max_size)
1602       {
1603       os << line << "\n";
1604       sep = "  ";
1605       line = "";
1606       }
1607     line += sep;
1608     line += *i;
1609     // Convert to the other separator.
1610     sep = ", ";
1611     }
1612   if(!line.empty())
1613     {
1614     os << line << "\n";
1615     }
1616   }
1617
1618   // List the paths old behavior is adding.
1619   os << "and other libraries with known full path:\n";
1620   std::set<cmStdString> emitted;
1621   for(std::vector<std::string>::const_iterator
1622         i = this->OldLinkDirItems.begin();
1623       i != this->OldLinkDirItems.end(); ++i)
1624     {
1625     if(emitted.insert(cmSystemTools::GetFilenamePath(*i)).second)
1626       {
1627       os << "  " << *i << "\n";
1628       }
1629     }
1630
1631   // Explain.
1632   os << "CMake is adding directories in the second list to the linker "
1633      << "search path in case they are needed to find libraries from the "
1634      << "first list (for backwards compatibility with CMake 2.4).  "
1635      << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1636      << "behavior explicitly.  "
1637      << "Run \"cmake --help-policy CMP0003\" for more information.";
1638 }
1639
1640 //----------------------------------------------------------------------------
1641 void cmComputeLinkInformation::LoadImplicitLinkInfo()
1642 {
1643   std::vector<std::string> implicitDirVec;
1644
1645   // Get platform-wide implicit directories.
1646   if(const char* implicitLinks =
1647      (this->Makefile->GetDefinition
1648       ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
1649     {
1650     cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1651     }
1652
1653   // Append library architecture to all implicit platform directories
1654   // and add them to the set
1655   if(const char* libraryArch =
1656      this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
1657     {
1658     for (std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1659          i != implicitDirVec.end(); ++i)
1660       {
1661       this->ImplicitLinkDirs.insert(*i + "/" + libraryArch);
1662       }
1663     }
1664
1665   // Get language-specific implicit directories.
1666   std::string implicitDirVar = "CMAKE_";
1667   implicitDirVar += this->LinkLanguage;
1668   implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
1669   if(const char* implicitDirs =
1670      this->Makefile->GetDefinition(implicitDirVar.c_str()))
1671     {
1672     cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1673     }
1674
1675   // Store implicit link directories.
1676   for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1677       i != implicitDirVec.end(); ++i)
1678     {
1679     this->ImplicitLinkDirs.insert(*i);
1680     }
1681
1682   // Get language-specific implicit libraries.
1683   std::vector<std::string> implicitLibVec;
1684   std::string implicitLibVar = "CMAKE_";
1685   implicitLibVar += this->LinkLanguage;
1686   implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
1687   if(const char* implicitLibs =
1688      this->Makefile->GetDefinition(implicitLibVar.c_str()))
1689     {
1690     cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec);
1691     }
1692
1693   // Store implicit link libraries.
1694   for(std::vector<std::string>::const_iterator i = implicitLibVec.begin();
1695       i != implicitLibVec.end(); ++i)
1696     {
1697     // Items starting in '-' but not '-l' are flags, not libraries,
1698     // and should not be filtered by this implicit list.
1699     std::string const& item = *i;
1700     if(item[0] != '-' || item[1] == 'l')
1701       {
1702       this->ImplicitLinkLibs.insert(item);
1703       }
1704     }
1705
1706   // Get platform specific rpath link directories
1707   if(const char *rpathDirs =
1708      (this->Makefile->GetDefinition
1709       ("CMAKE_PLATFORM_RUNTIME_PATH")))
1710     {
1711     cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs);
1712     }
1713 }
1714
1715 //----------------------------------------------------------------------------
1716 std::vector<std::string> const&
1717 cmComputeLinkInformation::GetRuntimeSearchPath()
1718 {
1719   return this->OrderRuntimeSearchPath->GetOrderedDirectories();
1720 }
1721
1722 //----------------------------------------------------------------------------
1723 void
1724 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
1725                                                 cmTarget* target)
1726 {
1727   // Libraries with unknown type must be handled using just the file
1728   // on disk.
1729   if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
1730     {
1731     this->AddLibraryRuntimeInfo(fullPath);
1732     return;
1733     }
1734
1735   // Skip targets that are not shared libraries (modules cannot be linked).
1736   if(target->GetType() != cmTarget::SHARED_LIBRARY)
1737     {
1738     return;
1739     }
1740
1741   // Try to get the soname of the library.  Only files with this name
1742   // could possibly conflict.
1743   std::string soName = target->GetSOName(this->Config);
1744   const char* soname = soName.empty()? 0 : soName.c_str();
1745
1746   // Include this library in the runtime path ordering.
1747   this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
1748   if(this->LinkWithRuntimePath)
1749     {
1750     this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
1751     }
1752 }
1753
1754 //----------------------------------------------------------------------------
1755 void
1756 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
1757 {
1758   // Get the name of the library from the file name.
1759   std::string file = cmSystemTools::GetFilenameName(fullPath);
1760   if(!this->ExtractSharedLibraryName.find(file.c_str()))
1761     {
1762     // On some platforms (AIX) a shared library may look static.
1763     if(this->ArchivesMayBeShared)
1764       {
1765       if(!this->ExtractStaticLibraryName.find(file.c_str()))
1766         {
1767         // This is not the name of a shared library or archive.
1768         return;
1769         }
1770       }
1771     else
1772       {
1773       // This is not the name of a shared library.
1774       return;
1775       }
1776     }
1777
1778   // Include this library in the runtime path ordering.
1779   this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
1780   if(this->LinkWithRuntimePath)
1781     {
1782     this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
1783     }
1784 }
1785
1786 //----------------------------------------------------------------------------
1787 static void cmCLI_ExpandListUnique(const char* str,
1788                                    std::vector<std::string>& out,
1789                                    std::set<cmStdString>& emitted)
1790 {
1791   std::vector<std::string> tmp;
1792   cmSystemTools::ExpandListArgument(str, tmp);
1793   for(std::vector<std::string>::iterator i = tmp.begin(); i != tmp.end(); ++i)
1794     {
1795     if(emitted.insert(*i).second)
1796       {
1797       out.push_back(*i);
1798       }
1799     }
1800 }
1801
1802 //----------------------------------------------------------------------------
1803 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
1804                                         bool for_install)
1805 {
1806   // Select whether to generate runtime search directories.
1807   bool outputRuntime =
1808     !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
1809
1810   // Select whether to generate an rpath for the install tree or the
1811   // build tree.
1812   bool linking_for_install =
1813     (for_install ||
1814      this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1815   bool use_install_rpath =
1816     (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
1817      linking_for_install);
1818   bool use_build_rpath =
1819     (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
1820      !linking_for_install);
1821   bool use_link_rpath =
1822     outputRuntime && linking_for_install &&
1823     !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
1824     this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1825
1826   // Construct the RPATH.
1827   std::set<cmStdString> emitted;
1828   if(use_install_rpath)
1829     {
1830     const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
1831     cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
1832     }
1833   if(use_build_rpath || use_link_rpath)
1834     {
1835     std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
1836     for(std::vector<std::string>::const_iterator ri = rdirs.begin();
1837         ri != rdirs.end(); ++ri)
1838       {
1839       // Put this directory in the rpath if using build-tree rpath
1840       // support or if using the link path as an rpath.
1841       if(use_build_rpath)
1842         {
1843         if(emitted.insert(*ri).second)
1844           {
1845           runtimeDirs.push_back(*ri);
1846           }
1847         }
1848       else if(use_link_rpath)
1849         {
1850         // Do not add any path inside the source or build tree.
1851         const char* topSourceDir = this->Makefile->GetHomeDirectory();
1852         const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
1853         if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
1854            !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
1855            !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
1856            !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
1857           {
1858           if(emitted.insert(*ri).second)
1859             {
1860             runtimeDirs.push_back(*ri);
1861             }
1862           }
1863         }
1864       }
1865     }
1866
1867   // Add runtime paths required by the languages to always be
1868   // present.  This is done even when skipping rpath support.
1869   {
1870   cmTarget::LinkClosure const* lc =
1871     this->Target->GetLinkClosure(this->Config, this->HeadTarget);
1872   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
1873       li != lc->Languages.end(); ++li)
1874     {
1875     std::string useVar = "CMAKE_" + *li +
1876       "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
1877     if(this->Makefile->IsOn(useVar.c_str()))
1878       {
1879       std::string dirVar = "CMAKE_" + *li +
1880         "_IMPLICIT_LINK_DIRECTORIES";
1881       if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
1882         {
1883         cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
1884         }
1885       }
1886     }
1887   }
1888
1889   // Add runtime paths required by the platform to always be
1890   // present.  This is done even when skipping rpath support.
1891   cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
1892 }
1893
1894 //----------------------------------------------------------------------------
1895 std::string cmComputeLinkInformation::GetRPathString(bool for_install)
1896 {
1897   // Get the directories to use.
1898   std::vector<std::string> runtimeDirs;
1899   this->GetRPath(runtimeDirs, for_install);
1900
1901   // Concatenate the paths.
1902   std::string rpath;
1903   const char* sep = "";
1904   for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
1905       ri != runtimeDirs.end(); ++ri)
1906     {
1907     // Separate from previous path.
1908     rpath += sep;
1909     sep = this->GetRuntimeSep().c_str();
1910
1911     // Add this path.
1912     rpath += *ri;
1913     }
1914
1915   // If the rpath will be replaced at install time, prepare space.
1916   if(!for_install && this->RuntimeUseChrpath)
1917     {
1918     if(!rpath.empty())
1919       {
1920       // Add one trailing separator so the linker does not re-use the
1921       // rpath .dynstr entry for a symbol name that happens to match
1922       // the end of the rpath string.
1923       rpath += this->GetRuntimeSep();
1924       }
1925
1926     // Make sure it is long enough to hold the replacement value.
1927     std::string::size_type minLength = this->GetChrpathString().length();
1928     while(rpath.length() < minLength)
1929       {
1930       rpath += this->GetRuntimeSep();
1931       }
1932     }
1933
1934   return rpath;
1935 }
1936
1937 //----------------------------------------------------------------------------
1938 std::string cmComputeLinkInformation::GetChrpathString()
1939 {
1940   if(!this->RuntimeUseChrpath)
1941     {
1942     return "";
1943     }
1944
1945   return this->GetRPathString(true);
1946 }