Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmComputeLinkInformation.cxx
blobb06d7cc33fc1b3ce4270e28765afaa2baac4ecbe
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmComputeLinkInformation.cxx,v $
5 Language: C++
6 Date: $Date: 2008-03-31 16:47:31 $
7 Version: $Revision: 1.32 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmComputeLinkInformation.h"
19 #include "cmComputeLinkDepends.h"
20 #include "cmOrderDirectories.h"
22 #include "cmGlobalGenerator.h"
23 #include "cmLocalGenerator.h"
24 #include "cmMakefile.h"
25 #include "cmTarget.h"
26 #include "cmake.h"
28 #include <ctype.h>
30 //#define CM_COMPUTE_LINK_INFO_DEBUG
33 Notes about linking on various platforms:
35 ------------------------------------------------------------------------------
37 Linux, FreeBSD, Mac OS X, IRIX, Sun, Windows:
39 Linking to libraries using the full path works fine.
41 ------------------------------------------------------------------------------
43 On AIX, more work is needed.
45 The "-bnoipath" option is needed. From "man ld":
47 Note: If you specify a shared object, or an archive file
48 containing a shared object, with an absolute or relative path
49 name, instead of with the -lName flag, the path name is
50 included in the import file ID string in the loader section of
51 the output file. You can override this behavior with the
52 -bnoipath option.
54 noipath
56 For shared objects listed on the command-line, rather than
57 specified with the -l flag, use a null path component when
58 listing the shared object in the loader section of the
59 output file. A null path component is always used for
60 shared objects specified with the -l flag. This option
61 does not affect the specification of a path component by
62 using a line beginning with #! in an import file. The
63 default is the ipath option.
65 This prevents the full path specified on the compile line from being
66 compiled directly into the binary.
68 By default the linker places -L paths in the embedded runtime path.
69 In order to implement CMake's RPATH interface correctly, we need the
70 -blibpath:Path option. From "man ld":
72 libpath:Path
74 Uses Path as the library path when writing the loader section
75 of the output file. Path is neither checked for validity nor
76 used when searching for libraries specified by the -l flag.
77 Path overrides any library paths generated when the -L flag is
78 used.
80 If you do not specify any -L flags, or if you specify the
81 nolibpath option, the default library path information is
82 written in the loader section of the output file. The default
83 library path information is the value of the LIBPATH
84 environment variable if it is defined, and /usr/lib:/lib,
85 otherwise.
87 We can pass -Wl,-blibpath:/usr/lib:/lib always to avoid the -L stuff
88 and not break when the user sets LIBPATH. Then if we want to add an
89 rpath we insert it into the option before /usr/lib.
91 ------------------------------------------------------------------------------
93 On HP-UX, more work is needed. There are differences between
94 versions.
96 ld: 92453-07 linker linker ld B.10.33 990520
98 Linking with a full path works okay for static and shared libraries.
99 The linker seems to always put the full path to where the library
100 was found in the binary whether using a full path or -lfoo syntax.
101 Transitive link dependencies work just fine due to the full paths.
103 It has the "-l:libfoo.sl" option. The +nodefaultrpath is accepted
104 but not documented and does not seem to do anything. There is no
105 +forceload option.
107 ld: 92453-07 linker ld HP Itanium(R) B.12.41 IPF/IPF
109 Linking with a full path works okay for static libraries.
111 Linking with a full path works okay for shared libraries. However
112 dependent (transitive) libraries of those linked directly must be
113 either found with an rpath stored in the direct dependencies or
114 found in -L paths as if they were specified with "-l:libfoo.sl"
115 (really "-l:<soname>"). The search matches that of the dynamic
116 loader but only with -L paths. In other words, if we have an
117 executable that links to shared library bar which links to shared
118 library foo, the link line for the exe must contain
120 /dir/with/bar/libbar.sl -L/dir/with/foo
122 It does not matter whether the exe wants to link to foo directly or
123 whether /dir/with/foo/libfoo.sl is listed. The -L path must still
124 be present. It should match the runtime path computed for the
125 executable taking all directly and transitively linked libraries
126 into account.
128 The "+nodefaultrpath" option should be used to avoid getting -L
129 paths in the rpath unless we add our own rpath with +b. This means
130 that skip-build-rpath should use this option.
132 See documentation in "man ld", "man dld.so", and
133 http://docs.hp.com/en/B2355-90968/creatingandusinglibraries.htm
135 +[no]defaultrpath
136 +defaultrpath is the default. Include any paths that are
137 specified with -L in the embedded path, unless you specify the
138 +b option. If you use +b, only the path list specified by +b is
139 in the embedded path.
141 The +nodefaultrpath option removes all library paths that were
142 specified with the -L option from the embedded path. The linker
143 searches the library paths specified by the -L option at link
144 time. At run time, the only library paths searched are those
145 specified by the environment variables LD_LIBRARY_PATH and
146 SHLIB_PATH, library paths specified by the +b linker option, and
147 finally the default library paths.
149 +rpathfirst
150 This option will cause the paths specified in RPATH (embedded
151 path) to be used before the paths specified in LD_LIBRARY_PATH
152 or SHLIB_PATH, in searching for shared libraries. This changes
153 the default search order of LD_LIBRARY_PATH, SHLIB_PATH, and
154 RPATH (embedded path).
156 ------------------------------------------------------------------------------
157 Notes about dependent (transitive) shared libraries:
159 On non-Windows systems shared libraries may have transitive
160 dependencies. In order to support LINK_INTERFACE_LIBRARIES we must
161 support linking to a shared library without listing all the libraries
162 to which it links. Some linkers want to be able to find the
163 transitive dependencies (dependent libraries) of shared libraries
164 listed on the command line.
166 - On Windows, DLLs are not directly linked, and the import libraries
167 have no transitive dependencies.
169 - On Mac, we need to actually list the transitive dependencies.
170 Otherwise when using -isysroot for universal binaries it cannot
171 find the dependent libraries. Listing them on the command line
172 tells the linker where to find them, but unfortunately also links
173 the library.
175 - On HP-UX, the linker wants to find the transitive dependencies of
176 shared libraries in the -L paths even if the dependent libraries
177 are given on the link line.
179 - On AIX the transitive dependencies are not needed.
181 - On SGI, the linker wants to find the transitive dependencies of
182 shared libraries in the -L paths if they are not given on the link
183 line. Transitive linking can be disabled using the options
185 -no_transitive_link -Wl,-no_transitive_link
187 which disable it. Both options must be given when invoking the
188 linker through the compiler.
190 - On Sun, the linker wants to find the transitive dependencies of
191 shared libraries in the -L paths if they are not given on the link
192 line.
194 - On Linux, FreeBSD, and QNX:
196 The linker wants to find the transitive dependencies of shared
197 libraries in the "-rpath-link" paths option if they have not been
198 given on the link line. The option is like rpath but just for
199 link time:
201 -Wl,-rpath-link,"/path1:/path2"
203 For -rpath-link, we need a separate runtime path ordering pass
204 including just the dependent libraries that are not linked.
206 For -L paths on non-HP, we can do the same thing as with rpath-link
207 but put the results in -L paths. The paths should be listed at the
208 end to avoid conflicting with user search paths (?).
210 For -L paths on HP, we should do a runtime path ordering pass with
211 all libraries, both linked and non-linked. Even dependent
212 libraries that are also linked need to be listed in -L paths.
214 In our implementation we add all dependent libraries to the runtime
215 path computation. Then the auto-generated RPATH will find everything.
217 ------------------------------------------------------------------------------
218 Notes about shared libraries with not builtin soname:
220 Some UNIX shared libraries may be created with no builtin soname. On
221 some platforms such libraries cannot be linked using the path to their
222 location because the linker will copy the path into the field used to
223 find the library at runtime.
225 Apple: ../libfoo.dylib ==> libfoo.dylib # ok, uses install_name
226 SGI: ../libfoo.so ==> libfoo.so # ok
227 AIX: ../libfoo.so ==> libfoo.so # ok
228 Linux: ../libfoo.so ==> ../libfoo.so # bad
229 HP-UX: ../libfoo.so ==> ../libfoo.so # bad
230 Sun: ../libfoo.so ==> ../libfoo.so # bad
231 FreeBSD: ../libfoo.so ==> ../libfoo.so # bad
233 In order to link these libraries we need to use the old-style split
234 into -L.. and -lfoo options. This should be fairly safe because most
235 problems with -lfoo options were related to selecting shared libraries
236 instead of static but in this case we want the shared lib. Link
237 directory ordering needs to be done to make sure these shared
238 libraries are found first. There should be very few restrictions
239 because this need be done only for shared libraries without soname-s.
243 //----------------------------------------------------------------------------
244 cmComputeLinkInformation
245 ::cmComputeLinkInformation(cmTarget* target, const char* config)
247 // Store context information.
248 this->Target = target;
249 this->Makefile = this->Target->GetMakefile();
250 this->LocalGenerator = this->Makefile->GetLocalGenerator();
251 this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
252 this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
254 // The configuration being linked.
255 this->Config = config;
257 // Allocate internals.
258 this->OrderLinkerSearchPath =
259 new cmOrderDirectories(this->GlobalGenerator, target->GetName(),
260 "linker search path");
261 this->OrderRuntimeSearchPath =
262 new cmOrderDirectories(this->GlobalGenerator, target->GetName(),
263 "runtime search path");
264 this->OrderDependentRPath = 0;
266 // Get the language used for linking this target.
267 this->LinkLanguage =
268 this->Target->GetLinkerLanguage(this->GlobalGenerator);
269 if(!this->LinkLanguage)
271 // The Compute method will do nothing, so skip the rest of the
272 // initialization.
273 return;
276 // Check whether we should use an import library for linking a target.
277 this->UseImportLibrary =
278 this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
280 // On platforms without import libraries there may be a special flag
281 // to use when creating a plugin (module) that obtains symbols from
282 // the program that will load it.
283 this->LoaderFlag = 0;
284 if(!this->UseImportLibrary &&
285 this->Target->GetType() == cmTarget::MODULE_LIBRARY)
287 std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
288 loader_flag_var += this->LinkLanguage;
289 loader_flag_var += "_FLAG";
290 this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var.c_str());
293 // Get options needed to link libraries.
294 this->LibLinkFlag =
295 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
296 this->LibLinkFileFlag =
297 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
298 this->LibLinkSuffix =
299 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
301 // Get options needed to specify RPATHs.
302 this->RuntimeUseChrpath = false;
303 if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
305 const char* tType =
306 ((this->Target->GetType() == cmTarget::EXECUTABLE)?
307 "EXECUTABLE" : "SHARED_LIBRARY");
308 std::string rtVar = "CMAKE_";
309 rtVar += tType;
310 rtVar += "_RUNTIME_";
311 rtVar += this->LinkLanguage;
312 rtVar += "_FLAG";
313 std::string rtSepVar = rtVar + "_SEP";
314 this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar.c_str());
315 this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar.c_str());
316 this->RuntimeAlways =
317 (this->Makefile->
318 GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
319 this->RuntimeUseChrpath = this->Target->IsChrpathUsed();
321 // Get options needed to help find dependent libraries.
322 std::string rlVar = "CMAKE_";
323 rlVar += tType;
324 rlVar += "_RPATH_LINK_";
325 rlVar += this->LinkLanguage;
326 rlVar += "_FLAG";
327 this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar.c_str());
330 // Check if we need to include the runtime search path at link time.
332 std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
333 var += this->LinkLanguage;
334 var += "_WITH_RUNTIME_PATH";
335 this->LinkWithRuntimePath = this->Makefile->IsOn(var.c_str());
338 // Check the platform policy for missing soname case.
339 this->NoSONameUsesPath =
340 this->Makefile->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
342 // Get link type information.
343 this->ComputeLinkTypeInfo();
345 // Setup the link item parser.
346 this->ComputeItemParserInfo();
348 // Setup framework support.
349 this->ComputeFrameworkInfo();
351 // Choose a mode for dealing with shared library dependencies.
352 this->SharedDependencyMode = SharedDepModeNone;
353 if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES"))
355 this->SharedDependencyMode = SharedDepModeLink;
357 else if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS"))
359 this->SharedDependencyMode = SharedDepModeLibDir;
361 else if(!this->RPathLinkFlag.empty())
363 this->SharedDependencyMode = SharedDepModeDir;
364 this->OrderDependentRPath =
365 new cmOrderDirectories(this->GlobalGenerator, target->GetName(),
366 "dependent library path");
369 // Get the implicit link directories for this platform.
370 if(const char* implicitLinks =
371 (this->Makefile->GetDefinition
372 ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
374 std::vector<std::string> implicitLinkVec;
375 cmSystemTools::ExpandListArgument(implicitLinks, implicitLinkVec);
376 for(std::vector<std::string>::const_iterator
377 i = implicitLinkVec.begin();
378 i != implicitLinkVec.end(); ++i)
380 this->ImplicitLinkDirs.insert(*i);
384 // Add the search path entries requested by the user to path ordering.
385 this->OrderLinkerSearchPath
386 ->AddUserDirectories(this->Target->GetLinkDirectories());
387 this->OrderRuntimeSearchPath
388 ->AddUserDirectories(this->Target->GetLinkDirectories());
389 this->OrderLinkerSearchPath
390 ->SetImplicitDirectories(this->ImplicitLinkDirs);
391 this->OrderRuntimeSearchPath
392 ->SetImplicitDirectories(this->ImplicitLinkDirs);
393 if(this->OrderDependentRPath)
395 this->OrderDependentRPath
396 ->SetImplicitDirectories(this->ImplicitLinkDirs);
399 // Decide whether to enable compatible library search path mode.
400 // There exists code that effectively does
402 // /path/to/libA.so -lB
404 // where -lB is meant to link to /path/to/libB.so. This is broken
405 // because it specified -lB without specifying a link directory (-L)
406 // in which to search for B. This worked in CMake 2.4 and below
407 // because -L/path/to would be added by the -L/-l split for A. In
408 // order to support such projects we need to add the directories
409 // containing libraries linked with a full path to the -L path.
410 this->OldLinkDirMode =
411 this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
412 if(this->OldLinkDirMode)
414 // Construct a mask to not bother with this behavior for link
415 // directories already specified by the user.
416 std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
417 for(std::vector<std::string>::const_iterator di = dirs.begin();
418 di != dirs.end(); ++di)
420 this->OldLinkDirMask.insert(*di);
425 //----------------------------------------------------------------------------
426 cmComputeLinkInformation::~cmComputeLinkInformation()
428 delete this->OrderLinkerSearchPath;
429 delete this->OrderRuntimeSearchPath;
430 delete this->OrderDependentRPath;
433 //----------------------------------------------------------------------------
434 cmComputeLinkInformation::ItemVector const&
435 cmComputeLinkInformation::GetItems()
437 return this->Items;
440 //----------------------------------------------------------------------------
441 std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
443 return this->OrderLinkerSearchPath->GetOrderedDirectories();
446 //----------------------------------------------------------------------------
447 std::string cmComputeLinkInformation::GetRPathLinkString()
449 // If there is no separate linker runtime search flag (-rpath-link)
450 // there is no reason to compute a string.
451 if(!this->OrderDependentRPath)
453 return "";
456 // Construct the linker runtime search path.
457 std::string rpath_link;
458 const char* sep = "";
459 std::vector<std::string> const& dirs =
460 this->OrderDependentRPath->GetOrderedDirectories();
461 for(std::vector<std::string>::const_iterator di = dirs.begin();
462 di != dirs.end(); ++di)
464 rpath_link += sep;
465 sep = ":";
466 rpath_link += *di;
468 return rpath_link;
471 //----------------------------------------------------------------------------
472 std::vector<std::string> const& cmComputeLinkInformation::GetDepends()
474 return this->Depends;
477 //----------------------------------------------------------------------------
478 std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
480 return this->FrameworkPaths;
483 //----------------------------------------------------------------------------
484 std::set<cmTarget*> const&
485 cmComputeLinkInformation::GetSharedLibrariesLinked()
487 return this->SharedLibrariesLinked;
490 //----------------------------------------------------------------------------
491 bool cmComputeLinkInformation::Compute()
493 // Skip targets that do not link.
494 if(!(this->Target->GetType() == cmTarget::EXECUTABLE ||
495 this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
496 this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
497 this->Target->GetType() == cmTarget::STATIC_LIBRARY))
499 return false;
502 // We require a link language for the target.
503 if(!this->LinkLanguage)
505 cmSystemTools::
506 Error("CMake can not determine linker language for target:",
507 this->Target->GetName());
508 return false;
511 // Compute the ordered link line items.
512 cmComputeLinkDepends cld(this->Target, this->Config);
513 cld.SetOldLinkDirMode(this->OldLinkDirMode);
514 cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
516 // Add the link line items.
517 for(cmComputeLinkDepends::EntryVector::const_iterator
518 lei = linkEntries.begin();
519 lei != linkEntries.end(); ++lei)
521 if(lei->IsSharedDep)
523 this->AddSharedDepItem(lei->Item, lei->Target);
525 else
527 this->AddItem(lei->Item, lei->Target);
531 // Restore the target link type so the correct system runtime
532 // libraries are found.
533 const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
534 if(cmSystemTools::IsOn(lss))
536 this->SetCurrentLinkType(LinkStatic);
538 else
540 this->SetCurrentLinkType(this->StartLinkType);
543 // Finish listing compatibility paths.
544 if(this->OldLinkDirMode)
546 // For CMake 2.4 bug-compatibility we need to consider the output
547 // directories of targets linked in another configuration as link
548 // directories.
549 std::set<cmTarget*> const& wrongItems = cld.GetOldWrongConfigItems();
550 for(std::set<cmTarget*>::const_iterator i = wrongItems.begin();
551 i != wrongItems.end(); ++i)
553 cmTarget* tgt = *i;
554 bool implib =
555 (this->UseImportLibrary &&
556 (tgt->GetType() == cmTarget::SHARED_LIBRARY));
557 std::string lib = tgt->GetFullPath(this->Config , implib, true);
558 this->OldLinkDirItems.push_back(lib);
562 // Finish setting up linker search directories.
563 if(!this->FinishLinkerSearchDirectories())
565 return false;
568 return true;
571 //----------------------------------------------------------------------------
572 void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
574 // Compute the proper name to use to link this library.
575 const char* config = this->Config;
576 bool impexe = (tgt && tgt->IsExecutableWithExports());
577 if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
579 // Skip linking to executables on platforms with no import
580 // libraries or loader flags.
581 return;
584 if(tgt && (tgt->GetType() == cmTarget::STATIC_LIBRARY ||
585 tgt->GetType() == cmTarget::SHARED_LIBRARY ||
586 tgt->GetType() == cmTarget::MODULE_LIBRARY ||
587 impexe))
589 // This is a CMake target. Ask the target for its real name.
590 if(impexe && this->LoaderFlag)
592 // This link item is an executable that may provide symbols
593 // used by this target. A special flag is needed on this
594 // platform. Add it now.
595 std::string linkItem;
596 linkItem = this->LoaderFlag;
597 std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
598 true);
599 linkItem += exe;
600 this->Items.push_back(Item(linkItem, true));
601 this->Depends.push_back(exe);
603 else
605 // Decide whether to use an import library.
606 bool implib =
607 (this->UseImportLibrary &&
608 (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
610 // Pass the full path to the target file.
611 std::string lib = tgt->GetFullPath(config, implib, true);
612 this->Depends.push_back(lib);
614 if(tgt->IsFrameworkOnApple())
616 // Frameworks on OS X need only the framework directory to
617 // link.
618 std::string fw = tgt->GetDirectory(config, implib);
619 this->AddFrameworkItem(fw);
621 else
623 this->AddTargetItem(lib, tgt);
624 this->AddLibraryRuntimeInfo(lib, tgt);
628 else
630 // This is not a CMake target. Use the name given.
631 if(cmSystemTools::FileIsFullPath(item.c_str()))
633 if(cmSystemTools::FileIsDirectory(item.c_str()))
635 // This is a directory.
636 this->AddDirectoryItem(item);
638 else
640 // Use the full path given to the library file.
641 this->Depends.push_back(item);
642 this->AddFullItem(item);
643 this->AddLibraryRuntimeInfo(item);
646 else
648 // This is a library or option specified by the user.
649 this->AddUserItem(item);
654 //----------------------------------------------------------------------------
655 void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
656 cmTarget* tgt)
658 // If dropping shared library dependencies, ignore them.
659 if(this->SharedDependencyMode == SharedDepModeNone)
661 return;
664 // The user may have incorrectly named an item. Skip items that are
665 // not full paths to shared libraries.
666 if(tgt)
668 // The target will provide a full path. Make sure it is a shared
669 // library.
670 if(tgt->GetType() != cmTarget::SHARED_LIBRARY)
672 return;
675 else
677 // Skip items that are not full paths. We will not be able to
678 // reliably specify them.
679 if(!cmSystemTools::FileIsFullPath(item.c_str()))
681 return;
684 // Get the name of the library from the file name.
685 std::string file = cmSystemTools::GetFilenameName(item);
686 if(!this->ExtractSharedLibraryName.find(file.c_str()))
688 // This is not the name of a shared library.
689 return;
693 // If in linking mode, just link to the shared library.
694 if(this->SharedDependencyMode == SharedDepModeLink)
696 this->AddItem(item, tgt);
697 return;
700 // Get a full path to the dependent shared library.
701 // Add it to the runtime path computation so that the target being
702 // linked will be able to find it.
703 std::string lib;
704 if(tgt)
706 lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
707 this->AddLibraryRuntimeInfo(lib, tgt);
709 else
711 lib = item;
712 this->AddLibraryRuntimeInfo(lib);
715 // Check if we need to include the dependent shared library in other
716 // path ordering.
717 cmOrderDirectories* order = 0;
718 if(this->SharedDependencyMode == SharedDepModeLibDir &&
719 !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */)
721 // Add the item to the linker search path.
722 order = this->OrderLinkerSearchPath;
724 else if(this->SharedDependencyMode == SharedDepModeDir)
726 // Add the item to the separate dependent library search path.
727 order = this->OrderDependentRPath;
729 if(order)
731 if(tgt)
733 std::string soName = tgt->GetSOName(this->Config);
734 const char* soname = soName.empty()? 0 : soName.c_str();
735 order->AddRuntimeLibrary(lib, soname);
737 else
739 order->AddRuntimeLibrary(lib);
744 //----------------------------------------------------------------------------
745 void cmComputeLinkInformation::ComputeLinkTypeInfo()
747 // Check whether archives may actually be shared libraries.
748 this->ArchivesMayBeShared =
749 this->CMakeInstance->GetPropertyAsBool(
750 "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
752 // First assume we cannot do link type stuff.
753 this->LinkTypeEnabled = false;
755 // Lookup link type selection flags.
756 const char* static_link_type_flag = 0;
757 const char* shared_link_type_flag = 0;
758 const char* target_type_str = 0;
759 switch(this->Target->GetType())
761 case cmTarget::EXECUTABLE: target_type_str = "EXE"; break;
762 case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
763 case cmTarget::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
764 default: break;
766 if(target_type_str)
768 std::string static_link_type_flag_var = "CMAKE_";
769 static_link_type_flag_var += target_type_str;
770 static_link_type_flag_var += "_LINK_STATIC_";
771 static_link_type_flag_var += this->LinkLanguage;
772 static_link_type_flag_var += "_FLAGS";
773 static_link_type_flag =
774 this->Makefile->GetDefinition(static_link_type_flag_var.c_str());
776 std::string shared_link_type_flag_var = "CMAKE_";
777 shared_link_type_flag_var += target_type_str;
778 shared_link_type_flag_var += "_LINK_DYNAMIC_";
779 shared_link_type_flag_var += this->LinkLanguage;
780 shared_link_type_flag_var += "_FLAGS";
781 shared_link_type_flag =
782 this->Makefile->GetDefinition(shared_link_type_flag_var.c_str());
785 // We can support link type switching only if all needed flags are
786 // known.
787 if(static_link_type_flag && *static_link_type_flag &&
788 shared_link_type_flag && *shared_link_type_flag)
790 this->LinkTypeEnabled = true;
791 this->StaticLinkTypeFlag = static_link_type_flag;
792 this->SharedLinkTypeFlag = shared_link_type_flag;
795 // TODO: Lookup the starting link type from the target (is it being
796 // linked statically?).
797 this->StartLinkType = LinkShared;
798 this->CurrentLinkType = this->StartLinkType;
801 //----------------------------------------------------------------------------
802 void cmComputeLinkInformation::ComputeItemParserInfo()
804 // Get possible library name prefixes.
805 cmMakefile* mf = this->Makefile;
806 this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
807 this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
809 // Import library names should be matched and treated as shared
810 // libraries for the purposes of linking.
811 this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
812 LinkShared);
813 this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
814 LinkStatic);
815 this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
816 LinkShared);
817 this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
818 LinkUnknown);
819 if(const char* linkSuffixes =
820 mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
822 std::vector<std::string> linkSuffixVec;
823 cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
824 for(std::vector<std::string>::iterator i = linkSuffixVec.begin();
825 i != linkSuffixVec.end(); ++i)
827 this->AddLinkExtension(i->c_str(), LinkUnknown);
831 // Compute a regex to match link extensions.
832 std::string libext = this->CreateExtensionRegex(this->LinkExtensions);
834 // Create regex to remove any library extension.
835 std::string reg("(.*)");
836 reg += libext;
837 this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
838 reg);
840 // Create a regex to match a library name. Match index 1 will be
841 // the prefix if it exists and empty otherwise. Match index 2 will
842 // be the library name. Match index 3 will be the library
843 // extension.
844 reg = "^(";
845 for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
846 p != this->LinkPrefixes.end(); ++p)
848 reg += *p;
849 reg += "|";
851 reg += ")";
852 reg += "([^/]*)";
854 // Create a regex to match any library name.
855 std::string reg_any = reg;
856 reg_any += libext;
857 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
858 fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
859 #endif
860 this->ExtractAnyLibraryName.compile(reg_any.c_str());
862 // Create a regex to match static library names.
863 if(!this->StaticLinkExtensions.empty())
865 std::string reg_static = reg;
866 reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
867 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
868 fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
869 #endif
870 this->ExtractStaticLibraryName.compile(reg_static.c_str());
873 // Create a regex to match shared library names.
874 if(!this->SharedLinkExtensions.empty())
876 std::string reg_shared = reg;
877 reg_shared += this->CreateExtensionRegex(this->SharedLinkExtensions);
878 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
879 fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
880 #endif
881 this->ExtractSharedLibraryName.compile(reg_shared.c_str());
885 //----------------------------------------------------------------------------
886 void cmComputeLinkInformation::AddLinkPrefix(const char* p)
888 if(p)
890 this->LinkPrefixes.insert(p);
894 //----------------------------------------------------------------------------
895 void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
897 if(e && *e)
899 if(type == LinkStatic)
901 this->StaticLinkExtensions.push_back(e);
903 if(type == LinkShared)
905 this->SharedLinkExtensions.push_back(e);
907 this->LinkExtensions.push_back(e);
911 //----------------------------------------------------------------------------
912 std::string
913 cmComputeLinkInformation
914 ::CreateExtensionRegex(std::vector<std::string> const& exts)
916 // Build a list of extension choices.
917 std::string libext = "(";
918 const char* sep = "";
919 for(std::vector<std::string>::const_iterator i = exts.begin();
920 i != exts.end(); ++i)
922 // Separate this choice from the previous one.
923 libext += sep;
924 sep = "|";
926 // Store this extension choice with the "." escaped.
927 libext += "\\";
928 #if defined(_WIN32) && !defined(__CYGWIN__)
929 libext += this->NoCaseExpression(i->c_str());
930 #else
931 libext += *i;
932 #endif
935 // Finish the list.
936 libext += ")$";
937 return libext;
940 //----------------------------------------------------------------------------
941 std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
943 std::string ret;
944 const char* s = str;
945 while(*s)
947 if(*s == '.')
949 ret += *s;
951 else
953 ret += "[";
954 ret += tolower(*s);
955 ret += toupper(*s);
956 ret += "]";
958 s++;
960 return ret;
963 //-------------------------------------------------------------------
964 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
966 // If we are changing the current link type add the flag to tell the
967 // linker about it.
968 if(this->CurrentLinkType != lt)
970 this->CurrentLinkType = lt;
972 if(this->LinkTypeEnabled)
974 switch(this->CurrentLinkType)
976 case LinkStatic:
977 this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
978 break;
979 case LinkShared:
980 this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
981 break;
982 default:
983 break;
989 //----------------------------------------------------------------------------
990 void cmComputeLinkInformation::AddTargetItem(std::string const& item,
991 cmTarget* target)
993 // This is called to handle a link item that is a full path to a target.
994 // If the target is not a static library make sure the link type is
995 // shared. This is because dynamic-mode linking can handle both
996 // shared and static libraries but static-mode can handle only
997 // static libraries. If a previous user item changed the link type
998 // to static we need to make sure it is back to shared.
999 if(target->GetType() != cmTarget::STATIC_LIBRARY)
1001 this->SetCurrentLinkType(LinkShared);
1004 // Keep track of shared library targets linked.
1005 if(target->GetType() == cmTarget::SHARED_LIBRARY)
1007 this->SharedLibrariesLinked.insert(target);
1010 // Handle case of an imported shared library with no soname.
1011 if(this->NoSONameUsesPath &&
1012 target->IsImportedSharedLibWithoutSOName(this->Config))
1014 this->AddSharedLibNoSOName(item);
1015 return;
1018 // If this platform wants a flag before the full path, add it.
1019 if(!this->LibLinkFileFlag.empty())
1021 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1024 // For compatibility with CMake 2.4 include the item's directory in
1025 // the linker search path.
1026 if(this->OldLinkDirMode &&
1027 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1028 this->OldLinkDirMask.end())
1030 this->OldLinkDirItems.push_back(item);
1033 // Now add the full path to the library.
1034 this->Items.push_back(Item(item, true));
1037 //----------------------------------------------------------------------------
1038 void cmComputeLinkInformation::AddFullItem(std::string const& item)
1040 // Check for the implicit link directory special case.
1041 if(this->CheckImplicitDirItem(item))
1043 return;
1046 // Check for case of shared library with no builtin soname.
1047 if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
1049 return;
1052 // This is called to handle a link item that is a full path.
1053 // If the target is not a static library make sure the link type is
1054 // shared. This is because dynamic-mode linking can handle both
1055 // shared and static libraries but static-mode can handle only
1056 // static libraries. If a previous user item changed the link type
1057 // to static we need to make sure it is back to shared.
1058 if(this->LinkTypeEnabled)
1060 std::string name = cmSystemTools::GetFilenameName(item);
1061 if(this->ExtractSharedLibraryName.find(name))
1063 this->SetCurrentLinkType(LinkShared);
1065 else if(!this->ExtractStaticLibraryName.find(item))
1067 // We cannot determine the type. Assume it is the target's
1068 // default type.
1069 this->SetCurrentLinkType(this->StartLinkType);
1073 // For compatibility with CMake 2.4 include the item's directory in
1074 // the linker search path.
1075 if(this->OldLinkDirMode &&
1076 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1077 this->OldLinkDirMask.end())
1079 this->OldLinkDirItems.push_back(item);
1082 // If this platform wants a flag before the full path, add it.
1083 if(!this->LibLinkFileFlag.empty())
1085 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1088 // Now add the full path to the library.
1089 this->Items.push_back(Item(item, true));
1092 //----------------------------------------------------------------------------
1093 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
1095 // We only switch to a pathless item if the link type may be
1096 // enforced. Fortunately only platforms that support link types
1097 // seem to have magic per-architecture implicit link directories.
1098 if(!this->LinkTypeEnabled)
1100 return false;
1103 // Check if this item is in an implicit link directory.
1104 std::string dir = cmSystemTools::GetFilenamePath(item);
1105 if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
1107 // Only libraries in implicit link directories are converted to
1108 // pathless items.
1109 return false;
1112 // Only apply the policy below if the library file is one that can
1113 // be found by the linker.
1114 std::string file = cmSystemTools::GetFilenameName(item);
1115 if(!this->ExtractAnyLibraryName.find(file))
1117 return false;
1120 // Many system linkers support multiple architectures by
1121 // automatically selecting the implicit linker search path for the
1122 // current architecture. If the library appears in an implicit link
1123 // directory then just report the file name without the directory
1124 // portion. This will allow the system linker to locate the proper
1125 // library for the architecture at link time.
1126 this->AddUserItem(file);
1127 return true;
1130 //----------------------------------------------------------------------------
1131 void cmComputeLinkInformation::AddUserItem(std::string const& item)
1133 // This is called to handle a link item that does not match a CMake
1134 // target and is not a full path. We check here if it looks like a
1135 // library file name to automatically request the proper link type
1136 // from the linker. For example:
1138 // foo ==> -lfoo
1139 // libfoo.a ==> -Wl,-Bstatic -lfoo
1140 std::string lib;
1142 // Parse out the prefix, base, and suffix components of the
1143 // library name. If the name matches that of a shared or static
1144 // library then set the link type accordingly.
1146 // Search for shared library names first because some platforms
1147 // have shared libraries with names that match the static library
1148 // pattern. For example cygwin and msys use the convention
1149 // libfoo.dll.a for import libraries and libfoo.a for static
1150 // libraries. On AIX a library with the name libfoo.a can be
1151 // shared!
1152 if(this->ExtractSharedLibraryName.find(item))
1154 // This matches a shared library file name.
1155 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1156 fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
1157 this->ExtractSharedLibraryName.match(1).c_str(),
1158 this->ExtractSharedLibraryName.match(2).c_str(),
1159 this->ExtractSharedLibraryName.match(3).c_str());
1160 #endif
1161 // Set the link type to shared.
1162 this->SetCurrentLinkType(LinkShared);
1164 // Use just the library name so the linker will search.
1165 lib = this->ExtractSharedLibraryName.match(2);
1167 else if(this->ExtractStaticLibraryName.find(item))
1169 // This matches a static library file name.
1170 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1171 fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
1172 this->ExtractStaticLibraryName.match(1).c_str(),
1173 this->ExtractStaticLibraryName.match(2).c_str(),
1174 this->ExtractStaticLibraryName.match(3).c_str());
1175 #endif
1176 // Set the link type to static.
1177 this->SetCurrentLinkType(LinkStatic);
1179 // Use just the library name so the linker will search.
1180 lib = this->ExtractStaticLibraryName.match(2);
1182 else if(this->ExtractAnyLibraryName.find(item))
1184 // This matches a library file name.
1185 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1186 fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
1187 this->ExtractAnyLibraryName.match(1).c_str(),
1188 this->ExtractAnyLibraryName.match(2).c_str(),
1189 this->ExtractAnyLibraryName.match(3).c_str());
1190 #endif
1191 // Restore the target link type since this item does not specify
1192 // one.
1193 this->SetCurrentLinkType(this->StartLinkType);
1195 // Use just the library name so the linker will search.
1196 lib = this->ExtractAnyLibraryName.match(2);
1198 else if(item[0] == '-' || item[0] == '$' || item[0] == '`')
1200 if(item.find("-framework") != 0)
1202 // This is a linker option provided by the user.
1203 this->OldUserFlagItems.push_back(item);
1206 // Restore the target link type since this item does not specify
1207 // one.
1208 this->SetCurrentLinkType(this->StartLinkType);
1210 // Use the item verbatim.
1211 this->Items.push_back(Item(item, false));
1212 return;
1214 else
1216 // This is a name specified by the user.
1217 this->OldUserFlagItems.push_back(item);
1219 // We must ask the linker to search for a library with this name.
1220 // Restore the target link type since this item does not specify
1221 // one.
1222 this->SetCurrentLinkType(this->StartLinkType);
1223 lib = item;
1226 // Create an option to ask the linker to search for the library.
1227 std::string out = this->LibLinkFlag;
1228 out += lib;
1229 out += this->LibLinkSuffix;
1230 this->Items.push_back(Item(out, false));
1232 // Here we could try to find the library the linker will find and
1233 // add a runtime information entry for it. It would probably not be
1234 // reliable and we want to encourage use of full paths for library
1235 // specification.
1238 //----------------------------------------------------------------------------
1239 void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
1241 // Try to separate the framework name and path.
1242 if(!this->SplitFramework.find(item.c_str()))
1244 cmOStringStream e;
1245 e << "Could not parse framework path \"" << item << "\" "
1246 << "linked by target " << this->Target->GetName() << ".";
1247 cmSystemTools::Error(e.str().c_str());
1248 return;
1251 // Add the directory portion to the framework search path.
1252 this->AddFrameworkPath(this->SplitFramework.match(1));
1254 // Add the item using the -framework option.
1255 std::string fw = "-framework ";
1256 fw += this->SplitFramework.match(2);
1257 this->Items.push_back(Item(fw, false));
1260 //----------------------------------------------------------------------------
1261 void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
1263 #ifdef __APPLE__
1264 if(cmSystemTools::IsPathToFramework(item.c_str()))
1266 this->AddFrameworkItem(item);
1268 else
1269 #endif
1271 this->DropDirectoryItem(item);
1275 //----------------------------------------------------------------------------
1276 void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
1278 // A full path to a directory was found as a link item. Warn the
1279 // user.
1280 cmOStringStream e;
1281 e << "WARNING: Target \"" << this->Target->GetName()
1282 << "\" requests linking to directory \"" << item << "\". "
1283 << "Targets may link only to libraries. "
1284 << "CMake is dropping the item.";
1285 cmSystemTools::Message(e.str().c_str());
1288 //----------------------------------------------------------------------------
1289 void cmComputeLinkInformation::ComputeFrameworkInfo()
1291 // Avoid adding system framework paths. See "man ld" on OS X.
1292 this->FrameworkPathsEmmitted.insert("/Library/Frameworks");
1293 this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks");
1294 this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks");
1296 // Regular expression to extract a framework path and name.
1297 this->SplitFramework.compile("(.*)/(.*)\\.framework$");
1300 //----------------------------------------------------------------------------
1301 void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
1303 if(this->FrameworkPathsEmmitted.insert(p).second)
1305 this->FrameworkPaths.push_back(p);
1309 //----------------------------------------------------------------------------
1310 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
1312 // This platform will use the path to a library as its soname if the
1313 // library is given via path and was not built with an soname. If
1314 // this is a shared library that might be the case.
1315 std::string file = cmSystemTools::GetFilenameName(item);
1316 if(this->ExtractSharedLibraryName.find(file))
1318 // If we can guess the soname fairly reliably then assume the
1319 // library has one. Otherwise assume the library has no builtin
1320 // soname.
1321 std::string soname;
1322 if(!cmSystemTools::GuessLibrarySOName(item, soname))
1324 this->AddSharedLibNoSOName(item);
1325 return true;
1328 return false;
1331 //----------------------------------------------------------------------------
1332 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
1334 // We have a full path to a shared library with no soname. We need
1335 // to ask the linker to locate the item because otherwise the path
1336 // we give to it will be embedded in the target linked. Then at
1337 // runtime the dynamic linker will search for the library using the
1338 // path instead of just the name.
1339 std::string file = cmSystemTools::GetFilenameName(item);
1340 this->AddUserItem(file);
1342 // Make sure the link directory ordering will find the library.
1343 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1346 //----------------------------------------------------------------------------
1347 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1349 // Support broken projects if necessary.
1350 if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
1351 !this->OldLinkDirMode)
1353 return true;
1356 // Enforce policy constraints.
1357 switch(this->Target->GetPolicyStatusCMP0003())
1359 case cmPolicies::WARN:
1360 if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1362 this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
1363 cmOStringStream w;
1364 this->PrintLinkPolicyDiagnosis(w);
1365 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1366 this->Target->GetBacktrace());
1368 case cmPolicies::OLD:
1369 // OLD behavior is to add the paths containing libraries with
1370 // known full paths as link directories.
1371 break;
1372 case cmPolicies::NEW:
1373 // Should never happen due to assignment of OldLinkDirMode
1374 return true;
1375 case cmPolicies::REQUIRED_IF_USED:
1376 case cmPolicies::REQUIRED_ALWAYS:
1378 cmOStringStream e;
1379 e << (this->Makefile->GetPolicies()->
1380 GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
1381 this->PrintLinkPolicyDiagnosis(e);
1382 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1383 this->Target->GetBacktrace());
1384 return false;
1388 // Add the link directories for full path items.
1389 for(std::vector<std::string>::const_iterator
1390 i = this->OldLinkDirItems.begin();
1391 i != this->OldLinkDirItems.end(); ++i)
1393 this->OrderLinkerSearchPath->AddLinkLibrary(*i);
1395 return true;
1398 //----------------------------------------------------------------------------
1399 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
1401 // Tell the user what to do.
1402 os << "Policy CMP0003 should be set before this line. "
1403 << "Add code such as\n"
1404 << " if(COMMAND cmake_policy)\n"
1405 << " cmake_policy(SET CMP0003 NEW)\n"
1406 << " endif(COMMAND cmake_policy)\n"
1407 << "as early as possible but after the most recent call to "
1408 << "cmake_minimum_required or cmake_policy(VERSION). ";
1410 // List the items that might need the old-style paths.
1411 os << "This warning appears because target \""
1412 << this->Target->GetName() << "\" "
1413 << "links to some libraries for which the linker must search:\n";
1415 // Format the list of unknown items to be as short as possible while
1416 // still fitting in the allowed width (a true solution would be the
1417 // bin packing problem if we were allowed to change the order).
1418 std::string::size_type max_size = 76;
1419 std::string line;
1420 const char* sep = " ";
1421 for(std::vector<std::string>::const_iterator
1422 i = this->OldUserFlagItems.begin();
1423 i != this->OldUserFlagItems.end(); ++i)
1425 // If the addition of another item will exceed the limit then
1426 // output the current line and reset it. Note that the separator
1427 // is either " " or ", " which is always 2 characters.
1428 if(!line.empty() && (line.size() + i->size() + 2) > max_size)
1430 os << line << "\n";
1431 sep = " ";
1432 line = "";
1434 line += sep;
1435 line += *i;
1436 // Convert to the other separator.
1437 sep = ", ";
1439 if(!line.empty())
1441 os << line << "\n";
1445 // List the paths old behavior is adding.
1446 os << "and other libraries with known full path:\n";
1447 std::set<cmStdString> emitted;
1448 for(std::vector<std::string>::const_iterator
1449 i = this->OldLinkDirItems.begin();
1450 i != this->OldLinkDirItems.end(); ++i)
1452 if(emitted.insert(cmSystemTools::GetFilenamePath(*i)).second)
1454 os << " " << *i << "\n";
1458 // Explain.
1459 os << "CMake is adding directories in the second list to the linker "
1460 << "search path in case they are needed to find libraries from the "
1461 << "first list (for backwards compatibility with CMake 2.4). "
1462 << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1463 << "behavior explicitly. "
1464 << "Run \"cmake --help-policy CMP0003\" for more information.";
1467 //----------------------------------------------------------------------------
1468 std::vector<std::string> const&
1469 cmComputeLinkInformation::GetRuntimeSearchPath()
1471 return this->OrderRuntimeSearchPath->GetOrderedDirectories();
1474 //----------------------------------------------------------------------------
1475 void
1476 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
1477 cmTarget* target)
1479 // Skip targets that are not shared libraries (modules cannot be linked).
1480 if(target->GetType() != cmTarget::SHARED_LIBRARY)
1482 return;
1485 // Try to get the soname of the library. Only files with this name
1486 // could possibly conflict.
1487 std::string soName = target->GetSOName(this->Config);
1488 const char* soname = soName.empty()? 0 : soName.c_str();
1490 // Include this library in the runtime path ordering.
1491 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
1492 if(this->LinkWithRuntimePath)
1494 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
1498 //----------------------------------------------------------------------------
1499 void
1500 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
1502 // Get the name of the library from the file name.
1503 std::string file = cmSystemTools::GetFilenameName(fullPath);
1504 if(!this->ExtractSharedLibraryName.find(file.c_str()))
1506 // On some platforms (AIX) a shared library may look static.
1507 if(this->ArchivesMayBeShared)
1509 if(!this->ExtractStaticLibraryName.find(file.c_str()))
1511 // This is not the name of a shared library or archive.
1512 return;
1515 else
1517 // This is not the name of a shared library.
1518 return;
1522 // Include this library in the runtime path ordering.
1523 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
1524 if(this->LinkWithRuntimePath)
1526 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
1530 //----------------------------------------------------------------------------
1531 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
1532 bool for_install)
1534 // Select whether to generate runtime search directories.
1535 bool outputRuntime =
1536 !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
1538 // Select whether to generate an rpath for the install tree or the
1539 // build tree.
1540 bool linking_for_install =
1541 (for_install ||
1542 this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1543 bool use_install_rpath =
1544 (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
1545 linking_for_install);
1546 bool use_build_rpath =
1547 (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
1548 !linking_for_install);
1549 bool use_link_rpath =
1550 outputRuntime && linking_for_install &&
1551 this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1553 // Construct the RPATH.
1554 if(use_install_rpath)
1556 const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
1557 cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
1559 if(use_build_rpath || use_link_rpath)
1561 std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
1562 for(std::vector<std::string>::const_iterator ri = rdirs.begin();
1563 ri != rdirs.end(); ++ri)
1565 // Put this directory in the rpath if using build-tree rpath
1566 // support or if using the link path as an rpath.
1567 if(use_build_rpath)
1569 runtimeDirs.push_back(*ri);
1571 else if(use_link_rpath)
1573 // Do not add any path inside the source or build tree.
1574 const char* topSourceDir = this->Makefile->GetHomeDirectory();
1575 const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
1576 if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
1577 !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
1578 !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
1579 !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
1581 runtimeDirs.push_back(*ri);
1587 // Add runtime paths required by the platform to always be
1588 // present. This is done even when skipping rpath support.
1589 cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs);
1592 //----------------------------------------------------------------------------
1593 std::string cmComputeLinkInformation::GetRPathString(bool for_install)
1595 // Get the directories to use.
1596 std::vector<std::string> runtimeDirs;
1597 this->GetRPath(runtimeDirs, for_install);
1599 // Concatenate the paths.
1600 std::string rpath;
1601 const char* sep = "";
1602 for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
1603 ri != runtimeDirs.end(); ++ri)
1605 // Separate from previous path.
1606 rpath += sep;
1607 sep = this->GetRuntimeSep().c_str();
1609 // Add this path.
1610 rpath += *ri;
1613 // If the rpath will be replaced at install time make sure it is
1614 // long enough now.
1615 if(!for_install && this->RuntimeUseChrpath)
1617 std::string::size_type minLength = this->GetChrpathString().length();
1618 while(rpath.length() < minLength)
1620 rpath += this->GetRuntimeSep();
1624 return rpath;
1627 //----------------------------------------------------------------------------
1628 std::string cmComputeLinkInformation::GetChrpathString()
1630 if(!this->RuntimeUseChrpath)
1632 return "";
1635 return this->GetRPathString(true);