1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
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"
14 #include "cmComputeLinkDepends.h"
15 #include "cmOrderDirectories.h"
17 #include "cmGlobalGenerator.h"
18 #include "cmLocalGenerator.h"
19 #include "cmMakefile.h"
25 //#define CM_COMPUTE_LINK_INFO_DEBUG
28 Notes about linking on various platforms:
30 ------------------------------------------------------------------------------
32 Linux, FreeBSD, Mac OS X, IRIX, Sun, Windows:
34 Linking to libraries using the full path works fine.
36 ------------------------------------------------------------------------------
38 On AIX, more work is needed.
40 The "-bnoipath" option is needed. From "man ld":
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
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.
60 This prevents the full path specified on the compile line from being
61 compiled directly into the binary.
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":
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
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,
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.
86 ------------------------------------------------------------------------------
88 On HP-UX, more work is needed. There are differences between
91 ld: 92453-07 linker linker ld B.10.33 990520
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.
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
102 ld: 92453-07 linker ld HP Itanium(R) B.12.41 IPF/IPF
104 Linking with a full path works okay for static libraries.
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
115 /dir/with/bar/libbar.sl -L/dir/with/foo
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
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.
127 See documentation in "man ld", "man dld.so", and
128 http://docs.hp.com/en/B2355-90968/creatingandusinglibraries.htm
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.
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.
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).
151 ------------------------------------------------------------------------------
152 Notes about dependent (transitive) shared libraries:
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.
161 - On Windows, DLLs are not directly linked, and the import libraries
162 have no transitive dependencies.
164 - On Mac OS X 10.5 and above transitive dependencies are not needed.
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
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.
176 - On AIX the transitive dependencies are not needed.
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
182 -no_transitive_link -Wl,-no_transitive_link
184 which disable it. Both options must be given when invoking the
185 linker through the compiler.
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
191 - On Linux, FreeBSD, and QNX:
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
198 -Wl,-rpath-link,"/path1:/path2"
200 For -rpath-link, we need a separate runtime path ordering pass
201 including just the dependent libraries that are not linked.
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 (?).
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.
211 In our implementation we add all dependent libraries to the runtime
212 path computation. Then the auto-generated RPATH will find everything.
214 ------------------------------------------------------------------------------
215 Notes about shared libraries with not builtin soname:
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.
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
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.
240 //----------------------------------------------------------------------------
241 cmComputeLinkInformation
242 ::cmComputeLinkInformation(cmTarget* target, const char* config)
244 // Store context information.
245 this->Target = target;
246 this->Makefile = this->Target->GetMakefile();
247 this->LocalGenerator = this->Makefile->GetLocalGenerator();
248 this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
249 this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
251 // Check whether to recognize OpenBSD-style library versioned names.
252 this->OpenBSD = this->Makefile->GetCMakeInstance()
253 ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
255 // The configuration being linked.
256 this->Config = config;
258 // Allocate internals.
259 this->OrderLinkerSearchPath =
260 new cmOrderDirectories(this->GlobalGenerator, target,
261 "linker search path");
262 this->OrderRuntimeSearchPath =
263 new cmOrderDirectories(this->GlobalGenerator, target,
264 "runtime search path");
265 this->OrderDependentRPath = 0;
267 // Get the language used for linking this target.
268 this->LinkLanguage = this->Target->GetLinkerLanguage(config);
269 if(!this->LinkLanguage)
271 // The Compute method will do nothing, so skip the rest of the
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.
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)
306 ((this->Target->GetType() == cmTarget::EXECUTABLE)?
307 "EXECUTABLE" : "SHARED_LIBRARY");
308 std::string rtVar = "CMAKE_";
310 rtVar += "_RUNTIME_";
311 rtVar += this->LinkLanguage;
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 =
318 GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
319 this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);
321 // Get options needed to help find dependent libraries.
322 std::string rlVar = "CMAKE_";
324 rlVar += "_RPATH_LINK_";
325 rlVar += this->LinkLanguage;
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,
366 "dependent library path");
369 // Add the search path entries requested by the user to path ordering.
370 this->OrderLinkerSearchPath
371 ->AddUserDirectories(this->Target->GetLinkDirectories());
372 this->OrderRuntimeSearchPath
373 ->AddUserDirectories(this->Target->GetLinkDirectories());
375 // Set up the implicit link directories.
376 this->LoadImplicitLinkInfo();
377 this->OrderLinkerSearchPath
378 ->SetImplicitDirectories(this->ImplicitLinkDirs);
379 this->OrderRuntimeSearchPath
380 ->SetImplicitDirectories(this->ImplicitLinkDirs);
381 if(this->OrderDependentRPath)
383 this->OrderDependentRPath
384 ->SetImplicitDirectories(this->ImplicitLinkDirs);
385 this->OrderDependentRPath
386 ->AddLanguageDirectories(this->RuntimeLinkDirs);
389 // Decide whether to enable compatible library search path mode.
390 // There exists code that effectively does
392 // /path/to/libA.so -lB
394 // where -lB is meant to link to /path/to/libB.so. This is broken
395 // because it specified -lB without specifying a link directory (-L)
396 // in which to search for B. This worked in CMake 2.4 and below
397 // because -L/path/to would be added by the -L/-l split for A. In
398 // order to support such projects we need to add the directories
399 // containing libraries linked with a full path to the -L path.
400 this->OldLinkDirMode =
401 this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
402 if(this->OldLinkDirMode)
404 // Construct a mask to not bother with this behavior for link
405 // directories already specified by the user.
406 std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
407 for(std::vector<std::string>::const_iterator di = dirs.begin();
408 di != dirs.end(); ++di)
410 this->OldLinkDirMask.insert(*di);
415 //----------------------------------------------------------------------------
416 cmComputeLinkInformation::~cmComputeLinkInformation()
418 delete this->OrderLinkerSearchPath;
419 delete this->OrderRuntimeSearchPath;
420 delete this->OrderDependentRPath;
423 //----------------------------------------------------------------------------
424 cmComputeLinkInformation::ItemVector const&
425 cmComputeLinkInformation::GetItems()
430 //----------------------------------------------------------------------------
431 std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
433 return this->OrderLinkerSearchPath->GetOrderedDirectories();
436 //----------------------------------------------------------------------------
437 std::string cmComputeLinkInformation::GetRPathLinkString()
439 // If there is no separate linker runtime search flag (-rpath-link)
440 // there is no reason to compute a string.
441 if(!this->OrderDependentRPath)
446 // Construct the linker runtime search path.
447 std::string rpath_link;
448 const char* sep = "";
449 std::vector<std::string> const& dirs =
450 this->OrderDependentRPath->GetOrderedDirectories();
451 for(std::vector<std::string>::const_iterator di = dirs.begin();
452 di != dirs.end(); ++di)
461 //----------------------------------------------------------------------------
462 std::vector<std::string> const& cmComputeLinkInformation::GetDepends()
464 return this->Depends;
467 //----------------------------------------------------------------------------
468 std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
470 return this->FrameworkPaths;
473 //----------------------------------------------------------------------------
474 std::set<cmTarget*> const&
475 cmComputeLinkInformation::GetSharedLibrariesLinked()
477 return this->SharedLibrariesLinked;
480 //----------------------------------------------------------------------------
481 bool cmComputeLinkInformation::Compute()
483 // Skip targets that do not link.
484 if(!(this->Target->GetType() == cmTarget::EXECUTABLE ||
485 this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
486 this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
487 this->Target->GetType() == cmTarget::STATIC_LIBRARY))
492 // We require a link language for the target.
493 if(!this->LinkLanguage)
496 Error("CMake can not determine linker language for target:",
497 this->Target->GetName());
501 // Compute the ordered link line items.
502 cmComputeLinkDepends cld(this->Target, this->Config);
503 cld.SetOldLinkDirMode(this->OldLinkDirMode);
504 cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
506 // Add the link line items.
507 for(cmComputeLinkDepends::EntryVector::const_iterator
508 lei = linkEntries.begin();
509 lei != linkEntries.end(); ++lei)
513 this->AddSharedDepItem(lei->Item, lei->Target);
517 this->AddItem(lei->Item, lei->Target);
521 // Restore the target link type so the correct system runtime
522 // libraries are found.
523 const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
524 if(cmSystemTools::IsOn(lss))
526 this->SetCurrentLinkType(LinkStatic);
530 this->SetCurrentLinkType(this->StartLinkType);
533 // Finish listing compatibility paths.
534 if(this->OldLinkDirMode)
536 // For CMake 2.4 bug-compatibility we need to consider the output
537 // directories of targets linked in another configuration as link
539 std::set<cmTarget*> const& wrongItems = cld.GetOldWrongConfigItems();
540 for(std::set<cmTarget*>::const_iterator i = wrongItems.begin();
541 i != wrongItems.end(); ++i)
545 (this->UseImportLibrary &&
546 (tgt->GetType() == cmTarget::SHARED_LIBRARY));
547 std::string lib = tgt->GetFullPath(this->Config , implib, true);
548 this->OldLinkDirItems.push_back(lib);
552 // Finish setting up linker search directories.
553 if(!this->FinishLinkerSearchDirectories())
558 // Add implicit language runtime libraries and directories.
559 this->AddImplicitLinkInfo();
564 //----------------------------------------------------------------------------
565 void cmComputeLinkInformation::AddImplicitLinkInfo()
567 // The link closure lists all languages whose implicit info is needed.
568 cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config);
569 for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
570 li != lc->Languages.end(); ++li)
572 // Skip those of the linker language. They are implicit.
573 if(*li != this->LinkLanguage)
575 this->AddImplicitLinkInfo(*li);
580 //----------------------------------------------------------------------------
581 void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
583 // Add libraries for this language that are not implied by the
585 std::string libVar = "CMAKE_";
587 libVar += "_IMPLICIT_LINK_LIBRARIES";
588 if(const char* libs = this->Makefile->GetDefinition(libVar.c_str()))
590 std::vector<std::string> libsVec;
591 cmSystemTools::ExpandListArgument(libs, libsVec);
592 for(std::vector<std::string>::const_iterator i = libsVec.begin();
593 i != libsVec.end(); ++i)
595 if(this->ImplicitLinkLibs.find(*i) == this->ImplicitLinkLibs.end())
597 this->AddItem(i->c_str(), 0);
602 // Add linker search paths for this language that are not
603 // implied by the linker language.
604 std::string dirVar = "CMAKE_";
606 dirVar += "_IMPLICIT_LINK_DIRECTORIES";
607 if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
609 std::vector<std::string> dirsVec;
610 cmSystemTools::ExpandListArgument(dirs, dirsVec);
611 this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
615 //----------------------------------------------------------------------------
616 void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
618 // Compute the proper name to use to link this library.
619 const char* config = this->Config;
620 bool impexe = (tgt && tgt->IsExecutableWithExports());
621 if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
623 // Skip linking to executables on platforms with no import
624 // libraries or loader flags.
628 if(tgt && tgt->IsLinkable())
630 // This is a CMake target. Ask the target for its real name.
631 if(impexe && this->LoaderFlag)
633 // This link item is an executable that may provide symbols
634 // used by this target. A special flag is needed on this
635 // platform. Add it now.
636 std::string linkItem;
637 linkItem = this->LoaderFlag;
638 std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
641 this->Items.push_back(Item(linkItem, true, tgt));
642 this->Depends.push_back(exe);
646 // Decide whether to use an import library.
648 (this->UseImportLibrary &&
649 (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
651 // Pass the full path to the target file.
652 std::string lib = tgt->GetFullPath(config, implib, true);
653 this->Depends.push_back(lib);
655 this->AddTargetItem(lib, tgt);
656 this->AddLibraryRuntimeInfo(lib, tgt);
661 // This is not a CMake target. Use the name given.
662 if(cmSystemTools::FileIsFullPath(item.c_str()))
664 if(cmSystemTools::FileIsDirectory(item.c_str()))
666 // This is a directory.
667 this->AddDirectoryItem(item);
671 // Use the full path given to the library file.
672 this->Depends.push_back(item);
673 this->AddFullItem(item);
674 this->AddLibraryRuntimeInfo(item);
679 // This is a library or option specified by the user.
680 this->AddUserItem(item, true);
685 //----------------------------------------------------------------------------
686 void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
689 // If dropping shared library dependencies, ignore them.
690 if(this->SharedDependencyMode == SharedDepModeNone)
695 // The user may have incorrectly named an item. Skip items that are
696 // not full paths to shared libraries.
699 // The target will provide a full path. Make sure it is a shared
701 if(tgt->GetType() != cmTarget::SHARED_LIBRARY)
708 // Skip items that are not full paths. We will not be able to
709 // reliably specify them.
710 if(!cmSystemTools::FileIsFullPath(item.c_str()))
715 // Get the name of the library from the file name.
716 std::string file = cmSystemTools::GetFilenameName(item);
717 if(!this->ExtractSharedLibraryName.find(file.c_str()))
719 // This is not the name of a shared library.
724 // If in linking mode, just link to the shared library.
725 if(this->SharedDependencyMode == SharedDepModeLink)
727 this->AddItem(item, tgt);
731 // Get a full path to the dependent shared library.
732 // Add it to the runtime path computation so that the target being
733 // linked will be able to find it.
737 lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
738 this->AddLibraryRuntimeInfo(lib, tgt);
743 this->AddLibraryRuntimeInfo(lib);
746 // Check if we need to include the dependent shared library in other
748 cmOrderDirectories* order = 0;
749 if(this->SharedDependencyMode == SharedDepModeLibDir &&
750 !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */)
752 // Add the item to the linker search path.
753 order = this->OrderLinkerSearchPath;
755 else if(this->SharedDependencyMode == SharedDepModeDir)
757 // Add the item to the separate dependent library search path.
758 order = this->OrderDependentRPath;
764 std::string soName = tgt->GetSOName(this->Config);
765 const char* soname = soName.empty()? 0 : soName.c_str();
766 order->AddRuntimeLibrary(lib, soname);
770 order->AddRuntimeLibrary(lib);
775 //----------------------------------------------------------------------------
776 void cmComputeLinkInformation::ComputeLinkTypeInfo()
778 // Check whether archives may actually be shared libraries.
779 this->ArchivesMayBeShared =
780 this->CMakeInstance->GetPropertyAsBool(
781 "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
783 // First assume we cannot do link type stuff.
784 this->LinkTypeEnabled = false;
786 // Lookup link type selection flags.
787 const char* static_link_type_flag = 0;
788 const char* shared_link_type_flag = 0;
789 const char* target_type_str = 0;
790 switch(this->Target->GetType())
792 case cmTarget::EXECUTABLE: target_type_str = "EXE"; break;
793 case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
794 case cmTarget::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
799 std::string static_link_type_flag_var = "CMAKE_";
800 static_link_type_flag_var += target_type_str;
801 static_link_type_flag_var += "_LINK_STATIC_";
802 static_link_type_flag_var += this->LinkLanguage;
803 static_link_type_flag_var += "_FLAGS";
804 static_link_type_flag =
805 this->Makefile->GetDefinition(static_link_type_flag_var.c_str());
807 std::string shared_link_type_flag_var = "CMAKE_";
808 shared_link_type_flag_var += target_type_str;
809 shared_link_type_flag_var += "_LINK_DYNAMIC_";
810 shared_link_type_flag_var += this->LinkLanguage;
811 shared_link_type_flag_var += "_FLAGS";
812 shared_link_type_flag =
813 this->Makefile->GetDefinition(shared_link_type_flag_var.c_str());
816 // We can support link type switching only if all needed flags are
818 if(static_link_type_flag && *static_link_type_flag &&
819 shared_link_type_flag && *shared_link_type_flag)
821 this->LinkTypeEnabled = true;
822 this->StaticLinkTypeFlag = static_link_type_flag;
823 this->SharedLinkTypeFlag = shared_link_type_flag;
826 // Lookup the starting link type from the target (linked statically?).
827 const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
828 this->StartLinkType = cmSystemTools::IsOn(lss)? LinkStatic : LinkShared;
829 this->CurrentLinkType = this->StartLinkType;
832 //----------------------------------------------------------------------------
833 void cmComputeLinkInformation::ComputeItemParserInfo()
835 // Get possible library name prefixes.
836 cmMakefile* mf = this->Makefile;
837 this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
838 this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
840 // Import library names should be matched and treated as shared
841 // libraries for the purposes of linking.
842 this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
844 this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
846 this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
848 this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
850 if(const char* linkSuffixes =
851 mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
853 std::vector<std::string> linkSuffixVec;
854 cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
855 for(std::vector<std::string>::iterator i = linkSuffixVec.begin();
856 i != linkSuffixVec.end(); ++i)
858 this->AddLinkExtension(i->c_str(), LinkUnknown);
861 if(const char* sharedSuffixes =
862 mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES"))
864 std::vector<std::string> sharedSuffixVec;
865 cmSystemTools::ExpandListArgument(sharedSuffixes, sharedSuffixVec);
866 for(std::vector<std::string>::iterator i = sharedSuffixVec.begin();
867 i != sharedSuffixVec.end(); ++i)
869 this->AddLinkExtension(i->c_str(), LinkShared);
873 // Compute a regex to match link extensions.
874 std::string libext = this->CreateExtensionRegex(this->LinkExtensions);
876 // Create regex to remove any library extension.
877 std::string reg("(.*)");
879 this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
882 // Create a regex to match a library name. Match index 1 will be
883 // the prefix if it exists and empty otherwise. Match index 2 will
884 // be the library name. Match index 3 will be the library
887 for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
888 p != this->LinkPrefixes.end(); ++p)
896 // Create a regex to match any library name.
897 std::string reg_any = reg;
899 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
900 fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
902 this->ExtractAnyLibraryName.compile(reg_any.c_str());
904 // Create a regex to match static library names.
905 if(!this->StaticLinkExtensions.empty())
907 std::string reg_static = reg;
908 reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
909 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
910 fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
912 this->ExtractStaticLibraryName.compile(reg_static.c_str());
915 // Create a regex to match shared library names.
916 if(!this->SharedLinkExtensions.empty())
918 std::string reg_shared = reg;
919 this->SharedRegexString =
920 this->CreateExtensionRegex(this->SharedLinkExtensions);
921 reg_shared += this->SharedRegexString;
922 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
923 fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
925 this->ExtractSharedLibraryName.compile(reg_shared.c_str());
929 //----------------------------------------------------------------------------
930 void cmComputeLinkInformation::AddLinkPrefix(const char* p)
934 this->LinkPrefixes.insert(p);
938 //----------------------------------------------------------------------------
939 void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
943 if(type == LinkStatic)
945 this->StaticLinkExtensions.push_back(e);
947 if(type == LinkShared)
949 this->SharedLinkExtensions.push_back(e);
951 this->LinkExtensions.push_back(e);
955 //----------------------------------------------------------------------------
957 cmComputeLinkInformation
958 ::CreateExtensionRegex(std::vector<std::string> const& exts)
960 // Build a list of extension choices.
961 std::string libext = "(";
962 const char* sep = "";
963 for(std::vector<std::string>::const_iterator i = exts.begin();
964 i != exts.end(); ++i)
966 // Separate this choice from the previous one.
970 // Store this extension choice with the "." escaped.
972 #if defined(_WIN32) && !defined(__CYGWIN__)
973 libext += this->NoCaseExpression(i->c_str());
982 // Add an optional OpenBSD version component.
985 libext += "(\\.[0-9]+\\.[0-9]+)?";
992 //----------------------------------------------------------------------------
993 std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
1006 ret += static_cast<char>(tolower(*s));
1007 ret += static_cast<char>(toupper(*s));
1015 //-------------------------------------------------------------------
1016 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
1018 // If we are changing the current link type add the flag to tell the
1020 if(this->CurrentLinkType != lt)
1022 this->CurrentLinkType = lt;
1024 if(this->LinkTypeEnabled)
1026 switch(this->CurrentLinkType)
1029 this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
1032 this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
1041 //----------------------------------------------------------------------------
1042 void cmComputeLinkInformation::AddTargetItem(std::string const& item,
1045 // This is called to handle a link item that is a full path to a target.
1046 // If the target is not a static library make sure the link type is
1047 // shared. This is because dynamic-mode linking can handle both
1048 // shared and static libraries but static-mode can handle only
1049 // static libraries. If a previous user item changed the link type
1050 // to static we need to make sure it is back to shared.
1051 if(target->GetType() != cmTarget::STATIC_LIBRARY)
1053 this->SetCurrentLinkType(LinkShared);
1056 // Keep track of shared library targets linked.
1057 if(target->GetType() == cmTarget::SHARED_LIBRARY)
1059 this->SharedLibrariesLinked.insert(target);
1062 // Handle case of an imported shared library with no soname.
1063 if(this->NoSONameUsesPath &&
1064 target->IsImportedSharedLibWithoutSOName(this->Config))
1066 this->AddSharedLibNoSOName(item);
1070 // If this platform wants a flag before the full path, add it.
1071 if(!this->LibLinkFileFlag.empty())
1073 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1076 // For compatibility with CMake 2.4 include the item's directory in
1077 // the linker search path.
1078 if(this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
1079 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1080 this->OldLinkDirMask.end())
1082 this->OldLinkDirItems.push_back(item);
1085 // Now add the full path to the library.
1086 this->Items.push_back(Item(item, true, target));
1089 //----------------------------------------------------------------------------
1090 void cmComputeLinkInformation::AddFullItem(std::string const& item)
1092 // Check for the implicit link directory special case.
1093 if(this->CheckImplicitDirItem(item))
1098 // Check for case of shared library with no builtin soname.
1099 if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
1104 // Full path libraries should specify a valid library file name.
1105 // See documentation of CMP0008.
1106 if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
1107 (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
1108 strstr(this->GlobalGenerator->GetName(), "Xcode")))
1110 std::string file = cmSystemTools::GetFilenameName(item);
1111 if(!this->ExtractAnyLibraryName.find(file.c_str()))
1113 this->HandleBadFullItem(item, file);
1118 // This is called to handle a link item that is a full path.
1119 // If the target is not a static library make sure the link type is
1120 // shared. This is because dynamic-mode linking can handle both
1121 // shared and static libraries but static-mode can handle only
1122 // static libraries. If a previous user item changed the link type
1123 // to static we need to make sure it is back to shared.
1124 if(this->LinkTypeEnabled)
1126 std::string name = cmSystemTools::GetFilenameName(item);
1127 if(this->ExtractSharedLibraryName.find(name))
1129 this->SetCurrentLinkType(LinkShared);
1131 else if(!this->ExtractStaticLibraryName.find(item))
1133 // We cannot determine the type. Assume it is the target's
1135 this->SetCurrentLinkType(this->StartLinkType);
1139 // For compatibility with CMake 2.4 include the item's directory in
1140 // the linker search path.
1141 if(this->OldLinkDirMode &&
1142 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1143 this->OldLinkDirMask.end())
1145 this->OldLinkDirItems.push_back(item);
1148 // If this platform wants a flag before the full path, add it.
1149 if(!this->LibLinkFileFlag.empty())
1151 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1154 // Now add the full path to the library.
1155 this->Items.push_back(Item(item, true));
1158 //----------------------------------------------------------------------------
1159 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
1161 // We only switch to a pathless item if the link type may be
1162 // enforced. Fortunately only platforms that support link types
1163 // seem to have magic per-architecture implicit link directories.
1164 if(!this->LinkTypeEnabled)
1169 // Check if this item is in an implicit link directory.
1170 std::string dir = cmSystemTools::GetFilenamePath(item);
1171 if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
1173 // Only libraries in implicit link directories are converted to
1178 // Only apply the policy below if the library file is one that can
1179 // be found by the linker.
1180 std::string file = cmSystemTools::GetFilenameName(item);
1181 if(!this->ExtractAnyLibraryName.find(file))
1186 // Many system linkers support multiple architectures by
1187 // automatically selecting the implicit linker search path for the
1188 // current architecture. If the library appears in an implicit link
1189 // directory then just report the file name without the directory
1190 // portion. This will allow the system linker to locate the proper
1191 // library for the architecture at link time.
1192 this->AddUserItem(file, false);
1194 // Make sure the link directory ordering will find the library.
1195 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1200 //----------------------------------------------------------------------------
1201 void cmComputeLinkInformation::AddUserItem(std::string const& item,
1204 // This is called to handle a link item that does not match a CMake
1205 // target and is not a full path. We check here if it looks like a
1206 // library file name to automatically request the proper link type
1207 // from the linker. For example:
1210 // libfoo.a ==> -Wl,-Bstatic -lfoo
1212 // Pass flags through untouched.
1213 if(item[0] == '-' || item[0] == '$' || item[0] == '`')
1215 // if this is a -l option then we might need to warn about
1216 // CMP0003 so put it in OldUserFlagItems, if it is not a -l
1217 // or -Wl,-l (-framework -pthread), then allow it without a
1218 // CMP0003 as -L will not affect those other linker flags
1219 if(item.find("-l") == 0 || item.find("-Wl,-l") == 0)
1221 // This is a linker option provided by the user.
1222 this->OldUserFlagItems.push_back(item);
1225 // Restore the target link type since this item does not specify
1227 this->SetCurrentLinkType(this->StartLinkType);
1229 // Use the item verbatim.
1230 this->Items.push_back(Item(item, false));
1234 // Parse out the prefix, base, and suffix components of the
1235 // library name. If the name matches that of a shared or static
1236 // library then set the link type accordingly.
1238 // Search for shared library names first because some platforms
1239 // have shared libraries with names that match the static library
1240 // pattern. For example cygwin and msys use the convention
1241 // libfoo.dll.a for import libraries and libfoo.a for static
1242 // libraries. On AIX a library with the name libfoo.a can be
1245 if(this->ExtractSharedLibraryName.find(item))
1247 // This matches a shared library file name.
1248 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1249 fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
1250 this->ExtractSharedLibraryName.match(1).c_str(),
1251 this->ExtractSharedLibraryName.match(2).c_str(),
1252 this->ExtractSharedLibraryName.match(3).c_str());
1254 // Set the link type to shared.
1255 this->SetCurrentLinkType(LinkShared);
1257 // Use just the library name so the linker will search.
1258 lib = this->ExtractSharedLibraryName.match(2);
1260 else if(this->ExtractStaticLibraryName.find(item))
1262 // This matches a static library file name.
1263 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1264 fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
1265 this->ExtractStaticLibraryName.match(1).c_str(),
1266 this->ExtractStaticLibraryName.match(2).c_str(),
1267 this->ExtractStaticLibraryName.match(3).c_str());
1269 // Set the link type to static.
1270 this->SetCurrentLinkType(LinkStatic);
1272 // Use just the library name so the linker will search.
1273 lib = this->ExtractStaticLibraryName.match(2);
1275 else if(this->ExtractAnyLibraryName.find(item))
1277 // This matches a library file name.
1278 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1279 fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
1280 this->ExtractAnyLibraryName.match(1).c_str(),
1281 this->ExtractAnyLibraryName.match(2).c_str(),
1282 this->ExtractAnyLibraryName.match(3).c_str());
1284 // Restore the target link type since this item does not specify
1286 this->SetCurrentLinkType(this->StartLinkType);
1288 // Use just the library name so the linker will search.
1289 lib = this->ExtractAnyLibraryName.match(2);
1293 // This is a name specified by the user.
1296 this->OldUserFlagItems.push_back(item);
1299 // We must ask the linker to search for a library with this name.
1300 // Restore the target link type since this item does not specify
1302 this->SetCurrentLinkType(this->StartLinkType);
1306 // Create an option to ask the linker to search for the library.
1307 std::string out = this->LibLinkFlag;
1309 out += this->LibLinkSuffix;
1310 this->Items.push_back(Item(out, false));
1312 // Here we could try to find the library the linker will find and
1313 // add a runtime information entry for it. It would probably not be
1314 // reliable and we want to encourage use of full paths for library
1318 //----------------------------------------------------------------------------
1319 void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
1321 // Try to separate the framework name and path.
1322 if(!this->SplitFramework.find(item.c_str()))
1325 e << "Could not parse framework path \"" << item << "\" "
1326 << "linked by target " << this->Target->GetName() << ".";
1327 cmSystemTools::Error(e.str().c_str());
1331 // Add the directory portion to the framework search path.
1332 this->AddFrameworkPath(this->SplitFramework.match(1));
1334 // Add the item using the -framework option.
1335 this->Items.push_back(Item("-framework", false));
1336 std::string fw = this->SplitFramework.match(2);
1337 fw = this->LocalGenerator->EscapeForShell(fw.c_str());
1338 this->Items.push_back(Item(fw, false));
1341 //----------------------------------------------------------------------------
1342 void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
1344 if(this->Makefile->IsOn("APPLE")
1345 && cmSystemTools::IsPathToFramework(item.c_str()))
1347 this->AddFrameworkItem(item);
1351 this->DropDirectoryItem(item);
1355 //----------------------------------------------------------------------------
1356 void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
1358 // A full path to a directory was found as a link item. Warn the
1361 e << "WARNING: Target \"" << this->Target->GetName()
1362 << "\" requests linking to directory \"" << item << "\". "
1363 << "Targets may link only to libraries. "
1364 << "CMake is dropping the item.";
1365 cmSystemTools::Message(e.str().c_str());
1368 //----------------------------------------------------------------------------
1369 void cmComputeLinkInformation::ComputeFrameworkInfo()
1371 // Avoid adding system framework paths. See "man ld" on OS X.
1372 this->FrameworkPathsEmmitted.insert("/Library/Frameworks");
1373 this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks");
1374 this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks");
1376 // Regular expression to extract a framework path and name.
1377 this->SplitFramework.compile("(.*)/(.*)\\.framework$");
1380 //----------------------------------------------------------------------------
1381 void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
1383 if(this->FrameworkPathsEmmitted.insert(p).second)
1385 this->FrameworkPaths.push_back(p);
1389 //----------------------------------------------------------------------------
1390 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
1392 // This platform will use the path to a library as its soname if the
1393 // library is given via path and was not built with an soname. If
1394 // this is a shared library that might be the case.
1395 std::string file = cmSystemTools::GetFilenameName(item);
1396 if(this->ExtractSharedLibraryName.find(file))
1398 // If we can guess the soname fairly reliably then assume the
1399 // library has one. Otherwise assume the library has no builtin
1402 if(!cmSystemTools::GuessLibrarySOName(item, soname))
1404 this->AddSharedLibNoSOName(item);
1411 //----------------------------------------------------------------------------
1412 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
1414 // We have a full path to a shared library with no soname. We need
1415 // to ask the linker to locate the item because otherwise the path
1416 // we give to it will be embedded in the target linked. Then at
1417 // runtime the dynamic linker will search for the library using the
1418 // path instead of just the name.
1419 std::string file = cmSystemTools::GetFilenameName(item);
1420 this->AddUserItem(file, false);
1422 // Make sure the link directory ordering will find the library.
1423 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1426 //----------------------------------------------------------------------------
1427 void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
1428 std::string const& file)
1430 // Do not depend on things that do not exist.
1431 std::vector<std::string>::iterator i =
1432 std::find(this->Depends.begin(), this->Depends.end(), item);
1433 if(i != this->Depends.end())
1435 this->Depends.erase(i);
1438 // Tell the linker to search for the item and provide the proper
1439 // path for it. Do not contribute to any CMP0003 warning (do not
1440 // put in OldLinkDirItems or OldUserFlagItems).
1441 this->AddUserItem(file, false);
1442 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1444 // Produce any needed message.
1445 switch(this->Target->GetPolicyStatusCMP0008())
1447 case cmPolicies::WARN:
1449 // Print the warning at most once for this item.
1450 std::string wid = "CMP0008-WARNING-GIVEN-";
1452 if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
1454 this->CMakeInstance->SetProperty(wid.c_str(), "1");
1456 w << (this->Makefile->GetPolicies()
1457 ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n"
1458 << "Target \"" << this->Target->GetName() << "\" links to item\n"
1459 << " " << item << "\n"
1460 << "which is a full-path but not a valid library file name.";
1461 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1462 this->Target->GetBacktrace());
1465 case cmPolicies::OLD:
1466 // OLD behavior does not warn.
1468 case cmPolicies::NEW:
1469 // NEW behavior will not get here.
1471 case cmPolicies::REQUIRED_IF_USED:
1472 case cmPolicies::REQUIRED_ALWAYS:
1475 e << (this->Makefile->GetPolicies()->
1476 GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n"
1477 << "Target \"" << this->Target->GetName() << "\" links to item\n"
1478 << " " << item << "\n"
1479 << "which is a full-path but not a valid library file name.";
1480 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1481 this->Target->GetBacktrace());
1487 //----------------------------------------------------------------------------
1488 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1490 // Support broken projects if necessary.
1491 if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
1492 !this->OldLinkDirMode)
1497 // Enforce policy constraints.
1498 switch(this->Target->GetPolicyStatusCMP0003())
1500 case cmPolicies::WARN:
1501 if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1503 this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
1505 this->PrintLinkPolicyDiagnosis(w);
1506 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1507 this->Target->GetBacktrace());
1509 case cmPolicies::OLD:
1510 // OLD behavior is to add the paths containing libraries with
1511 // known full paths as link directories.
1513 case cmPolicies::NEW:
1514 // Should never happen due to assignment of OldLinkDirMode
1516 case cmPolicies::REQUIRED_IF_USED:
1517 case cmPolicies::REQUIRED_ALWAYS:
1520 e << (this->Makefile->GetPolicies()->
1521 GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
1522 this->PrintLinkPolicyDiagnosis(e);
1523 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1524 this->Target->GetBacktrace());
1529 // Add the link directories for full path items.
1530 for(std::vector<std::string>::const_iterator
1531 i = this->OldLinkDirItems.begin();
1532 i != this->OldLinkDirItems.end(); ++i)
1534 this->OrderLinkerSearchPath->AddLinkLibrary(*i);
1539 //----------------------------------------------------------------------------
1540 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
1542 // Tell the user what to do.
1543 os << "Policy CMP0003 should be set before this line. "
1544 << "Add code such as\n"
1545 << " if(COMMAND cmake_policy)\n"
1546 << " cmake_policy(SET CMP0003 NEW)\n"
1547 << " endif(COMMAND cmake_policy)\n"
1548 << "as early as possible but after the most recent call to "
1549 << "cmake_minimum_required or cmake_policy(VERSION). ";
1551 // List the items that might need the old-style paths.
1552 os << "This warning appears because target \""
1553 << this->Target->GetName() << "\" "
1554 << "links to some libraries for which the linker must search:\n";
1556 // Format the list of unknown items to be as short as possible while
1557 // still fitting in the allowed width (a true solution would be the
1558 // bin packing problem if we were allowed to change the order).
1559 std::string::size_type max_size = 76;
1561 const char* sep = " ";
1562 for(std::vector<std::string>::const_iterator
1563 i = this->OldUserFlagItems.begin();
1564 i != this->OldUserFlagItems.end(); ++i)
1566 // If the addition of another item will exceed the limit then
1567 // output the current line and reset it. Note that the separator
1568 // is either " " or ", " which is always 2 characters.
1569 if(!line.empty() && (line.size() + i->size() + 2) > max_size)
1577 // Convert to the other separator.
1586 // List the paths old behavior is adding.
1587 os << "and other libraries with known full path:\n";
1588 std::set<cmStdString> emitted;
1589 for(std::vector<std::string>::const_iterator
1590 i = this->OldLinkDirItems.begin();
1591 i != this->OldLinkDirItems.end(); ++i)
1593 if(emitted.insert(cmSystemTools::GetFilenamePath(*i)).second)
1595 os << " " << *i << "\n";
1600 os << "CMake is adding directories in the second list to the linker "
1601 << "search path in case they are needed to find libraries from the "
1602 << "first list (for backwards compatibility with CMake 2.4). "
1603 << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1604 << "behavior explicitly. "
1605 << "Run \"cmake --help-policy CMP0003\" for more information.";
1608 //----------------------------------------------------------------------------
1609 void cmComputeLinkInformation::LoadImplicitLinkInfo()
1611 std::vector<std::string> implicitDirVec;
1613 // Get platform-wide implicit directories.
1614 if(const char* implicitLinks =
1615 (this->Makefile->GetDefinition
1616 ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
1618 cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1621 // Append library architecture to all implicit platform directories
1622 // and add them to the set
1623 if(const char* libraryArch =
1624 this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
1626 for (std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1627 i != implicitDirVec.end(); ++i)
1629 this->ImplicitLinkDirs.insert(*i + "/" + libraryArch);
1633 // Get language-specific implicit directories.
1634 std::string implicitDirVar = "CMAKE_";
1635 implicitDirVar += this->LinkLanguage;
1636 implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
1637 if(const char* implicitDirs =
1638 this->Makefile->GetDefinition(implicitDirVar.c_str()))
1640 cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1643 // Store implicit link directories.
1644 for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1645 i != implicitDirVec.end(); ++i)
1647 this->ImplicitLinkDirs.insert(*i);
1650 // Get language-specific implicit libraries.
1651 std::vector<std::string> implicitLibVec;
1652 std::string implicitLibVar = "CMAKE_";
1653 implicitLibVar += this->LinkLanguage;
1654 implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
1655 if(const char* implicitLibs =
1656 this->Makefile->GetDefinition(implicitLibVar.c_str()))
1658 cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec);
1661 // Store implicit link libraries.
1662 for(std::vector<std::string>::const_iterator i = implicitLibVec.begin();
1663 i != implicitLibVec.end(); ++i)
1665 // Items starting in '-' but not '-l' are flags, not libraries,
1666 // and should not be filtered by this implicit list.
1667 std::string const& item = *i;
1668 if(item[0] != '-' || item[1] == 'l')
1670 this->ImplicitLinkLibs.insert(item);
1674 // Get platform specific rpath link directories
1675 if(const char *rpathDirs =
1676 (this->Makefile->GetDefinition
1677 ("CMAKE_PLATFORM_RUNTIME_PATH")))
1679 cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs);
1683 //----------------------------------------------------------------------------
1684 std::vector<std::string> const&
1685 cmComputeLinkInformation::GetRuntimeSearchPath()
1687 return this->OrderRuntimeSearchPath->GetOrderedDirectories();
1690 //----------------------------------------------------------------------------
1692 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
1695 // Libraries with unknown type must be handled using just the file
1697 if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
1699 this->AddLibraryRuntimeInfo(fullPath);
1703 // Skip targets that are not shared libraries (modules cannot be linked).
1704 if(target->GetType() != cmTarget::SHARED_LIBRARY)
1709 // Try to get the soname of the library. Only files with this name
1710 // could possibly conflict.
1711 std::string soName = target->GetSOName(this->Config);
1712 const char* soname = soName.empty()? 0 : soName.c_str();
1714 // Include this library in the runtime path ordering.
1715 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
1716 if(this->LinkWithRuntimePath)
1718 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
1722 //----------------------------------------------------------------------------
1724 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
1726 // Get the name of the library from the file name.
1727 std::string file = cmSystemTools::GetFilenameName(fullPath);
1728 if(!this->ExtractSharedLibraryName.find(file.c_str()))
1730 // On some platforms (AIX) a shared library may look static.
1731 if(this->ArchivesMayBeShared)
1733 if(!this->ExtractStaticLibraryName.find(file.c_str()))
1735 // This is not the name of a shared library or archive.
1741 // This is not the name of a shared library.
1746 // Include this library in the runtime path ordering.
1747 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
1748 if(this->LinkWithRuntimePath)
1750 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
1754 //----------------------------------------------------------------------------
1755 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
1758 // Select whether to generate runtime search directories.
1759 bool outputRuntime =
1760 !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
1762 // Select whether to generate an rpath for the install tree or the
1764 bool linking_for_install =
1766 this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1767 bool use_install_rpath =
1768 (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
1769 linking_for_install);
1770 bool use_build_rpath =
1771 (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
1772 !linking_for_install);
1773 bool use_link_rpath =
1774 outputRuntime && linking_for_install &&
1775 !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
1776 this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1778 // Construct the RPATH.
1779 if(use_install_rpath)
1781 const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
1782 cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
1784 if(use_build_rpath || use_link_rpath)
1786 std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
1787 for(std::vector<std::string>::const_iterator ri = rdirs.begin();
1788 ri != rdirs.end(); ++ri)
1790 // Put this directory in the rpath if using build-tree rpath
1791 // support or if using the link path as an rpath.
1794 runtimeDirs.push_back(*ri);
1796 else if(use_link_rpath)
1798 // Do not add any path inside the source or build tree.
1799 const char* topSourceDir = this->Makefile->GetHomeDirectory();
1800 const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
1801 if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
1802 !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
1803 !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
1804 !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
1806 runtimeDirs.push_back(*ri);
1812 // Add runtime paths required by the platform to always be
1813 // present. This is done even when skipping rpath support.
1814 cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs);
1817 //----------------------------------------------------------------------------
1818 std::string cmComputeLinkInformation::GetRPathString(bool for_install)
1820 // Get the directories to use.
1821 std::vector<std::string> runtimeDirs;
1822 this->GetRPath(runtimeDirs, for_install);
1824 // Concatenate the paths.
1826 const char* sep = "";
1827 for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
1828 ri != runtimeDirs.end(); ++ri)
1830 // Separate from previous path.
1832 sep = this->GetRuntimeSep().c_str();
1838 // If the rpath will be replaced at install time, prepare space.
1839 if(!for_install && this->RuntimeUseChrpath)
1843 // Add one trailing separator so the linker does not re-use the
1844 // rpath .dynstr entry for a symbol name that happens to match
1845 // the end of the rpath string.
1846 rpath += this->GetRuntimeSep();
1849 // Make sure it is long enough to hold the replacement value.
1850 std::string::size_type minLength = this->GetChrpathString().length();
1851 while(rpath.length() < minLength)
1853 rpath += this->GetRuntimeSep();
1860 //----------------------------------------------------------------------------
1861 std::string cmComputeLinkInformation::GetChrpathString()
1863 if(!this->RuntimeUseChrpath)
1868 return this->GetRPathString(true);