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,
243 cmTarget *headTarget)
245 // Store context information.
246 this->Target = target;
247 this->HeadTarget = headTarget;
248 this->Makefile = this->Target->GetMakefile();
249 this->LocalGenerator = this->Makefile->GetLocalGenerator();
250 this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
251 this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
253 // Check whether to recognize OpenBSD-style library versioned names.
254 this->OpenBSD = this->Makefile->GetCMakeInstance()
255 ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
257 // The configuration being linked.
258 this->Config = config;
260 // Allocate internals.
261 this->OrderLinkerSearchPath =
262 new cmOrderDirectories(this->GlobalGenerator, target,
263 "linker search path");
264 this->OrderRuntimeSearchPath =
265 new cmOrderDirectories(this->GlobalGenerator, target,
266 "runtime search path");
267 this->OrderDependentRPath = 0;
269 // Get the language used for linking this target.
270 this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
271 if(!this->LinkLanguage)
273 // The Compute method will do nothing, so skip the rest of the
278 // Check whether we should use an import library for linking a target.
279 this->UseImportLibrary =
280 this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
282 // Check whether we should skip dependencies on shared library files.
283 this->LinkDependsNoShared =
284 this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
286 // On platforms without import libraries there may be a special flag
287 // to use when creating a plugin (module) that obtains symbols from
288 // the program that will load it.
289 this->LoaderFlag = 0;
290 if(!this->UseImportLibrary &&
291 this->Target->GetType() == cmTarget::MODULE_LIBRARY)
293 std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
294 loader_flag_var += this->LinkLanguage;
295 loader_flag_var += "_FLAG";
296 this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var.c_str());
299 // Get options needed to link libraries.
301 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
302 this->LibLinkFileFlag =
303 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
304 this->LibLinkSuffix =
305 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
307 // Get options needed to specify RPATHs.
308 this->RuntimeUseChrpath = false;
309 if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
312 ((this->Target->GetType() == cmTarget::EXECUTABLE)?
313 "EXECUTABLE" : "SHARED_LIBRARY");
314 std::string rtVar = "CMAKE_";
316 rtVar += "_RUNTIME_";
317 rtVar += this->LinkLanguage;
319 std::string rtSepVar = rtVar + "_SEP";
320 this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar.c_str());
321 this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar.c_str());
322 this->RuntimeAlways =
324 GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
325 this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);
327 // Get options needed to help find dependent libraries.
328 std::string rlVar = "CMAKE_";
330 rlVar += "_RPATH_LINK_";
331 rlVar += this->LinkLanguage;
333 this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar.c_str());
336 // Check if we need to include the runtime search path at link time.
338 std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
339 var += this->LinkLanguage;
340 var += "_WITH_RUNTIME_PATH";
341 this->LinkWithRuntimePath = this->Makefile->IsOn(var.c_str());
344 // Check the platform policy for missing soname case.
345 this->NoSONameUsesPath =
346 this->Makefile->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
348 // Get link type information.
349 this->ComputeLinkTypeInfo();
351 // Setup the link item parser.
352 this->ComputeItemParserInfo();
354 // Setup framework support.
355 this->ComputeFrameworkInfo();
357 // Choose a mode for dealing with shared library dependencies.
358 this->SharedDependencyMode = SharedDepModeNone;
359 if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES"))
361 this->SharedDependencyMode = SharedDepModeLink;
363 else if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS"))
365 this->SharedDependencyMode = SharedDepModeLibDir;
367 else if(!this->RPathLinkFlag.empty())
369 this->SharedDependencyMode = SharedDepModeDir;
370 this->OrderDependentRPath =
371 new cmOrderDirectories(this->GlobalGenerator, target,
372 "dependent library path");
375 // Add the search path entries requested by the user to path ordering.
376 this->OrderLinkerSearchPath
377 ->AddUserDirectories(this->Target->GetLinkDirectories());
378 this->OrderRuntimeSearchPath
379 ->AddUserDirectories(this->Target->GetLinkDirectories());
381 // Set up the implicit link directories.
382 this->LoadImplicitLinkInfo();
383 this->OrderLinkerSearchPath
384 ->SetImplicitDirectories(this->ImplicitLinkDirs);
385 this->OrderRuntimeSearchPath
386 ->SetImplicitDirectories(this->ImplicitLinkDirs);
387 if(this->OrderDependentRPath)
389 this->OrderDependentRPath
390 ->SetImplicitDirectories(this->ImplicitLinkDirs);
391 this->OrderDependentRPath
392 ->AddLanguageDirectories(this->RuntimeLinkDirs);
395 // Decide whether to enable compatible library search path mode.
396 // There exists code that effectively does
398 // /path/to/libA.so -lB
400 // where -lB is meant to link to /path/to/libB.so. This is broken
401 // because it specified -lB without specifying a link directory (-L)
402 // in which to search for B. This worked in CMake 2.4 and below
403 // because -L/path/to would be added by the -L/-l split for A. In
404 // order to support such projects we need to add the directories
405 // containing libraries linked with a full path to the -L path.
406 this->OldLinkDirMode =
407 this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
408 if(this->OldLinkDirMode)
410 // Construct a mask to not bother with this behavior for link
411 // directories already specified by the user.
412 std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
413 for(std::vector<std::string>::const_iterator di = dirs.begin();
414 di != dirs.end(); ++di)
416 this->OldLinkDirMask.insert(*di);
421 //----------------------------------------------------------------------------
422 cmComputeLinkInformation::~cmComputeLinkInformation()
424 delete this->OrderLinkerSearchPath;
425 delete this->OrderRuntimeSearchPath;
426 delete this->OrderDependentRPath;
429 //----------------------------------------------------------------------------
430 cmComputeLinkInformation::ItemVector const&
431 cmComputeLinkInformation::GetItems()
436 //----------------------------------------------------------------------------
437 std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
439 return this->OrderLinkerSearchPath->GetOrderedDirectories();
442 //----------------------------------------------------------------------------
443 std::string cmComputeLinkInformation::GetRPathLinkString()
445 // If there is no separate linker runtime search flag (-rpath-link)
446 // there is no reason to compute a string.
447 if(!this->OrderDependentRPath)
452 // Construct the linker runtime search path.
453 std::string rpath_link;
454 const char* sep = "";
455 std::vector<std::string> const& dirs =
456 this->OrderDependentRPath->GetOrderedDirectories();
457 for(std::vector<std::string>::const_iterator di = dirs.begin();
458 di != dirs.end(); ++di)
467 //----------------------------------------------------------------------------
468 std::vector<std::string> const& cmComputeLinkInformation::GetDepends()
470 return this->Depends;
473 //----------------------------------------------------------------------------
474 std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
476 return this->FrameworkPaths;
479 //----------------------------------------------------------------------------
480 std::set<cmTarget*> const&
481 cmComputeLinkInformation::GetSharedLibrariesLinked()
483 return this->SharedLibrariesLinked;
486 //----------------------------------------------------------------------------
487 bool cmComputeLinkInformation::Compute()
489 // Skip targets that do not link.
490 if(!(this->Target->GetType() == cmTarget::EXECUTABLE ||
491 this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
492 this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
493 this->Target->GetType() == cmTarget::STATIC_LIBRARY))
498 // We require a link language for the target.
499 if(!this->LinkLanguage)
502 Error("CMake can not determine linker language for target: ",
503 this->Target->GetName());
507 // Compute the ordered link line items.
508 cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
509 cld.SetOldLinkDirMode(this->OldLinkDirMode);
510 cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
512 // Add the link line items.
513 for(cmComputeLinkDepends::EntryVector::const_iterator
514 lei = linkEntries.begin();
515 lei != linkEntries.end(); ++lei)
519 this->AddSharedDepItem(lei->Item, lei->Target);
523 this->AddItem(lei->Item, lei->Target);
527 // Restore the target link type so the correct system runtime
528 // libraries are found.
529 const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
530 if(cmSystemTools::IsOn(lss))
532 this->SetCurrentLinkType(LinkStatic);
536 this->SetCurrentLinkType(this->StartLinkType);
539 // Finish listing compatibility paths.
540 if(this->OldLinkDirMode)
542 // For CMake 2.4 bug-compatibility we need to consider the output
543 // directories of targets linked in another configuration as link
545 std::set<cmTarget*> const& wrongItems = cld.GetOldWrongConfigItems();
546 for(std::set<cmTarget*>::const_iterator i = wrongItems.begin();
547 i != wrongItems.end(); ++i)
551 (this->UseImportLibrary &&
552 (tgt->GetType() == cmTarget::SHARED_LIBRARY));
553 std::string lib = tgt->GetFullPath(this->Config , implib, true);
554 this->OldLinkDirItems.push_back(lib);
558 // Finish setting up linker search directories.
559 if(!this->FinishLinkerSearchDirectories())
564 // Add implicit language runtime libraries and directories.
565 this->AddImplicitLinkInfo();
570 //----------------------------------------------------------------------------
571 void cmComputeLinkInformation::AddImplicitLinkInfo()
573 // The link closure lists all languages whose implicit info is needed.
574 cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
576 for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
577 li != lc->Languages.end(); ++li)
579 // Skip those of the linker language. They are implicit.
580 if(*li != this->LinkLanguage)
582 this->AddImplicitLinkInfo(*li);
587 //----------------------------------------------------------------------------
588 void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
590 // Add libraries for this language that are not implied by the
592 std::string libVar = "CMAKE_";
594 libVar += "_IMPLICIT_LINK_LIBRARIES";
595 if(const char* libs = this->Makefile->GetDefinition(libVar.c_str()))
597 std::vector<std::string> libsVec;
598 cmSystemTools::ExpandListArgument(libs, libsVec);
599 for(std::vector<std::string>::const_iterator i = libsVec.begin();
600 i != libsVec.end(); ++i)
602 if(this->ImplicitLinkLibs.find(*i) == this->ImplicitLinkLibs.end())
604 this->AddItem(i->c_str(), 0);
609 // Add linker search paths for this language that are not
610 // implied by the linker language.
611 std::string dirVar = "CMAKE_";
613 dirVar += "_IMPLICIT_LINK_DIRECTORIES";
614 if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
616 std::vector<std::string> dirsVec;
617 cmSystemTools::ExpandListArgument(dirs, dirsVec);
618 this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
622 //----------------------------------------------------------------------------
623 void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
625 // Compute the proper name to use to link this library.
626 const char* config = this->Config;
627 bool impexe = (tgt && tgt->IsExecutableWithExports());
628 if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
630 // Skip linking to executables on platforms with no import
631 // libraries or loader flags.
635 if(tgt && tgt->IsLinkable())
637 // This is a CMake target. Ask the target for its real name.
638 if(impexe && this->LoaderFlag)
640 // This link item is an executable that may provide symbols
641 // used by this target. A special flag is needed on this
642 // platform. Add it now.
643 std::string linkItem;
644 linkItem = this->LoaderFlag;
645 std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
648 this->Items.push_back(Item(linkItem, true, tgt));
649 this->Depends.push_back(exe);
653 // Decide whether to use an import library.
655 (this->UseImportLibrary &&
656 (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
658 // Pass the full path to the target file.
659 std::string lib = tgt->GetFullPath(config, implib, true);
660 if(!this->LinkDependsNoShared ||
661 tgt->GetType() != cmTarget::SHARED_LIBRARY)
663 this->Depends.push_back(lib);
666 this->AddTargetItem(lib, tgt);
667 this->AddLibraryRuntimeInfo(lib, tgt);
672 // This is not a CMake target. Use the name given.
673 if(cmSystemTools::FileIsFullPath(item.c_str()))
675 if(cmSystemTools::FileIsDirectory(item.c_str()))
677 // This is a directory.
678 this->AddDirectoryItem(item);
682 // Use the full path given to the library file.
683 this->Depends.push_back(item);
684 this->AddFullItem(item);
685 this->AddLibraryRuntimeInfo(item);
690 // This is a library or option specified by the user.
691 this->AddUserItem(item, true);
696 //----------------------------------------------------------------------------
697 void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
700 // If dropping shared library dependencies, ignore them.
701 if(this->SharedDependencyMode == SharedDepModeNone)
706 // The user may have incorrectly named an item. Skip items that are
707 // not full paths to shared libraries.
710 // The target will provide a full path. Make sure it is a shared
712 if(tgt->GetType() != cmTarget::SHARED_LIBRARY)
719 // Skip items that are not full paths. We will not be able to
720 // reliably specify them.
721 if(!cmSystemTools::FileIsFullPath(item.c_str()))
726 // Get the name of the library from the file name.
727 std::string file = cmSystemTools::GetFilenameName(item);
728 if(!this->ExtractSharedLibraryName.find(file.c_str()))
730 // This is not the name of a shared library.
735 // If in linking mode, just link to the shared library.
736 if(this->SharedDependencyMode == SharedDepModeLink)
738 this->AddItem(item, tgt);
742 // Get a full path to the dependent shared library.
743 // Add it to the runtime path computation so that the target being
744 // linked will be able to find it.
748 lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
749 this->AddLibraryRuntimeInfo(lib, tgt);
754 this->AddLibraryRuntimeInfo(lib);
757 // Check if we need to include the dependent shared library in other
759 cmOrderDirectories* order = 0;
760 if(this->SharedDependencyMode == SharedDepModeLibDir &&
761 !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */)
763 // Add the item to the linker search path.
764 order = this->OrderLinkerSearchPath;
766 else if(this->SharedDependencyMode == SharedDepModeDir)
768 // Add the item to the separate dependent library search path.
769 order = this->OrderDependentRPath;
775 std::string soName = tgt->GetSOName(this->Config);
776 const char* soname = soName.empty()? 0 : soName.c_str();
777 order->AddRuntimeLibrary(lib, soname);
781 order->AddRuntimeLibrary(lib);
786 //----------------------------------------------------------------------------
787 void cmComputeLinkInformation::ComputeLinkTypeInfo()
789 // Check whether archives may actually be shared libraries.
790 this->ArchivesMayBeShared =
791 this->CMakeInstance->GetPropertyAsBool(
792 "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
794 // First assume we cannot do link type stuff.
795 this->LinkTypeEnabled = false;
797 // Lookup link type selection flags.
798 const char* static_link_type_flag = 0;
799 const char* shared_link_type_flag = 0;
800 const char* target_type_str = 0;
801 switch(this->Target->GetType())
803 case cmTarget::EXECUTABLE: target_type_str = "EXE"; break;
804 case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
805 case cmTarget::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
810 std::string static_link_type_flag_var = "CMAKE_";
811 static_link_type_flag_var += target_type_str;
812 static_link_type_flag_var += "_LINK_STATIC_";
813 static_link_type_flag_var += this->LinkLanguage;
814 static_link_type_flag_var += "_FLAGS";
815 static_link_type_flag =
816 this->Makefile->GetDefinition(static_link_type_flag_var.c_str());
818 std::string shared_link_type_flag_var = "CMAKE_";
819 shared_link_type_flag_var += target_type_str;
820 shared_link_type_flag_var += "_LINK_DYNAMIC_";
821 shared_link_type_flag_var += this->LinkLanguage;
822 shared_link_type_flag_var += "_FLAGS";
823 shared_link_type_flag =
824 this->Makefile->GetDefinition(shared_link_type_flag_var.c_str());
827 // We can support link type switching only if all needed flags are
829 if(static_link_type_flag && *static_link_type_flag &&
830 shared_link_type_flag && *shared_link_type_flag)
832 this->LinkTypeEnabled = true;
833 this->StaticLinkTypeFlag = static_link_type_flag;
834 this->SharedLinkTypeFlag = shared_link_type_flag;
837 // Lookup the starting link type from the target (linked statically?).
838 const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
839 this->StartLinkType = cmSystemTools::IsOn(lss)? LinkStatic : LinkShared;
840 this->CurrentLinkType = this->StartLinkType;
843 //----------------------------------------------------------------------------
844 void cmComputeLinkInformation::ComputeItemParserInfo()
846 // Get possible library name prefixes.
847 cmMakefile* mf = this->Makefile;
848 this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
849 this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
851 // Import library names should be matched and treated as shared
852 // libraries for the purposes of linking.
853 this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
855 this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
857 this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
859 this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
861 if(const char* linkSuffixes =
862 mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
864 std::vector<std::string> linkSuffixVec;
865 cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
866 for(std::vector<std::string>::iterator i = linkSuffixVec.begin();
867 i != linkSuffixVec.end(); ++i)
869 this->AddLinkExtension(i->c_str(), LinkUnknown);
872 if(const char* sharedSuffixes =
873 mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES"))
875 std::vector<std::string> sharedSuffixVec;
876 cmSystemTools::ExpandListArgument(sharedSuffixes, sharedSuffixVec);
877 for(std::vector<std::string>::iterator i = sharedSuffixVec.begin();
878 i != sharedSuffixVec.end(); ++i)
880 this->AddLinkExtension(i->c_str(), LinkShared);
884 // Compute a regex to match link extensions.
885 std::string libext = this->CreateExtensionRegex(this->LinkExtensions,
888 // Create regex to remove any library extension.
889 std::string reg("(.*)");
891 this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
894 // Create a regex to match a library name. Match index 1 will be
895 // the prefix if it exists and empty otherwise. Match index 2 will
896 // be the library name. Match index 3 will be the library
899 for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
900 p != this->LinkPrefixes.end(); ++p)
908 // Create a regex to match any library name.
909 std::string reg_any = reg;
911 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
912 fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
914 this->ExtractAnyLibraryName.compile(reg_any.c_str());
916 // Create a regex to match static library names.
917 if(!this->StaticLinkExtensions.empty())
919 std::string reg_static = reg;
920 reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions,
922 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
923 fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
925 this->ExtractStaticLibraryName.compile(reg_static.c_str());
928 // Create a regex to match shared library names.
929 if(!this->SharedLinkExtensions.empty())
931 std::string reg_shared = reg;
932 this->SharedRegexString =
933 this->CreateExtensionRegex(this->SharedLinkExtensions, LinkShared);
934 reg_shared += this->SharedRegexString;
935 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
936 fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
938 this->ExtractSharedLibraryName.compile(reg_shared.c_str());
942 //----------------------------------------------------------------------------
943 void cmComputeLinkInformation::AddLinkPrefix(const char* p)
947 this->LinkPrefixes.insert(p);
951 //----------------------------------------------------------------------------
952 void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
956 if(type == LinkStatic)
958 this->StaticLinkExtensions.push_back(e);
960 if(type == LinkShared)
962 this->SharedLinkExtensions.push_back(e);
964 this->LinkExtensions.push_back(e);
968 //----------------------------------------------------------------------------
970 cmComputeLinkInformation
971 ::CreateExtensionRegex(std::vector<std::string> const& exts, LinkType type)
973 // Build a list of extension choices.
974 std::string libext = "(";
975 const char* sep = "";
976 for(std::vector<std::string>::const_iterator i = exts.begin();
977 i != exts.end(); ++i)
979 // Separate this choice from the previous one.
983 // Store this extension choice with the "." escaped.
985 #if defined(_WIN32) && !defined(__CYGWIN__)
986 libext += this->NoCaseExpression(i->c_str());
995 // Add an optional OpenBSD version component.
998 libext += "(\\.[0-9]+\\.[0-9]+)?";
1000 else if(type == LinkShared)
1002 libext += "(\\.[0-9]+)?";
1009 //----------------------------------------------------------------------------
1010 std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
1013 const char* s = str;
1023 ret += static_cast<char>(tolower(*s));
1024 ret += static_cast<char>(toupper(*s));
1032 //-------------------------------------------------------------------
1033 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
1035 // If we are changing the current link type add the flag to tell the
1037 if(this->CurrentLinkType != lt)
1039 this->CurrentLinkType = lt;
1041 if(this->LinkTypeEnabled)
1043 switch(this->CurrentLinkType)
1046 this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
1049 this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
1058 //----------------------------------------------------------------------------
1059 void cmComputeLinkInformation::AddTargetItem(std::string const& item,
1062 // This is called to handle a link item that is a full path to a target.
1063 // If the target is not a static library make sure the link type is
1064 // shared. This is because dynamic-mode linking can handle both
1065 // shared and static libraries but static-mode can handle only
1066 // static libraries. If a previous user item changed the link type
1067 // to static we need to make sure it is back to shared.
1068 if(target->GetType() != cmTarget::STATIC_LIBRARY)
1070 this->SetCurrentLinkType(LinkShared);
1073 // Keep track of shared library targets linked.
1074 if(target->GetType() == cmTarget::SHARED_LIBRARY)
1076 this->SharedLibrariesLinked.insert(target);
1079 // Handle case of an imported shared library with no soname.
1080 if(this->NoSONameUsesPath &&
1081 target->IsImportedSharedLibWithoutSOName(this->Config))
1083 this->AddSharedLibNoSOName(item);
1087 // If this platform wants a flag before the full path, add it.
1088 if(!this->LibLinkFileFlag.empty())
1090 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1093 // For compatibility with CMake 2.4 include the item's directory in
1094 // the linker search path.
1095 if(this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
1096 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1097 this->OldLinkDirMask.end())
1099 this->OldLinkDirItems.push_back(item);
1102 // Now add the full path to the library.
1103 this->Items.push_back(Item(item, true, target));
1106 //----------------------------------------------------------------------------
1107 void cmComputeLinkInformation::AddFullItem(std::string const& item)
1109 // Check for the implicit link directory special case.
1110 if(this->CheckImplicitDirItem(item))
1115 // Check for case of shared library with no builtin soname.
1116 if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
1121 // Full path libraries should specify a valid library file name.
1122 // See documentation of CMP0008.
1123 if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
1124 (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
1125 strstr(this->GlobalGenerator->GetName(), "Xcode")))
1127 std::string file = cmSystemTools::GetFilenameName(item);
1128 if(!this->ExtractAnyLibraryName.find(file.c_str()))
1130 this->HandleBadFullItem(item, file);
1135 // This is called to handle a link item that is a full path.
1136 // If the target is not a static library make sure the link type is
1137 // shared. This is because dynamic-mode linking can handle both
1138 // shared and static libraries but static-mode can handle only
1139 // static libraries. If a previous user item changed the link type
1140 // to static we need to make sure it is back to shared.
1141 if(this->LinkTypeEnabled)
1143 std::string name = cmSystemTools::GetFilenameName(item);
1144 if(this->ExtractSharedLibraryName.find(name))
1146 this->SetCurrentLinkType(LinkShared);
1148 else if(!this->ExtractStaticLibraryName.find(item))
1150 // We cannot determine the type. Assume it is the target's
1152 this->SetCurrentLinkType(this->StartLinkType);
1156 // For compatibility with CMake 2.4 include the item's directory in
1157 // the linker search path.
1158 if(this->OldLinkDirMode &&
1159 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1160 this->OldLinkDirMask.end())
1162 this->OldLinkDirItems.push_back(item);
1165 // If this platform wants a flag before the full path, add it.
1166 if(!this->LibLinkFileFlag.empty())
1168 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1171 // Now add the full path to the library.
1172 this->Items.push_back(Item(item, true));
1175 //----------------------------------------------------------------------------
1176 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
1178 // We only switch to a pathless item if the link type may be
1179 // enforced. Fortunately only platforms that support link types
1180 // seem to have magic per-architecture implicit link directories.
1181 if(!this->LinkTypeEnabled)
1186 // Check if this item is in an implicit link directory.
1187 std::string dir = cmSystemTools::GetFilenamePath(item);
1188 if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
1190 // Only libraries in implicit link directories are converted to
1195 // Only apply the policy below if the library file is one that can
1196 // be found by the linker.
1197 std::string file = cmSystemTools::GetFilenameName(item);
1198 if(!this->ExtractAnyLibraryName.find(file))
1203 // Many system linkers support multiple architectures by
1204 // automatically selecting the implicit linker search path for the
1205 // current architecture. If the library appears in an implicit link
1206 // directory then just report the file name without the directory
1207 // portion. This will allow the system linker to locate the proper
1208 // library for the architecture at link time.
1209 this->AddUserItem(file, false);
1211 // Make sure the link directory ordering will find the library.
1212 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1217 //----------------------------------------------------------------------------
1218 void cmComputeLinkInformation::AddUserItem(std::string const& item,
1221 // This is called to handle a link item that does not match a CMake
1222 // target and is not a full path. We check here if it looks like a
1223 // library file name to automatically request the proper link type
1224 // from the linker. For example:
1227 // libfoo.a ==> -Wl,-Bstatic -lfoo
1229 // Pass flags through untouched.
1230 if(item[0] == '-' || item[0] == '$' || item[0] == '`')
1232 // if this is a -l option then we might need to warn about
1233 // CMP0003 so put it in OldUserFlagItems, if it is not a -l
1234 // or -Wl,-l (-framework -pthread), then allow it without a
1235 // CMP0003 as -L will not affect those other linker flags
1236 if(item.find("-l") == 0 || item.find("-Wl,-l") == 0)
1238 // This is a linker option provided by the user.
1239 this->OldUserFlagItems.push_back(item);
1242 // Restore the target link type since this item does not specify
1244 this->SetCurrentLinkType(this->StartLinkType);
1246 // Use the item verbatim.
1247 this->Items.push_back(Item(item, false));
1251 // Parse out the prefix, base, and suffix components of the
1252 // library name. If the name matches that of a shared or static
1253 // library then set the link type accordingly.
1255 // Search for shared library names first because some platforms
1256 // have shared libraries with names that match the static library
1257 // pattern. For example cygwin and msys use the convention
1258 // libfoo.dll.a for import libraries and libfoo.a for static
1259 // libraries. On AIX a library with the name libfoo.a can be
1262 if(this->ExtractSharedLibraryName.find(item))
1264 // This matches a shared library file name.
1265 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1266 fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
1267 this->ExtractSharedLibraryName.match(1).c_str(),
1268 this->ExtractSharedLibraryName.match(2).c_str(),
1269 this->ExtractSharedLibraryName.match(3).c_str());
1271 // Set the link type to shared.
1272 this->SetCurrentLinkType(LinkShared);
1274 // Use just the library name so the linker will search.
1275 lib = this->ExtractSharedLibraryName.match(2);
1277 else if(this->ExtractStaticLibraryName.find(item))
1279 // This matches a static library file name.
1280 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1281 fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
1282 this->ExtractStaticLibraryName.match(1).c_str(),
1283 this->ExtractStaticLibraryName.match(2).c_str(),
1284 this->ExtractStaticLibraryName.match(3).c_str());
1286 // Set the link type to static.
1287 this->SetCurrentLinkType(LinkStatic);
1289 // Use just the library name so the linker will search.
1290 lib = this->ExtractStaticLibraryName.match(2);
1292 else if(this->ExtractAnyLibraryName.find(item))
1294 // This matches a library file name.
1295 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1296 fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
1297 this->ExtractAnyLibraryName.match(1).c_str(),
1298 this->ExtractAnyLibraryName.match(2).c_str(),
1299 this->ExtractAnyLibraryName.match(3).c_str());
1301 // Restore the target link type since this item does not specify
1303 this->SetCurrentLinkType(this->StartLinkType);
1305 // Use just the library name so the linker will search.
1306 lib = this->ExtractAnyLibraryName.match(2);
1310 // This is a name specified by the user.
1313 this->OldUserFlagItems.push_back(item);
1316 // We must ask the linker to search for a library with this name.
1317 // Restore the target link type since this item does not specify
1319 this->SetCurrentLinkType(this->StartLinkType);
1323 // Create an option to ask the linker to search for the library.
1324 std::string out = this->LibLinkFlag;
1326 out += this->LibLinkSuffix;
1327 this->Items.push_back(Item(out, false));
1329 // Here we could try to find the library the linker will find and
1330 // add a runtime information entry for it. It would probably not be
1331 // reliable and we want to encourage use of full paths for library
1335 //----------------------------------------------------------------------------
1336 void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
1338 // Try to separate the framework name and path.
1339 if(!this->SplitFramework.find(item.c_str()))
1342 e << "Could not parse framework path \"" << item << "\" "
1343 << "linked by target " << this->Target->GetName() << ".";
1344 cmSystemTools::Error(e.str().c_str());
1348 std::string fw_path = this->SplitFramework.match(1);
1349 std::string fw = this->SplitFramework.match(2);
1350 std::string full_fw = fw_path;
1353 full_fw += ".framework";
1357 // Add the directory portion to the framework search path.
1358 this->AddFrameworkPath(fw_path);
1360 // add runtime information
1361 this->AddLibraryRuntimeInfo(full_fw);
1363 // Add the item using the -framework option.
1364 this->Items.push_back(Item("-framework", false));
1365 fw = this->LocalGenerator->EscapeForShell(fw.c_str());
1366 this->Items.push_back(Item(fw, false));
1369 //----------------------------------------------------------------------------
1370 void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
1372 if(this->Makefile->IsOn("APPLE")
1373 && cmSystemTools::IsPathToFramework(item.c_str()))
1375 this->AddFrameworkItem(item);
1379 this->DropDirectoryItem(item);
1383 //----------------------------------------------------------------------------
1384 void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
1386 // A full path to a directory was found as a link item. Warn the
1389 e << "WARNING: Target \"" << this->Target->GetName()
1390 << "\" requests linking to directory \"" << item << "\". "
1391 << "Targets may link only to libraries. "
1392 << "CMake is dropping the item.";
1393 cmSystemTools::Message(e.str().c_str());
1396 //----------------------------------------------------------------------------
1397 void cmComputeLinkInformation::ComputeFrameworkInfo()
1399 // Avoid adding implicit framework paths.
1400 std::vector<std::string> implicitDirVec;
1402 // Get platform-wide implicit directories.
1403 if(const char* implicitLinks = this->Makefile->GetDefinition
1404 ("CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"))
1406 cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1409 // Get language-specific implicit directories.
1410 std::string implicitDirVar = "CMAKE_";
1411 implicitDirVar += this->LinkLanguage;
1412 implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
1413 if(const char* implicitDirs =
1414 this->Makefile->GetDefinition(implicitDirVar.c_str()))
1416 cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1419 for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1420 i != implicitDirVec.end(); ++i)
1422 this->FrameworkPathsEmmitted.insert(*i);
1425 // Regular expression to extract a framework path and name.
1426 this->SplitFramework.compile("(.*)/(.*)\\.framework$");
1429 //----------------------------------------------------------------------------
1430 void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
1432 if(this->FrameworkPathsEmmitted.insert(p).second)
1434 this->FrameworkPaths.push_back(p);
1438 //----------------------------------------------------------------------------
1439 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
1441 // This platform will use the path to a library as its soname if the
1442 // library is given via path and was not built with an soname. If
1443 // this is a shared library that might be the case.
1444 std::string file = cmSystemTools::GetFilenameName(item);
1445 if(this->ExtractSharedLibraryName.find(file))
1447 // If we can guess the soname fairly reliably then assume the
1448 // library has one. Otherwise assume the library has no builtin
1451 if(!cmSystemTools::GuessLibrarySOName(item, soname))
1453 this->AddSharedLibNoSOName(item);
1460 //----------------------------------------------------------------------------
1461 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
1463 // We have a full path to a shared library with no soname. We need
1464 // to ask the linker to locate the item because otherwise the path
1465 // we give to it will be embedded in the target linked. Then at
1466 // runtime the dynamic linker will search for the library using the
1467 // path instead of just the name.
1468 std::string file = cmSystemTools::GetFilenameName(item);
1469 this->AddUserItem(file, false);
1471 // Make sure the link directory ordering will find the library.
1472 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1475 //----------------------------------------------------------------------------
1476 void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
1477 std::string const& file)
1479 // Do not depend on things that do not exist.
1480 std::vector<std::string>::iterator i =
1481 std::find(this->Depends.begin(), this->Depends.end(), item);
1482 if(i != this->Depends.end())
1484 this->Depends.erase(i);
1487 // Tell the linker to search for the item and provide the proper
1488 // path for it. Do not contribute to any CMP0003 warning (do not
1489 // put in OldLinkDirItems or OldUserFlagItems).
1490 this->AddUserItem(file, false);
1491 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1493 // Produce any needed message.
1494 switch(this->Target->GetPolicyStatusCMP0008())
1496 case cmPolicies::WARN:
1498 // Print the warning at most once for this item.
1499 std::string wid = "CMP0008-WARNING-GIVEN-";
1501 if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
1503 this->CMakeInstance->SetProperty(wid.c_str(), "1");
1505 w << (this->Makefile->GetPolicies()
1506 ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n"
1507 << "Target \"" << this->Target->GetName() << "\" links to item\n"
1508 << " " << item << "\n"
1509 << "which is a full-path but not a valid library file name.";
1510 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1511 this->Target->GetBacktrace());
1514 case cmPolicies::OLD:
1515 // OLD behavior does not warn.
1517 case cmPolicies::NEW:
1518 // NEW behavior will not get here.
1520 case cmPolicies::REQUIRED_IF_USED:
1521 case cmPolicies::REQUIRED_ALWAYS:
1524 e << (this->Makefile->GetPolicies()->
1525 GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n"
1526 << "Target \"" << this->Target->GetName() << "\" links to item\n"
1527 << " " << item << "\n"
1528 << "which is a full-path but not a valid library file name.";
1529 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1530 this->Target->GetBacktrace());
1536 //----------------------------------------------------------------------------
1537 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1539 // Support broken projects if necessary.
1540 if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
1541 !this->OldLinkDirMode)
1546 // Enforce policy constraints.
1547 switch(this->Target->GetPolicyStatusCMP0003())
1549 case cmPolicies::WARN:
1550 if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1552 this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
1554 this->PrintLinkPolicyDiagnosis(w);
1555 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1556 this->Target->GetBacktrace());
1558 case cmPolicies::OLD:
1559 // OLD behavior is to add the paths containing libraries with
1560 // known full paths as link directories.
1562 case cmPolicies::NEW:
1563 // Should never happen due to assignment of OldLinkDirMode
1565 case cmPolicies::REQUIRED_IF_USED:
1566 case cmPolicies::REQUIRED_ALWAYS:
1569 e << (this->Makefile->GetPolicies()->
1570 GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
1571 this->PrintLinkPolicyDiagnosis(e);
1572 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1573 this->Target->GetBacktrace());
1578 // Add the link directories for full path items.
1579 for(std::vector<std::string>::const_iterator
1580 i = this->OldLinkDirItems.begin();
1581 i != this->OldLinkDirItems.end(); ++i)
1583 this->OrderLinkerSearchPath->AddLinkLibrary(*i);
1588 //----------------------------------------------------------------------------
1589 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
1591 // Tell the user what to do.
1592 os << "Policy CMP0003 should be set before this line. "
1593 << "Add code such as\n"
1594 << " if(COMMAND cmake_policy)\n"
1595 << " cmake_policy(SET CMP0003 NEW)\n"
1596 << " endif(COMMAND cmake_policy)\n"
1597 << "as early as possible but after the most recent call to "
1598 << "cmake_minimum_required or cmake_policy(VERSION). ";
1600 // List the items that might need the old-style paths.
1601 os << "This warning appears because target \""
1602 << this->Target->GetName() << "\" "
1603 << "links to some libraries for which the linker must search:\n";
1605 // Format the list of unknown items to be as short as possible while
1606 // still fitting in the allowed width (a true solution would be the
1607 // bin packing problem if we were allowed to change the order).
1608 std::string::size_type max_size = 76;
1610 const char* sep = " ";
1611 for(std::vector<std::string>::const_iterator
1612 i = this->OldUserFlagItems.begin();
1613 i != this->OldUserFlagItems.end(); ++i)
1615 // If the addition of another item will exceed the limit then
1616 // output the current line and reset it. Note that the separator
1617 // is either " " or ", " which is always 2 characters.
1618 if(!line.empty() && (line.size() + i->size() + 2) > max_size)
1626 // Convert to the other separator.
1635 // List the paths old behavior is adding.
1636 os << "and other libraries with known full path:\n";
1637 std::set<cmStdString> emitted;
1638 for(std::vector<std::string>::const_iterator
1639 i = this->OldLinkDirItems.begin();
1640 i != this->OldLinkDirItems.end(); ++i)
1642 if(emitted.insert(cmSystemTools::GetFilenamePath(*i)).second)
1644 os << " " << *i << "\n";
1649 os << "CMake is adding directories in the second list to the linker "
1650 << "search path in case they are needed to find libraries from the "
1651 << "first list (for backwards compatibility with CMake 2.4). "
1652 << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1653 << "behavior explicitly. "
1654 << "Run \"cmake --help-policy CMP0003\" for more information.";
1657 //----------------------------------------------------------------------------
1658 void cmComputeLinkInformation::LoadImplicitLinkInfo()
1660 std::vector<std::string> implicitDirVec;
1662 // Get platform-wide implicit directories.
1663 if(const char* implicitLinks =
1664 (this->Makefile->GetDefinition
1665 ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
1667 cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1670 // Append library architecture to all implicit platform directories
1671 // and add them to the set
1672 if(const char* libraryArch =
1673 this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
1675 for (std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1676 i != implicitDirVec.end(); ++i)
1678 this->ImplicitLinkDirs.insert(*i + "/" + libraryArch);
1682 // Get language-specific implicit directories.
1683 std::string implicitDirVar = "CMAKE_";
1684 implicitDirVar += this->LinkLanguage;
1685 implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
1686 if(const char* implicitDirs =
1687 this->Makefile->GetDefinition(implicitDirVar.c_str()))
1689 cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1692 // Store implicit link directories.
1693 for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1694 i != implicitDirVec.end(); ++i)
1696 this->ImplicitLinkDirs.insert(*i);
1699 // Get language-specific implicit libraries.
1700 std::vector<std::string> implicitLibVec;
1701 std::string implicitLibVar = "CMAKE_";
1702 implicitLibVar += this->LinkLanguage;
1703 implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
1704 if(const char* implicitLibs =
1705 this->Makefile->GetDefinition(implicitLibVar.c_str()))
1707 cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec);
1710 // Store implicit link libraries.
1711 for(std::vector<std::string>::const_iterator i = implicitLibVec.begin();
1712 i != implicitLibVec.end(); ++i)
1714 // Items starting in '-' but not '-l' are flags, not libraries,
1715 // and should not be filtered by this implicit list.
1716 std::string const& item = *i;
1717 if(item[0] != '-' || item[1] == 'l')
1719 this->ImplicitLinkLibs.insert(item);
1723 // Get platform specific rpath link directories
1724 if(const char *rpathDirs =
1725 (this->Makefile->GetDefinition
1726 ("CMAKE_PLATFORM_RUNTIME_PATH")))
1728 cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs);
1732 //----------------------------------------------------------------------------
1733 std::vector<std::string> const&
1734 cmComputeLinkInformation::GetRuntimeSearchPath()
1736 return this->OrderRuntimeSearchPath->GetOrderedDirectories();
1739 //----------------------------------------------------------------------------
1741 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
1744 // Ignore targets on Apple where install_name is not @rpath.
1745 // The dependenty library can be found with other means such as
1746 // @loader_path or full paths.
1747 if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
1749 if(!target->HasMacOSXRpath(this->Config))
1755 // Libraries with unknown type must be handled using just the file
1757 if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
1759 this->AddLibraryRuntimeInfo(fullPath);
1763 // Skip targets that are not shared libraries (modules cannot be linked).
1764 if(target->GetType() != cmTarget::SHARED_LIBRARY)
1769 // Try to get the soname of the library. Only files with this name
1770 // could possibly conflict.
1771 std::string soName = target->GetSOName(this->Config);
1772 const char* soname = soName.empty()? 0 : soName.c_str();
1774 // Include this library in the runtime path ordering.
1775 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
1776 if(this->LinkWithRuntimePath)
1778 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
1782 //----------------------------------------------------------------------------
1784 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
1786 // Get the name of the library from the file name.
1787 bool is_shared_library = false;
1788 std::string file = cmSystemTools::GetFilenameName(fullPath);
1790 if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
1792 // Check that @rpath is part of the install name.
1793 // If it isn't, return.
1795 if(!cmSystemTools::GuessLibraryInstallName(fullPath, soname))
1800 if(soname.find("@rpath") == std::string::npos)
1806 is_shared_library = this->ExtractSharedLibraryName.find(file.c_str());
1808 if(!is_shared_library)
1810 // On some platforms (AIX) a shared library may look static.
1811 if(this->ArchivesMayBeShared)
1813 if(this->ExtractStaticLibraryName.find(file.c_str()))
1815 // This is the name of a shared library or archive.
1816 is_shared_library = true;
1821 // It could be an Apple framework
1822 if(!is_shared_library)
1824 if(fullPath.find(".framework") != std::string::npos)
1826 cmsys::RegularExpression splitFramework;
1827 splitFramework.compile("^(.*)/(.*).framework/(.*)$");
1828 if(splitFramework.find(fullPath) &&
1829 (std::string::npos !=
1830 splitFramework.match(3).find(splitFramework.match(2))))
1832 is_shared_library = true;
1837 if(!is_shared_library)
1842 // Include this library in the runtime path ordering.
1843 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
1844 if(this->LinkWithRuntimePath)
1846 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
1850 //----------------------------------------------------------------------------
1851 static void cmCLI_ExpandListUnique(const char* str,
1852 std::vector<std::string>& out,
1853 std::set<cmStdString>& emitted)
1855 std::vector<std::string> tmp;
1856 cmSystemTools::ExpandListArgument(str, tmp);
1857 for(std::vector<std::string>::iterator i = tmp.begin(); i != tmp.end(); ++i)
1859 if(emitted.insert(*i).second)
1866 //----------------------------------------------------------------------------
1867 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
1870 // Select whether to generate runtime search directories.
1871 bool outputRuntime =
1872 !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
1874 // Select whether to generate an rpath for the install tree or the
1876 bool linking_for_install =
1878 this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1879 bool use_install_rpath =
1880 (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
1881 linking_for_install);
1882 bool use_build_rpath =
1883 (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
1884 !linking_for_install);
1885 bool use_link_rpath =
1886 outputRuntime && linking_for_install &&
1887 !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
1888 this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1890 // Construct the RPATH.
1891 std::set<cmStdString> emitted;
1892 if(use_install_rpath)
1894 const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
1895 cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
1897 if(use_build_rpath || use_link_rpath)
1899 std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
1900 for(std::vector<std::string>::const_iterator ri = rdirs.begin();
1901 ri != rdirs.end(); ++ri)
1903 // Put this directory in the rpath if using build-tree rpath
1904 // support or if using the link path as an rpath.
1907 if(emitted.insert(*ri).second)
1909 runtimeDirs.push_back(*ri);
1912 else if(use_link_rpath)
1914 // Do not add any path inside the source or build tree.
1915 const char* topSourceDir = this->Makefile->GetHomeDirectory();
1916 const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
1917 if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
1918 !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
1919 !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
1920 !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
1922 if(emitted.insert(*ri).second)
1924 runtimeDirs.push_back(*ri);
1931 // Add runtime paths required by the languages to always be
1932 // present. This is done even when skipping rpath support.
1934 cmTarget::LinkClosure const* lc =
1935 this->Target->GetLinkClosure(this->Config, this->HeadTarget);
1936 for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
1937 li != lc->Languages.end(); ++li)
1939 std::string useVar = "CMAKE_" + *li +
1940 "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
1941 if(this->Makefile->IsOn(useVar.c_str()))
1943 std::string dirVar = "CMAKE_" + *li +
1944 "_IMPLICIT_LINK_DIRECTORIES";
1945 if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
1947 cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
1953 // Add runtime paths required by the platform to always be
1954 // present. This is done even when skipping rpath support.
1955 cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
1958 //----------------------------------------------------------------------------
1959 std::string cmComputeLinkInformation::GetRPathString(bool for_install)
1961 // Get the directories to use.
1962 std::vector<std::string> runtimeDirs;
1963 this->GetRPath(runtimeDirs, for_install);
1965 // Concatenate the paths.
1967 const char* sep = "";
1968 for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
1969 ri != runtimeDirs.end(); ++ri)
1971 // Separate from previous path.
1973 sep = this->GetRuntimeSep().c_str();
1979 // If the rpath will be replaced at install time, prepare space.
1980 if(!for_install && this->RuntimeUseChrpath)
1984 // Add one trailing separator so the linker does not re-use the
1985 // rpath .dynstr entry for a symbol name that happens to match
1986 // the end of the rpath string.
1987 rpath += this->GetRuntimeSep();
1990 // Make sure it is long enough to hold the replacement value.
1991 std::string::size_type minLength = this->GetChrpathString().length();
1992 while(rpath.length() < minLength)
1994 rpath += this->GetRuntimeSep();
2001 //----------------------------------------------------------------------------
2002 std::string cmComputeLinkInformation::GetChrpathString()
2004 if(!this->RuntimeUseChrpath)
2009 return this->GetRPathString(true);