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);
887 // Create regex to remove any library extension.
888 std::string reg("(.*)");
890 this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
893 // Create a regex to match a library name. Match index 1 will be
894 // the prefix if it exists and empty otherwise. Match index 2 will
895 // be the library name. Match index 3 will be the library
898 for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
899 p != this->LinkPrefixes.end(); ++p)
907 // Create a regex to match any library name.
908 std::string reg_any = reg;
910 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
911 fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
913 this->ExtractAnyLibraryName.compile(reg_any.c_str());
915 // Create a regex to match static library names.
916 if(!this->StaticLinkExtensions.empty())
918 std::string reg_static = reg;
919 reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
920 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
921 fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
923 this->ExtractStaticLibraryName.compile(reg_static.c_str());
926 // Create a regex to match shared library names.
927 if(!this->SharedLinkExtensions.empty())
929 std::string reg_shared = reg;
930 this->SharedRegexString =
931 this->CreateExtensionRegex(this->SharedLinkExtensions);
932 reg_shared += this->SharedRegexString;
933 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
934 fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
936 this->ExtractSharedLibraryName.compile(reg_shared.c_str());
940 //----------------------------------------------------------------------------
941 void cmComputeLinkInformation::AddLinkPrefix(const char* p)
945 this->LinkPrefixes.insert(p);
949 //----------------------------------------------------------------------------
950 void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
954 if(type == LinkStatic)
956 this->StaticLinkExtensions.push_back(e);
958 if(type == LinkShared)
960 this->SharedLinkExtensions.push_back(e);
962 this->LinkExtensions.push_back(e);
966 //----------------------------------------------------------------------------
968 cmComputeLinkInformation
969 ::CreateExtensionRegex(std::vector<std::string> const& exts)
971 // Build a list of extension choices.
972 std::string libext = "(";
973 const char* sep = "";
974 for(std::vector<std::string>::const_iterator i = exts.begin();
975 i != exts.end(); ++i)
977 // Separate this choice from the previous one.
981 // Store this extension choice with the "." escaped.
983 #if defined(_WIN32) && !defined(__CYGWIN__)
984 libext += this->NoCaseExpression(i->c_str());
993 // Add an optional OpenBSD version component.
996 libext += "(\\.[0-9]+\\.[0-9]+)?";
1003 //----------------------------------------------------------------------------
1004 std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
1007 const char* s = str;
1017 ret += static_cast<char>(tolower(*s));
1018 ret += static_cast<char>(toupper(*s));
1026 //-------------------------------------------------------------------
1027 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
1029 // If we are changing the current link type add the flag to tell the
1031 if(this->CurrentLinkType != lt)
1033 this->CurrentLinkType = lt;
1035 if(this->LinkTypeEnabled)
1037 switch(this->CurrentLinkType)
1040 this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
1043 this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
1052 //----------------------------------------------------------------------------
1053 void cmComputeLinkInformation::AddTargetItem(std::string const& item,
1056 // This is called to handle a link item that is a full path to a target.
1057 // If the target is not a static library make sure the link type is
1058 // shared. This is because dynamic-mode linking can handle both
1059 // shared and static libraries but static-mode can handle only
1060 // static libraries. If a previous user item changed the link type
1061 // to static we need to make sure it is back to shared.
1062 if(target->GetType() != cmTarget::STATIC_LIBRARY)
1064 this->SetCurrentLinkType(LinkShared);
1067 // Keep track of shared library targets linked.
1068 if(target->GetType() == cmTarget::SHARED_LIBRARY)
1070 this->SharedLibrariesLinked.insert(target);
1073 // Handle case of an imported shared library with no soname.
1074 if(this->NoSONameUsesPath &&
1075 target->IsImportedSharedLibWithoutSOName(this->Config))
1077 this->AddSharedLibNoSOName(item);
1081 // If this platform wants a flag before the full path, add it.
1082 if(!this->LibLinkFileFlag.empty())
1084 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1087 // For compatibility with CMake 2.4 include the item's directory in
1088 // the linker search path.
1089 if(this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
1090 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1091 this->OldLinkDirMask.end())
1093 this->OldLinkDirItems.push_back(item);
1096 // Now add the full path to the library.
1097 this->Items.push_back(Item(item, true, target));
1100 //----------------------------------------------------------------------------
1101 void cmComputeLinkInformation::AddFullItem(std::string const& item)
1103 // Check for the implicit link directory special case.
1104 if(this->CheckImplicitDirItem(item))
1109 // Check for case of shared library with no builtin soname.
1110 if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
1115 // Full path libraries should specify a valid library file name.
1116 // See documentation of CMP0008.
1117 if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
1118 (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
1119 strstr(this->GlobalGenerator->GetName(), "Xcode")))
1121 std::string file = cmSystemTools::GetFilenameName(item);
1122 if(!this->ExtractAnyLibraryName.find(file.c_str()))
1124 this->HandleBadFullItem(item, file);
1129 // This is called to handle a link item that is a full path.
1130 // If the target is not a static library make sure the link type is
1131 // shared. This is because dynamic-mode linking can handle both
1132 // shared and static libraries but static-mode can handle only
1133 // static libraries. If a previous user item changed the link type
1134 // to static we need to make sure it is back to shared.
1135 if(this->LinkTypeEnabled)
1137 std::string name = cmSystemTools::GetFilenameName(item);
1138 if(this->ExtractSharedLibraryName.find(name))
1140 this->SetCurrentLinkType(LinkShared);
1142 else if(!this->ExtractStaticLibraryName.find(item))
1144 // We cannot determine the type. Assume it is the target's
1146 this->SetCurrentLinkType(this->StartLinkType);
1150 // For compatibility with CMake 2.4 include the item's directory in
1151 // the linker search path.
1152 if(this->OldLinkDirMode &&
1153 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1154 this->OldLinkDirMask.end())
1156 this->OldLinkDirItems.push_back(item);
1159 // If this platform wants a flag before the full path, add it.
1160 if(!this->LibLinkFileFlag.empty())
1162 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1165 // Now add the full path to the library.
1166 this->Items.push_back(Item(item, true));
1169 //----------------------------------------------------------------------------
1170 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
1172 // We only switch to a pathless item if the link type may be
1173 // enforced. Fortunately only platforms that support link types
1174 // seem to have magic per-architecture implicit link directories.
1175 if(!this->LinkTypeEnabled)
1180 // Check if this item is in an implicit link directory.
1181 std::string dir = cmSystemTools::GetFilenamePath(item);
1182 if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
1184 // Only libraries in implicit link directories are converted to
1189 // Only apply the policy below if the library file is one that can
1190 // be found by the linker.
1191 std::string file = cmSystemTools::GetFilenameName(item);
1192 if(!this->ExtractAnyLibraryName.find(file))
1197 // Many system linkers support multiple architectures by
1198 // automatically selecting the implicit linker search path for the
1199 // current architecture. If the library appears in an implicit link
1200 // directory then just report the file name without the directory
1201 // portion. This will allow the system linker to locate the proper
1202 // library for the architecture at link time.
1203 this->AddUserItem(file, false);
1205 // Make sure the link directory ordering will find the library.
1206 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1211 //----------------------------------------------------------------------------
1212 void cmComputeLinkInformation::AddUserItem(std::string const& item,
1215 // This is called to handle a link item that does not match a CMake
1216 // target and is not a full path. We check here if it looks like a
1217 // library file name to automatically request the proper link type
1218 // from the linker. For example:
1221 // libfoo.a ==> -Wl,-Bstatic -lfoo
1223 // Pass flags through untouched.
1224 if(item[0] == '-' || item[0] == '$' || item[0] == '`')
1226 // if this is a -l option then we might need to warn about
1227 // CMP0003 so put it in OldUserFlagItems, if it is not a -l
1228 // or -Wl,-l (-framework -pthread), then allow it without a
1229 // CMP0003 as -L will not affect those other linker flags
1230 if(item.find("-l") == 0 || item.find("-Wl,-l") == 0)
1232 // This is a linker option provided by the user.
1233 this->OldUserFlagItems.push_back(item);
1236 // Restore the target link type since this item does not specify
1238 this->SetCurrentLinkType(this->StartLinkType);
1240 // Use the item verbatim.
1241 this->Items.push_back(Item(item, false));
1245 // Parse out the prefix, base, and suffix components of the
1246 // library name. If the name matches that of a shared or static
1247 // library then set the link type accordingly.
1249 // Search for shared library names first because some platforms
1250 // have shared libraries with names that match the static library
1251 // pattern. For example cygwin and msys use the convention
1252 // libfoo.dll.a for import libraries and libfoo.a for static
1253 // libraries. On AIX a library with the name libfoo.a can be
1256 if(this->ExtractSharedLibraryName.find(item))
1258 // This matches a shared library file name.
1259 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1260 fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
1261 this->ExtractSharedLibraryName.match(1).c_str(),
1262 this->ExtractSharedLibraryName.match(2).c_str(),
1263 this->ExtractSharedLibraryName.match(3).c_str());
1265 // Set the link type to shared.
1266 this->SetCurrentLinkType(LinkShared);
1268 // Use just the library name so the linker will search.
1269 lib = this->ExtractSharedLibraryName.match(2);
1271 else if(this->ExtractStaticLibraryName.find(item))
1273 // This matches a static library file name.
1274 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1275 fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
1276 this->ExtractStaticLibraryName.match(1).c_str(),
1277 this->ExtractStaticLibraryName.match(2).c_str(),
1278 this->ExtractStaticLibraryName.match(3).c_str());
1280 // Set the link type to static.
1281 this->SetCurrentLinkType(LinkStatic);
1283 // Use just the library name so the linker will search.
1284 lib = this->ExtractStaticLibraryName.match(2);
1286 else if(this->ExtractAnyLibraryName.find(item))
1288 // This matches a library file name.
1289 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1290 fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
1291 this->ExtractAnyLibraryName.match(1).c_str(),
1292 this->ExtractAnyLibraryName.match(2).c_str(),
1293 this->ExtractAnyLibraryName.match(3).c_str());
1295 // Restore the target link type since this item does not specify
1297 this->SetCurrentLinkType(this->StartLinkType);
1299 // Use just the library name so the linker will search.
1300 lib = this->ExtractAnyLibraryName.match(2);
1304 // This is a name specified by the user.
1307 this->OldUserFlagItems.push_back(item);
1310 // We must ask the linker to search for a library with this name.
1311 // Restore the target link type since this item does not specify
1313 this->SetCurrentLinkType(this->StartLinkType);
1317 // Create an option to ask the linker to search for the library.
1318 std::string out = this->LibLinkFlag;
1320 out += this->LibLinkSuffix;
1321 this->Items.push_back(Item(out, false));
1323 // Here we could try to find the library the linker will find and
1324 // add a runtime information entry for it. It would probably not be
1325 // reliable and we want to encourage use of full paths for library
1329 //----------------------------------------------------------------------------
1330 void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
1332 // Try to separate the framework name and path.
1333 if(!this->SplitFramework.find(item.c_str()))
1336 e << "Could not parse framework path \"" << item << "\" "
1337 << "linked by target " << this->Target->GetName() << ".";
1338 cmSystemTools::Error(e.str().c_str());
1342 // Add the directory portion to the framework search path.
1343 this->AddFrameworkPath(this->SplitFramework.match(1));
1345 // Add the item using the -framework option.
1346 this->Items.push_back(Item("-framework", false));
1347 std::string fw = this->SplitFramework.match(2);
1348 fw = this->LocalGenerator->EscapeForShell(fw.c_str());
1349 this->Items.push_back(Item(fw, false));
1352 //----------------------------------------------------------------------------
1353 void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
1355 if(this->Makefile->IsOn("APPLE")
1356 && cmSystemTools::IsPathToFramework(item.c_str()))
1358 this->AddFrameworkItem(item);
1362 this->DropDirectoryItem(item);
1366 //----------------------------------------------------------------------------
1367 void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
1369 // A full path to a directory was found as a link item. Warn the
1372 e << "WARNING: Target \"" << this->Target->GetName()
1373 << "\" requests linking to directory \"" << item << "\". "
1374 << "Targets may link only to libraries. "
1375 << "CMake is dropping the item.";
1376 cmSystemTools::Message(e.str().c_str());
1379 //----------------------------------------------------------------------------
1380 void cmComputeLinkInformation::ComputeFrameworkInfo()
1382 // Avoid adding implicit framework paths.
1383 std::vector<std::string> implicitDirVec;
1385 // Get platform-wide implicit directories.
1386 if(const char* implicitLinks = this->Makefile->GetDefinition
1387 ("CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"))
1389 cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1392 // Get language-specific implicit directories.
1393 std::string implicitDirVar = "CMAKE_";
1394 implicitDirVar += this->LinkLanguage;
1395 implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES";
1396 if(const char* implicitDirs =
1397 this->Makefile->GetDefinition(implicitDirVar.c_str()))
1399 cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1402 for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1403 i != implicitDirVec.end(); ++i)
1405 this->FrameworkPathsEmmitted.insert(*i);
1408 // Regular expression to extract a framework path and name.
1409 this->SplitFramework.compile("(.*)/(.*)\\.framework$");
1412 //----------------------------------------------------------------------------
1413 void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
1415 if(this->FrameworkPathsEmmitted.insert(p).second)
1417 this->FrameworkPaths.push_back(p);
1421 //----------------------------------------------------------------------------
1422 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
1424 // This platform will use the path to a library as its soname if the
1425 // library is given via path and was not built with an soname. If
1426 // this is a shared library that might be the case.
1427 std::string file = cmSystemTools::GetFilenameName(item);
1428 if(this->ExtractSharedLibraryName.find(file))
1430 // If we can guess the soname fairly reliably then assume the
1431 // library has one. Otherwise assume the library has no builtin
1434 if(!cmSystemTools::GuessLibrarySOName(item, soname))
1436 this->AddSharedLibNoSOName(item);
1443 //----------------------------------------------------------------------------
1444 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
1446 // We have a full path to a shared library with no soname. We need
1447 // to ask the linker to locate the item because otherwise the path
1448 // we give to it will be embedded in the target linked. Then at
1449 // runtime the dynamic linker will search for the library using the
1450 // path instead of just the name.
1451 std::string file = cmSystemTools::GetFilenameName(item);
1452 this->AddUserItem(file, false);
1454 // Make sure the link directory ordering will find the library.
1455 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1458 //----------------------------------------------------------------------------
1459 void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
1460 std::string const& file)
1462 // Do not depend on things that do not exist.
1463 std::vector<std::string>::iterator i =
1464 std::find(this->Depends.begin(), this->Depends.end(), item);
1465 if(i != this->Depends.end())
1467 this->Depends.erase(i);
1470 // Tell the linker to search for the item and provide the proper
1471 // path for it. Do not contribute to any CMP0003 warning (do not
1472 // put in OldLinkDirItems or OldUserFlagItems).
1473 this->AddUserItem(file, false);
1474 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1476 // Produce any needed message.
1477 switch(this->Target->GetPolicyStatusCMP0008())
1479 case cmPolicies::WARN:
1481 // Print the warning at most once for this item.
1482 std::string wid = "CMP0008-WARNING-GIVEN-";
1484 if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
1486 this->CMakeInstance->SetProperty(wid.c_str(), "1");
1488 w << (this->Makefile->GetPolicies()
1489 ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n"
1490 << "Target \"" << this->Target->GetName() << "\" links to item\n"
1491 << " " << item << "\n"
1492 << "which is a full-path but not a valid library file name.";
1493 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1494 this->Target->GetBacktrace());
1497 case cmPolicies::OLD:
1498 // OLD behavior does not warn.
1500 case cmPolicies::NEW:
1501 // NEW behavior will not get here.
1503 case cmPolicies::REQUIRED_IF_USED:
1504 case cmPolicies::REQUIRED_ALWAYS:
1507 e << (this->Makefile->GetPolicies()->
1508 GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n"
1509 << "Target \"" << this->Target->GetName() << "\" links to item\n"
1510 << " " << item << "\n"
1511 << "which is a full-path but not a valid library file name.";
1512 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1513 this->Target->GetBacktrace());
1519 //----------------------------------------------------------------------------
1520 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1522 // Support broken projects if necessary.
1523 if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
1524 !this->OldLinkDirMode)
1529 // Enforce policy constraints.
1530 switch(this->Target->GetPolicyStatusCMP0003())
1532 case cmPolicies::WARN:
1533 if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1535 this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
1537 this->PrintLinkPolicyDiagnosis(w);
1538 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1539 this->Target->GetBacktrace());
1541 case cmPolicies::OLD:
1542 // OLD behavior is to add the paths containing libraries with
1543 // known full paths as link directories.
1545 case cmPolicies::NEW:
1546 // Should never happen due to assignment of OldLinkDirMode
1548 case cmPolicies::REQUIRED_IF_USED:
1549 case cmPolicies::REQUIRED_ALWAYS:
1552 e << (this->Makefile->GetPolicies()->
1553 GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
1554 this->PrintLinkPolicyDiagnosis(e);
1555 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1556 this->Target->GetBacktrace());
1561 // Add the link directories for full path items.
1562 for(std::vector<std::string>::const_iterator
1563 i = this->OldLinkDirItems.begin();
1564 i != this->OldLinkDirItems.end(); ++i)
1566 this->OrderLinkerSearchPath->AddLinkLibrary(*i);
1571 //----------------------------------------------------------------------------
1572 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
1574 // Tell the user what to do.
1575 os << "Policy CMP0003 should be set before this line. "
1576 << "Add code such as\n"
1577 << " if(COMMAND cmake_policy)\n"
1578 << " cmake_policy(SET CMP0003 NEW)\n"
1579 << " endif(COMMAND cmake_policy)\n"
1580 << "as early as possible but after the most recent call to "
1581 << "cmake_minimum_required or cmake_policy(VERSION). ";
1583 // List the items that might need the old-style paths.
1584 os << "This warning appears because target \""
1585 << this->Target->GetName() << "\" "
1586 << "links to some libraries for which the linker must search:\n";
1588 // Format the list of unknown items to be as short as possible while
1589 // still fitting in the allowed width (a true solution would be the
1590 // bin packing problem if we were allowed to change the order).
1591 std::string::size_type max_size = 76;
1593 const char* sep = " ";
1594 for(std::vector<std::string>::const_iterator
1595 i = this->OldUserFlagItems.begin();
1596 i != this->OldUserFlagItems.end(); ++i)
1598 // If the addition of another item will exceed the limit then
1599 // output the current line and reset it. Note that the separator
1600 // is either " " or ", " which is always 2 characters.
1601 if(!line.empty() && (line.size() + i->size() + 2) > max_size)
1609 // Convert to the other separator.
1618 // List the paths old behavior is adding.
1619 os << "and other libraries with known full path:\n";
1620 std::set<cmStdString> emitted;
1621 for(std::vector<std::string>::const_iterator
1622 i = this->OldLinkDirItems.begin();
1623 i != this->OldLinkDirItems.end(); ++i)
1625 if(emitted.insert(cmSystemTools::GetFilenamePath(*i)).second)
1627 os << " " << *i << "\n";
1632 os << "CMake is adding directories in the second list to the linker "
1633 << "search path in case they are needed to find libraries from the "
1634 << "first list (for backwards compatibility with CMake 2.4). "
1635 << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1636 << "behavior explicitly. "
1637 << "Run \"cmake --help-policy CMP0003\" for more information.";
1640 //----------------------------------------------------------------------------
1641 void cmComputeLinkInformation::LoadImplicitLinkInfo()
1643 std::vector<std::string> implicitDirVec;
1645 // Get platform-wide implicit directories.
1646 if(const char* implicitLinks =
1647 (this->Makefile->GetDefinition
1648 ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
1650 cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
1653 // Append library architecture to all implicit platform directories
1654 // and add them to the set
1655 if(const char* libraryArch =
1656 this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
1658 for (std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1659 i != implicitDirVec.end(); ++i)
1661 this->ImplicitLinkDirs.insert(*i + "/" + libraryArch);
1665 // Get language-specific implicit directories.
1666 std::string implicitDirVar = "CMAKE_";
1667 implicitDirVar += this->LinkLanguage;
1668 implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
1669 if(const char* implicitDirs =
1670 this->Makefile->GetDefinition(implicitDirVar.c_str()))
1672 cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec);
1675 // Store implicit link directories.
1676 for(std::vector<std::string>::const_iterator i = implicitDirVec.begin();
1677 i != implicitDirVec.end(); ++i)
1679 this->ImplicitLinkDirs.insert(*i);
1682 // Get language-specific implicit libraries.
1683 std::vector<std::string> implicitLibVec;
1684 std::string implicitLibVar = "CMAKE_";
1685 implicitLibVar += this->LinkLanguage;
1686 implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
1687 if(const char* implicitLibs =
1688 this->Makefile->GetDefinition(implicitLibVar.c_str()))
1690 cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec);
1693 // Store implicit link libraries.
1694 for(std::vector<std::string>::const_iterator i = implicitLibVec.begin();
1695 i != implicitLibVec.end(); ++i)
1697 // Items starting in '-' but not '-l' are flags, not libraries,
1698 // and should not be filtered by this implicit list.
1699 std::string const& item = *i;
1700 if(item[0] != '-' || item[1] == 'l')
1702 this->ImplicitLinkLibs.insert(item);
1706 // Get platform specific rpath link directories
1707 if(const char *rpathDirs =
1708 (this->Makefile->GetDefinition
1709 ("CMAKE_PLATFORM_RUNTIME_PATH")))
1711 cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs);
1715 //----------------------------------------------------------------------------
1716 std::vector<std::string> const&
1717 cmComputeLinkInformation::GetRuntimeSearchPath()
1719 return this->OrderRuntimeSearchPath->GetOrderedDirectories();
1722 //----------------------------------------------------------------------------
1724 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
1727 // Libraries with unknown type must be handled using just the file
1729 if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
1731 this->AddLibraryRuntimeInfo(fullPath);
1735 // Skip targets that are not shared libraries (modules cannot be linked).
1736 if(target->GetType() != cmTarget::SHARED_LIBRARY)
1741 // Try to get the soname of the library. Only files with this name
1742 // could possibly conflict.
1743 std::string soName = target->GetSOName(this->Config);
1744 const char* soname = soName.empty()? 0 : soName.c_str();
1746 // Include this library in the runtime path ordering.
1747 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
1748 if(this->LinkWithRuntimePath)
1750 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
1754 //----------------------------------------------------------------------------
1756 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
1758 // Get the name of the library from the file name.
1759 std::string file = cmSystemTools::GetFilenameName(fullPath);
1760 if(!this->ExtractSharedLibraryName.find(file.c_str()))
1762 // On some platforms (AIX) a shared library may look static.
1763 if(this->ArchivesMayBeShared)
1765 if(!this->ExtractStaticLibraryName.find(file.c_str()))
1767 // This is not the name of a shared library or archive.
1773 // This is not the name of a shared library.
1778 // Include this library in the runtime path ordering.
1779 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
1780 if(this->LinkWithRuntimePath)
1782 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
1786 //----------------------------------------------------------------------------
1787 static void cmCLI_ExpandListUnique(const char* str,
1788 std::vector<std::string>& out,
1789 std::set<cmStdString>& emitted)
1791 std::vector<std::string> tmp;
1792 cmSystemTools::ExpandListArgument(str, tmp);
1793 for(std::vector<std::string>::iterator i = tmp.begin(); i != tmp.end(); ++i)
1795 if(emitted.insert(*i).second)
1802 //----------------------------------------------------------------------------
1803 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
1806 // Select whether to generate runtime search directories.
1807 bool outputRuntime =
1808 !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
1810 // Select whether to generate an rpath for the install tree or the
1812 bool linking_for_install =
1814 this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1815 bool use_install_rpath =
1816 (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
1817 linking_for_install);
1818 bool use_build_rpath =
1819 (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
1820 !linking_for_install);
1821 bool use_link_rpath =
1822 outputRuntime && linking_for_install &&
1823 !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
1824 this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1826 // Construct the RPATH.
1827 std::set<cmStdString> emitted;
1828 if(use_install_rpath)
1830 const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
1831 cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted);
1833 if(use_build_rpath || use_link_rpath)
1835 std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
1836 for(std::vector<std::string>::const_iterator ri = rdirs.begin();
1837 ri != rdirs.end(); ++ri)
1839 // Put this directory in the rpath if using build-tree rpath
1840 // support or if using the link path as an rpath.
1843 if(emitted.insert(*ri).second)
1845 runtimeDirs.push_back(*ri);
1848 else if(use_link_rpath)
1850 // Do not add any path inside the source or build tree.
1851 const char* topSourceDir = this->Makefile->GetHomeDirectory();
1852 const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
1853 if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
1854 !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
1855 !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
1856 !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
1858 if(emitted.insert(*ri).second)
1860 runtimeDirs.push_back(*ri);
1867 // Add runtime paths required by the languages to always be
1868 // present. This is done even when skipping rpath support.
1870 cmTarget::LinkClosure const* lc =
1871 this->Target->GetLinkClosure(this->Config, this->HeadTarget);
1872 for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
1873 li != lc->Languages.end(); ++li)
1875 std::string useVar = "CMAKE_" + *li +
1876 "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH";
1877 if(this->Makefile->IsOn(useVar.c_str()))
1879 std::string dirVar = "CMAKE_" + *li +
1880 "_IMPLICIT_LINK_DIRECTORIES";
1881 if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
1883 cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted);
1889 // Add runtime paths required by the platform to always be
1890 // present. This is done even when skipping rpath support.
1891 cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted);
1894 //----------------------------------------------------------------------------
1895 std::string cmComputeLinkInformation::GetRPathString(bool for_install)
1897 // Get the directories to use.
1898 std::vector<std::string> runtimeDirs;
1899 this->GetRPath(runtimeDirs, for_install);
1901 // Concatenate the paths.
1903 const char* sep = "";
1904 for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
1905 ri != runtimeDirs.end(); ++ri)
1907 // Separate from previous path.
1909 sep = this->GetRuntimeSep().c_str();
1915 // If the rpath will be replaced at install time, prepare space.
1916 if(!for_install && this->RuntimeUseChrpath)
1920 // Add one trailing separator so the linker does not re-use the
1921 // rpath .dynstr entry for a symbol name that happens to match
1922 // the end of the rpath string.
1923 rpath += this->GetRuntimeSep();
1926 // Make sure it is long enough to hold the replacement value.
1927 std::string::size_type minLength = this->GetChrpathString().length();
1928 while(rpath.length() < minLength)
1930 rpath += this->GetRuntimeSep();
1937 //----------------------------------------------------------------------------
1938 std::string cmComputeLinkInformation::GetChrpathString()
1940 if(!this->RuntimeUseChrpath)
1945 return this->GetRPathString(true);