Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmComputeLinkInformation.cxx
blobad6e9407e79808d6c5cd467cbdb430b048e69cc7
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmComputeLinkInformation.cxx,v $
5 Language: C++
6 Date: $Date: 2008-09-15 17:30:07 $
7 Version: $Revision: 1.44 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmComputeLinkInformation.h"
19 #include "cmComputeLinkDepends.h"
20 #include "cmOrderDirectories.h"
22 #include "cmGlobalGenerator.h"
23 #include "cmLocalGenerator.h"
24 #include "cmMakefile.h"
25 #include "cmTarget.h"
26 #include "cmake.h"
28 #include <ctype.h>
30 //#define CM_COMPUTE_LINK_INFO_DEBUG
33 Notes about linking on various platforms:
35 ------------------------------------------------------------------------------
37 Linux, FreeBSD, Mac OS X, IRIX, Sun, Windows:
39 Linking to libraries using the full path works fine.
41 ------------------------------------------------------------------------------
43 On AIX, more work is needed.
45 The "-bnoipath" option is needed. From "man ld":
47 Note: If you specify a shared object, or an archive file
48 containing a shared object, with an absolute or relative path
49 name, instead of with the -lName flag, the path name is
50 included in the import file ID string in the loader section of
51 the output file. You can override this behavior with the
52 -bnoipath option.
54 noipath
56 For shared objects listed on the command-line, rather than
57 specified with the -l flag, use a null path component when
58 listing the shared object in the loader section of the
59 output file. A null path component is always used for
60 shared objects specified with the -l flag. This option
61 does not affect the specification of a path component by
62 using a line beginning with #! in an import file. The
63 default is the ipath option.
65 This prevents the full path specified on the compile line from being
66 compiled directly into the binary.
68 By default the linker places -L paths in the embedded runtime path.
69 In order to implement CMake's RPATH interface correctly, we need the
70 -blibpath:Path option. From "man ld":
72 libpath:Path
74 Uses Path as the library path when writing the loader section
75 of the output file. Path is neither checked for validity nor
76 used when searching for libraries specified by the -l flag.
77 Path overrides any library paths generated when the -L flag is
78 used.
80 If you do not specify any -L flags, or if you specify the
81 nolibpath option, the default library path information is
82 written in the loader section of the output file. The default
83 library path information is the value of the LIBPATH
84 environment variable if it is defined, and /usr/lib:/lib,
85 otherwise.
87 We can pass -Wl,-blibpath:/usr/lib:/lib always to avoid the -L stuff
88 and not break when the user sets LIBPATH. Then if we want to add an
89 rpath we insert it into the option before /usr/lib.
91 ------------------------------------------------------------------------------
93 On HP-UX, more work is needed. There are differences between
94 versions.
96 ld: 92453-07 linker linker ld B.10.33 990520
98 Linking with a full path works okay for static and shared libraries.
99 The linker seems to always put the full path to where the library
100 was found in the binary whether using a full path or -lfoo syntax.
101 Transitive link dependencies work just fine due to the full paths.
103 It has the "-l:libfoo.sl" option. The +nodefaultrpath is accepted
104 but not documented and does not seem to do anything. There is no
105 +forceload option.
107 ld: 92453-07 linker ld HP Itanium(R) B.12.41 IPF/IPF
109 Linking with a full path works okay for static libraries.
111 Linking with a full path works okay for shared libraries. However
112 dependent (transitive) libraries of those linked directly must be
113 either found with an rpath stored in the direct dependencies or
114 found in -L paths as if they were specified with "-l:libfoo.sl"
115 (really "-l:<soname>"). The search matches that of the dynamic
116 loader but only with -L paths. In other words, if we have an
117 executable that links to shared library bar which links to shared
118 library foo, the link line for the exe must contain
120 /dir/with/bar/libbar.sl -L/dir/with/foo
122 It does not matter whether the exe wants to link to foo directly or
123 whether /dir/with/foo/libfoo.sl is listed. The -L path must still
124 be present. It should match the runtime path computed for the
125 executable taking all directly and transitively linked libraries
126 into account.
128 The "+nodefaultrpath" option should be used to avoid getting -L
129 paths in the rpath unless we add our own rpath with +b. This means
130 that skip-build-rpath should use this option.
132 See documentation in "man ld", "man dld.so", and
133 http://docs.hp.com/en/B2355-90968/creatingandusinglibraries.htm
135 +[no]defaultrpath
136 +defaultrpath is the default. Include any paths that are
137 specified with -L in the embedded path, unless you specify the
138 +b option. If you use +b, only the path list specified by +b is
139 in the embedded path.
141 The +nodefaultrpath option removes all library paths that were
142 specified with the -L option from the embedded path. The linker
143 searches the library paths specified by the -L option at link
144 time. At run time, the only library paths searched are those
145 specified by the environment variables LD_LIBRARY_PATH and
146 SHLIB_PATH, library paths specified by the +b linker option, and
147 finally the default library paths.
149 +rpathfirst
150 This option will cause the paths specified in RPATH (embedded
151 path) to be used before the paths specified in LD_LIBRARY_PATH
152 or SHLIB_PATH, in searching for shared libraries. This changes
153 the default search order of LD_LIBRARY_PATH, SHLIB_PATH, and
154 RPATH (embedded path).
156 ------------------------------------------------------------------------------
157 Notes about dependent (transitive) shared libraries:
159 On non-Windows systems shared libraries may have transitive
160 dependencies. In order to support LINK_INTERFACE_LIBRARIES we must
161 support linking to a shared library without listing all the libraries
162 to which it links. Some linkers want to be able to find the
163 transitive dependencies (dependent libraries) of shared libraries
164 listed on the command line.
166 - On Windows, DLLs are not directly linked, and the import libraries
167 have no transitive dependencies.
169 - On Mac, we need to actually list the transitive dependencies.
170 Otherwise when using -isysroot for universal binaries it cannot
171 find the dependent libraries. Listing them on the command line
172 tells the linker where to find them, but unfortunately also links
173 the library.
175 - On HP-UX, the linker wants to find the transitive dependencies of
176 shared libraries in the -L paths even if the dependent libraries
177 are given on the link line.
179 - On AIX the transitive dependencies are not needed.
181 - On SGI, the linker wants to find the transitive dependencies of
182 shared libraries in the -L paths if they are not given on the link
183 line. Transitive linking can be disabled using the options
185 -no_transitive_link -Wl,-no_transitive_link
187 which disable it. Both options must be given when invoking the
188 linker through the compiler.
190 - On Sun, the linker wants to find the transitive dependencies of
191 shared libraries in the -L paths if they are not given on the link
192 line.
194 - On Linux, FreeBSD, and QNX:
196 The linker wants to find the transitive dependencies of shared
197 libraries in the "-rpath-link" paths option if they have not been
198 given on the link line. The option is like rpath but just for
199 link time:
201 -Wl,-rpath-link,"/path1:/path2"
203 For -rpath-link, we need a separate runtime path ordering pass
204 including just the dependent libraries that are not linked.
206 For -L paths on non-HP, we can do the same thing as with rpath-link
207 but put the results in -L paths. The paths should be listed at the
208 end to avoid conflicting with user search paths (?).
210 For -L paths on HP, we should do a runtime path ordering pass with
211 all libraries, both linked and non-linked. Even dependent
212 libraries that are also linked need to be listed in -L paths.
214 In our implementation we add all dependent libraries to the runtime
215 path computation. Then the auto-generated RPATH will find everything.
217 ------------------------------------------------------------------------------
218 Notes about shared libraries with not builtin soname:
220 Some UNIX shared libraries may be created with no builtin soname. On
221 some platforms such libraries cannot be linked using the path to their
222 location because the linker will copy the path into the field used to
223 find the library at runtime.
225 Apple: ../libfoo.dylib ==> libfoo.dylib # ok, uses install_name
226 SGI: ../libfoo.so ==> libfoo.so # ok
227 AIX: ../libfoo.so ==> libfoo.so # ok
228 Linux: ../libfoo.so ==> ../libfoo.so # bad
229 HP-UX: ../libfoo.so ==> ../libfoo.so # bad
230 Sun: ../libfoo.so ==> ../libfoo.so # bad
231 FreeBSD: ../libfoo.so ==> ../libfoo.so # bad
233 In order to link these libraries we need to use the old-style split
234 into -L.. and -lfoo options. This should be fairly safe because most
235 problems with -lfoo options were related to selecting shared libraries
236 instead of static but in this case we want the shared lib. Link
237 directory ordering needs to be done to make sure these shared
238 libraries are found first. There should be very few restrictions
239 because this need be done only for shared libraries without soname-s.
243 //----------------------------------------------------------------------------
244 cmComputeLinkInformation
245 ::cmComputeLinkInformation(cmTarget* target, const char* config)
247 // Store context information.
248 this->Target = target;
249 this->Makefile = this->Target->GetMakefile();
250 this->LocalGenerator = this->Makefile->GetLocalGenerator();
251 this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
252 this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
254 // The configuration being linked.
255 this->Config = config;
257 // Allocate internals.
258 this->OrderLinkerSearchPath =
259 new cmOrderDirectories(this->GlobalGenerator, target,
260 "linker search path");
261 this->OrderRuntimeSearchPath =
262 new cmOrderDirectories(this->GlobalGenerator, target,
263 "runtime search path");
264 this->OrderDependentRPath = 0;
266 // Get the language used for linking this target.
267 this->LinkLanguage =
268 this->Target->GetLinkerLanguage(this->GlobalGenerator);
269 if(!this->LinkLanguage)
271 // The Compute method will do nothing, so skip the rest of the
272 // initialization.
273 return;
276 // Check whether we should use an import library for linking a target.
277 this->UseImportLibrary =
278 this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
280 // On platforms without import libraries there may be a special flag
281 // to use when creating a plugin (module) that obtains symbols from
282 // the program that will load it.
283 this->LoaderFlag = 0;
284 if(!this->UseImportLibrary &&
285 this->Target->GetType() == cmTarget::MODULE_LIBRARY)
287 std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
288 loader_flag_var += this->LinkLanguage;
289 loader_flag_var += "_FLAG";
290 this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var.c_str());
293 // Get options needed to link libraries.
294 this->LibLinkFlag =
295 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
296 this->LibLinkFileFlag =
297 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
298 this->LibLinkSuffix =
299 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
301 // Get options needed to specify RPATHs.
302 this->RuntimeUseChrpath = false;
303 if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
305 const char* tType =
306 ((this->Target->GetType() == cmTarget::EXECUTABLE)?
307 "EXECUTABLE" : "SHARED_LIBRARY");
308 std::string rtVar = "CMAKE_";
309 rtVar += tType;
310 rtVar += "_RUNTIME_";
311 rtVar += this->LinkLanguage;
312 rtVar += "_FLAG";
313 std::string rtSepVar = rtVar + "_SEP";
314 this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar.c_str());
315 this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar.c_str());
316 this->RuntimeAlways =
317 (this->Makefile->
318 GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
319 this->RuntimeUseChrpath = this->Target->IsChrpathUsed();
321 // Get options needed to help find dependent libraries.
322 std::string rlVar = "CMAKE_";
323 rlVar += tType;
324 rlVar += "_RPATH_LINK_";
325 rlVar += this->LinkLanguage;
326 rlVar += "_FLAG";
327 this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar.c_str());
330 // Check if we need to include the runtime search path at link time.
332 std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
333 var += this->LinkLanguage;
334 var += "_WITH_RUNTIME_PATH";
335 this->LinkWithRuntimePath = this->Makefile->IsOn(var.c_str());
338 // Check the platform policy for missing soname case.
339 this->NoSONameUsesPath =
340 this->Makefile->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
342 // Get link type information.
343 this->ComputeLinkTypeInfo();
345 // Setup the link item parser.
346 this->ComputeItemParserInfo();
348 // Setup framework support.
349 this->ComputeFrameworkInfo();
351 // Choose a mode for dealing with shared library dependencies.
352 this->SharedDependencyMode = SharedDepModeNone;
353 if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES"))
355 this->SharedDependencyMode = SharedDepModeLink;
357 else if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS"))
359 this->SharedDependencyMode = SharedDepModeLibDir;
361 else if(!this->RPathLinkFlag.empty())
363 this->SharedDependencyMode = SharedDepModeDir;
364 this->OrderDependentRPath =
365 new cmOrderDirectories(this->GlobalGenerator, target,
366 "dependent library path");
369 // Get the implicit link directories for this platform.
370 if(const char* implicitLinks =
371 (this->Makefile->GetDefinition
372 ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
374 std::vector<std::string> implicitLinkVec;
375 cmSystemTools::ExpandListArgument(implicitLinks, implicitLinkVec);
376 for(std::vector<std::string>::const_iterator
377 i = implicitLinkVec.begin();
378 i != implicitLinkVec.end(); ++i)
380 this->ImplicitLinkDirs.insert(*i);
384 // Add the search path entries requested by the user to path ordering.
385 this->OrderLinkerSearchPath
386 ->AddUserDirectories(this->Target->GetLinkDirectories());
387 this->OrderRuntimeSearchPath
388 ->AddUserDirectories(this->Target->GetLinkDirectories());
389 this->OrderLinkerSearchPath
390 ->SetImplicitDirectories(this->ImplicitLinkDirs);
391 this->OrderRuntimeSearchPath
392 ->SetImplicitDirectories(this->ImplicitLinkDirs);
393 if(this->OrderDependentRPath)
395 this->OrderDependentRPath
396 ->SetImplicitDirectories(this->ImplicitLinkDirs);
399 // Decide whether to enable compatible library search path mode.
400 // There exists code that effectively does
402 // /path/to/libA.so -lB
404 // where -lB is meant to link to /path/to/libB.so. This is broken
405 // because it specified -lB without specifying a link directory (-L)
406 // in which to search for B. This worked in CMake 2.4 and below
407 // because -L/path/to would be added by the -L/-l split for A. In
408 // order to support such projects we need to add the directories
409 // containing libraries linked with a full path to the -L path.
410 this->OldLinkDirMode =
411 this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
412 if(this->OldLinkDirMode)
414 // Construct a mask to not bother with this behavior for link
415 // directories already specified by the user.
416 std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
417 for(std::vector<std::string>::const_iterator di = dirs.begin();
418 di != dirs.end(); ++di)
420 this->OldLinkDirMask.insert(*di);
425 //----------------------------------------------------------------------------
426 cmComputeLinkInformation::~cmComputeLinkInformation()
428 delete this->OrderLinkerSearchPath;
429 delete this->OrderRuntimeSearchPath;
430 delete this->OrderDependentRPath;
433 //----------------------------------------------------------------------------
434 cmComputeLinkInformation::ItemVector const&
435 cmComputeLinkInformation::GetItems()
437 return this->Items;
440 //----------------------------------------------------------------------------
441 std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
443 return this->OrderLinkerSearchPath->GetOrderedDirectories();
446 //----------------------------------------------------------------------------
447 std::string cmComputeLinkInformation::GetRPathLinkString()
449 // If there is no separate linker runtime search flag (-rpath-link)
450 // there is no reason to compute a string.
451 if(!this->OrderDependentRPath)
453 return "";
456 // Construct the linker runtime search path.
457 std::string rpath_link;
458 const char* sep = "";
459 std::vector<std::string> const& dirs =
460 this->OrderDependentRPath->GetOrderedDirectories();
461 for(std::vector<std::string>::const_iterator di = dirs.begin();
462 di != dirs.end(); ++di)
464 rpath_link += sep;
465 sep = ":";
466 rpath_link += *di;
468 return rpath_link;
471 //----------------------------------------------------------------------------
472 std::vector<std::string> const& cmComputeLinkInformation::GetDepends()
474 return this->Depends;
477 //----------------------------------------------------------------------------
478 std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
480 return this->FrameworkPaths;
483 //----------------------------------------------------------------------------
484 std::set<cmTarget*> const&
485 cmComputeLinkInformation::GetSharedLibrariesLinked()
487 return this->SharedLibrariesLinked;
490 //----------------------------------------------------------------------------
491 bool cmComputeLinkInformation::Compute()
493 // Skip targets that do not link.
494 if(!(this->Target->GetType() == cmTarget::EXECUTABLE ||
495 this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
496 this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
497 this->Target->GetType() == cmTarget::STATIC_LIBRARY))
499 return false;
502 // We require a link language for the target.
503 if(!this->LinkLanguage)
505 cmSystemTools::
506 Error("CMake can not determine linker language for target:",
507 this->Target->GetName());
508 return false;
511 // Compute the ordered link line items.
512 cmComputeLinkDepends cld(this->Target, this->Config);
513 cld.SetOldLinkDirMode(this->OldLinkDirMode);
514 cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
516 // Add the link line items.
517 for(cmComputeLinkDepends::EntryVector::const_iterator
518 lei = linkEntries.begin();
519 lei != linkEntries.end(); ++lei)
521 if(lei->IsSharedDep)
523 this->AddSharedDepItem(lei->Item, lei->Target);
525 else
527 this->AddItem(lei->Item, lei->Target);
531 // Restore the target link type so the correct system runtime
532 // libraries are found.
533 const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
534 if(cmSystemTools::IsOn(lss))
536 this->SetCurrentLinkType(LinkStatic);
538 else
540 this->SetCurrentLinkType(this->StartLinkType);
543 // Finish listing compatibility paths.
544 if(this->OldLinkDirMode)
546 // For CMake 2.4 bug-compatibility we need to consider the output
547 // directories of targets linked in another configuration as link
548 // directories.
549 std::set<cmTarget*> const& wrongItems = cld.GetOldWrongConfigItems();
550 for(std::set<cmTarget*>::const_iterator i = wrongItems.begin();
551 i != wrongItems.end(); ++i)
553 cmTarget* tgt = *i;
554 bool implib =
555 (this->UseImportLibrary &&
556 (tgt->GetType() == cmTarget::SHARED_LIBRARY));
557 std::string lib = tgt->GetFullPath(this->Config , implib, true);
558 this->OldLinkDirItems.push_back(lib);
562 // Finish setting up linker search directories.
563 if(!this->FinishLinkerSearchDirectories())
565 return false;
568 return true;
571 //----------------------------------------------------------------------------
572 void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
574 // Compute the proper name to use to link this library.
575 const char* config = this->Config;
576 bool impexe = (tgt && tgt->IsExecutableWithExports());
577 if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
579 // Skip linking to executables on platforms with no import
580 // libraries or loader flags.
581 return;
584 if(tgt && tgt->IsLinkable())
586 // This is a CMake target. Ask the target for its real name.
587 if(impexe && this->LoaderFlag)
589 // This link item is an executable that may provide symbols
590 // used by this target. A special flag is needed on this
591 // platform. Add it now.
592 std::string linkItem;
593 linkItem = this->LoaderFlag;
594 std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
595 true);
596 linkItem += exe;
597 this->Items.push_back(Item(linkItem, true, tgt));
598 this->Depends.push_back(exe);
600 else
602 // Decide whether to use an import library.
603 bool implib =
604 (this->UseImportLibrary &&
605 (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
607 // Pass the full path to the target file.
608 std::string lib = tgt->GetFullPath(config, implib, true);
609 this->Depends.push_back(lib);
611 this->AddTargetItem(lib, tgt);
612 this->AddLibraryRuntimeInfo(lib, tgt);
615 else
617 // This is not a CMake target. Use the name given.
618 if(cmSystemTools::FileIsFullPath(item.c_str()))
620 if(cmSystemTools::FileIsDirectory(item.c_str()))
622 // This is a directory.
623 this->AddDirectoryItem(item);
625 else
627 // Use the full path given to the library file.
628 this->Depends.push_back(item);
629 this->AddFullItem(item);
630 this->AddLibraryRuntimeInfo(item);
633 else
635 // This is a library or option specified by the user.
636 this->AddUserItem(item, true);
641 //----------------------------------------------------------------------------
642 void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
643 cmTarget* tgt)
645 // If dropping shared library dependencies, ignore them.
646 if(this->SharedDependencyMode == SharedDepModeNone)
648 return;
651 // The user may have incorrectly named an item. Skip items that are
652 // not full paths to shared libraries.
653 if(tgt)
655 // The target will provide a full path. Make sure it is a shared
656 // library.
657 if(tgt->GetType() != cmTarget::SHARED_LIBRARY)
659 return;
662 else
664 // Skip items that are not full paths. We will not be able to
665 // reliably specify them.
666 if(!cmSystemTools::FileIsFullPath(item.c_str()))
668 return;
671 // Get the name of the library from the file name.
672 std::string file = cmSystemTools::GetFilenameName(item);
673 if(!this->ExtractSharedLibraryName.find(file.c_str()))
675 // This is not the name of a shared library.
676 return;
680 // If in linking mode, just link to the shared library.
681 if(this->SharedDependencyMode == SharedDepModeLink)
683 this->AddItem(item, tgt);
684 return;
687 // Get a full path to the dependent shared library.
688 // Add it to the runtime path computation so that the target being
689 // linked will be able to find it.
690 std::string lib;
691 if(tgt)
693 lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
694 this->AddLibraryRuntimeInfo(lib, tgt);
696 else
698 lib = item;
699 this->AddLibraryRuntimeInfo(lib);
702 // Check if we need to include the dependent shared library in other
703 // path ordering.
704 cmOrderDirectories* order = 0;
705 if(this->SharedDependencyMode == SharedDepModeLibDir &&
706 !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */)
708 // Add the item to the linker search path.
709 order = this->OrderLinkerSearchPath;
711 else if(this->SharedDependencyMode == SharedDepModeDir)
713 // Add the item to the separate dependent library search path.
714 order = this->OrderDependentRPath;
716 if(order)
718 if(tgt)
720 std::string soName = tgt->GetSOName(this->Config);
721 const char* soname = soName.empty()? 0 : soName.c_str();
722 order->AddRuntimeLibrary(lib, soname);
724 else
726 order->AddRuntimeLibrary(lib);
731 //----------------------------------------------------------------------------
732 void cmComputeLinkInformation::ComputeLinkTypeInfo()
734 // Check whether archives may actually be shared libraries.
735 this->ArchivesMayBeShared =
736 this->CMakeInstance->GetPropertyAsBool(
737 "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
739 // First assume we cannot do link type stuff.
740 this->LinkTypeEnabled = false;
742 // Lookup link type selection flags.
743 const char* static_link_type_flag = 0;
744 const char* shared_link_type_flag = 0;
745 const char* target_type_str = 0;
746 switch(this->Target->GetType())
748 case cmTarget::EXECUTABLE: target_type_str = "EXE"; break;
749 case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
750 case cmTarget::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
751 default: break;
753 if(target_type_str)
755 std::string static_link_type_flag_var = "CMAKE_";
756 static_link_type_flag_var += target_type_str;
757 static_link_type_flag_var += "_LINK_STATIC_";
758 static_link_type_flag_var += this->LinkLanguage;
759 static_link_type_flag_var += "_FLAGS";
760 static_link_type_flag =
761 this->Makefile->GetDefinition(static_link_type_flag_var.c_str());
763 std::string shared_link_type_flag_var = "CMAKE_";
764 shared_link_type_flag_var += target_type_str;
765 shared_link_type_flag_var += "_LINK_DYNAMIC_";
766 shared_link_type_flag_var += this->LinkLanguage;
767 shared_link_type_flag_var += "_FLAGS";
768 shared_link_type_flag =
769 this->Makefile->GetDefinition(shared_link_type_flag_var.c_str());
772 // We can support link type switching only if all needed flags are
773 // known.
774 if(static_link_type_flag && *static_link_type_flag &&
775 shared_link_type_flag && *shared_link_type_flag)
777 this->LinkTypeEnabled = true;
778 this->StaticLinkTypeFlag = static_link_type_flag;
779 this->SharedLinkTypeFlag = shared_link_type_flag;
782 // TODO: Lookup the starting link type from the target (is it being
783 // linked statically?).
784 this->StartLinkType = LinkShared;
785 this->CurrentLinkType = this->StartLinkType;
788 //----------------------------------------------------------------------------
789 void cmComputeLinkInformation::ComputeItemParserInfo()
791 // Get possible library name prefixes.
792 cmMakefile* mf = this->Makefile;
793 this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
794 this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
796 // Import library names should be matched and treated as shared
797 // libraries for the purposes of linking.
798 this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
799 LinkShared);
800 this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
801 LinkStatic);
802 this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
803 LinkShared);
804 this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
805 LinkUnknown);
806 if(const char* linkSuffixes =
807 mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
809 std::vector<std::string> linkSuffixVec;
810 cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
811 for(std::vector<std::string>::iterator i = linkSuffixVec.begin();
812 i != linkSuffixVec.end(); ++i)
814 this->AddLinkExtension(i->c_str(), LinkUnknown);
818 // Compute a regex to match link extensions.
819 std::string libext = this->CreateExtensionRegex(this->LinkExtensions);
821 // Create regex to remove any library extension.
822 std::string reg("(.*)");
823 reg += libext;
824 this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
825 reg);
827 // Create a regex to match a library name. Match index 1 will be
828 // the prefix if it exists and empty otherwise. Match index 2 will
829 // be the library name. Match index 3 will be the library
830 // extension.
831 reg = "^(";
832 for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
833 p != this->LinkPrefixes.end(); ++p)
835 reg += *p;
836 reg += "|";
838 reg += ")";
839 reg += "([^/]*)";
841 // Create a regex to match any library name.
842 std::string reg_any = reg;
843 reg_any += libext;
844 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
845 fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
846 #endif
847 this->ExtractAnyLibraryName.compile(reg_any.c_str());
849 // Create a regex to match static library names.
850 if(!this->StaticLinkExtensions.empty())
852 std::string reg_static = reg;
853 reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
854 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
855 fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
856 #endif
857 this->ExtractStaticLibraryName.compile(reg_static.c_str());
860 // Create a regex to match shared library names.
861 if(!this->SharedLinkExtensions.empty())
863 std::string reg_shared = reg;
864 this->SharedRegexString =
865 this->CreateExtensionRegex(this->SharedLinkExtensions);
866 reg_shared += this->SharedRegexString;
867 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
868 fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
869 #endif
870 this->ExtractSharedLibraryName.compile(reg_shared.c_str());
874 //----------------------------------------------------------------------------
875 void cmComputeLinkInformation::AddLinkPrefix(const char* p)
877 if(p)
879 this->LinkPrefixes.insert(p);
883 //----------------------------------------------------------------------------
884 void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
886 if(e && *e)
888 if(type == LinkStatic)
890 this->StaticLinkExtensions.push_back(e);
892 if(type == LinkShared)
894 this->SharedLinkExtensions.push_back(e);
896 this->LinkExtensions.push_back(e);
900 //----------------------------------------------------------------------------
901 std::string
902 cmComputeLinkInformation
903 ::CreateExtensionRegex(std::vector<std::string> const& exts)
905 // Build a list of extension choices.
906 std::string libext = "(";
907 const char* sep = "";
908 for(std::vector<std::string>::const_iterator i = exts.begin();
909 i != exts.end(); ++i)
911 // Separate this choice from the previous one.
912 libext += sep;
913 sep = "|";
915 // Store this extension choice with the "." escaped.
916 libext += "\\";
917 #if defined(_WIN32) && !defined(__CYGWIN__)
918 libext += this->NoCaseExpression(i->c_str());
919 #else
920 libext += *i;
921 #endif
924 // Finish the list.
925 libext += ")$";
926 return libext;
929 //----------------------------------------------------------------------------
930 std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
932 std::string ret;
933 const char* s = str;
934 while(*s)
936 if(*s == '.')
938 ret += *s;
940 else
942 ret += "[";
943 ret += tolower(*s);
944 ret += toupper(*s);
945 ret += "]";
947 s++;
949 return ret;
952 //-------------------------------------------------------------------
953 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
955 // If we are changing the current link type add the flag to tell the
956 // linker about it.
957 if(this->CurrentLinkType != lt)
959 this->CurrentLinkType = lt;
961 if(this->LinkTypeEnabled)
963 switch(this->CurrentLinkType)
965 case LinkStatic:
966 this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
967 break;
968 case LinkShared:
969 this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
970 break;
971 default:
972 break;
978 //----------------------------------------------------------------------------
979 void cmComputeLinkInformation::AddTargetItem(std::string const& item,
980 cmTarget* target)
982 // This is called to handle a link item that is a full path to a target.
983 // If the target is not a static library make sure the link type is
984 // shared. This is because dynamic-mode linking can handle both
985 // shared and static libraries but static-mode can handle only
986 // static libraries. If a previous user item changed the link type
987 // to static we need to make sure it is back to shared.
988 if(target->GetType() != cmTarget::STATIC_LIBRARY)
990 this->SetCurrentLinkType(LinkShared);
993 // Keep track of shared library targets linked.
994 if(target->GetType() == cmTarget::SHARED_LIBRARY)
996 this->SharedLibrariesLinked.insert(target);
999 // Handle case of an imported shared library with no soname.
1000 if(this->NoSONameUsesPath &&
1001 target->IsImportedSharedLibWithoutSOName(this->Config))
1003 this->AddSharedLibNoSOName(item);
1004 return;
1007 // If this platform wants a flag before the full path, add it.
1008 if(!this->LibLinkFileFlag.empty())
1010 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1013 // For compatibility with CMake 2.4 include the item's directory in
1014 // the linker search path.
1015 if(this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
1016 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1017 this->OldLinkDirMask.end())
1019 this->OldLinkDirItems.push_back(item);
1022 // Now add the full path to the library.
1023 this->Items.push_back(Item(item, true, target));
1026 //----------------------------------------------------------------------------
1027 void cmComputeLinkInformation::AddFullItem(std::string const& item)
1029 // Check for the implicit link directory special case.
1030 if(this->CheckImplicitDirItem(item))
1032 return;
1035 // Check for case of shared library with no builtin soname.
1036 if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
1038 return;
1041 // Full path libraries should specify a valid library file name.
1042 // See documentation of CMP0008.
1043 if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
1044 (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
1045 strstr(this->GlobalGenerator->GetName(), "Xcode")))
1047 std::string file = cmSystemTools::GetFilenameName(item);
1048 if(!this->ExtractAnyLibraryName.find(file.c_str()))
1050 this->HandleBadFullItem(item, file);
1051 return;
1055 // This is called to handle a link item that is a full path.
1056 // If the target is not a static library make sure the link type is
1057 // shared. This is because dynamic-mode linking can handle both
1058 // shared and static libraries but static-mode can handle only
1059 // static libraries. If a previous user item changed the link type
1060 // to static we need to make sure it is back to shared.
1061 if(this->LinkTypeEnabled)
1063 std::string name = cmSystemTools::GetFilenameName(item);
1064 if(this->ExtractSharedLibraryName.find(name))
1066 this->SetCurrentLinkType(LinkShared);
1068 else if(!this->ExtractStaticLibraryName.find(item))
1070 // We cannot determine the type. Assume it is the target's
1071 // default type.
1072 this->SetCurrentLinkType(this->StartLinkType);
1076 // For compatibility with CMake 2.4 include the item's directory in
1077 // the linker search path.
1078 if(this->OldLinkDirMode &&
1079 this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
1080 this->OldLinkDirMask.end())
1082 this->OldLinkDirItems.push_back(item);
1085 // If this platform wants a flag before the full path, add it.
1086 if(!this->LibLinkFileFlag.empty())
1088 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1091 // Now add the full path to the library.
1092 this->Items.push_back(Item(item, true));
1095 //----------------------------------------------------------------------------
1096 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
1098 // We only switch to a pathless item if the link type may be
1099 // enforced. Fortunately only platforms that support link types
1100 // seem to have magic per-architecture implicit link directories.
1101 if(!this->LinkTypeEnabled)
1103 return false;
1106 // Check if this item is in an implicit link directory.
1107 std::string dir = cmSystemTools::GetFilenamePath(item);
1108 if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
1110 // Only libraries in implicit link directories are converted to
1111 // pathless items.
1112 return false;
1115 // Only apply the policy below if the library file is one that can
1116 // be found by the linker.
1117 std::string file = cmSystemTools::GetFilenameName(item);
1118 if(!this->ExtractAnyLibraryName.find(file))
1120 return false;
1123 // Many system linkers support multiple architectures by
1124 // automatically selecting the implicit linker search path for the
1125 // current architecture. If the library appears in an implicit link
1126 // directory then just report the file name without the directory
1127 // portion. This will allow the system linker to locate the proper
1128 // library for the architecture at link time.
1129 this->AddUserItem(file, false);
1131 // Make sure the link directory ordering will find the library.
1132 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1134 return true;
1137 //----------------------------------------------------------------------------
1138 void cmComputeLinkInformation::AddUserItem(std::string const& item,
1139 bool pathNotKnown)
1141 // This is called to handle a link item that does not match a CMake
1142 // target and is not a full path. We check here if it looks like a
1143 // library file name to automatically request the proper link type
1144 // from the linker. For example:
1146 // foo ==> -lfoo
1147 // libfoo.a ==> -Wl,-Bstatic -lfoo
1148 std::string lib;
1150 // Parse out the prefix, base, and suffix components of the
1151 // library name. If the name matches that of a shared or static
1152 // library then set the link type accordingly.
1154 // Search for shared library names first because some platforms
1155 // have shared libraries with names that match the static library
1156 // pattern. For example cygwin and msys use the convention
1157 // libfoo.dll.a for import libraries and libfoo.a for static
1158 // libraries. On AIX a library with the name libfoo.a can be
1159 // shared!
1160 if(this->ExtractSharedLibraryName.find(item))
1162 // This matches a shared library file name.
1163 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1164 fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
1165 this->ExtractSharedLibraryName.match(1).c_str(),
1166 this->ExtractSharedLibraryName.match(2).c_str(),
1167 this->ExtractSharedLibraryName.match(3).c_str());
1168 #endif
1169 // Set the link type to shared.
1170 this->SetCurrentLinkType(LinkShared);
1172 // Use just the library name so the linker will search.
1173 lib = this->ExtractSharedLibraryName.match(2);
1175 else if(this->ExtractStaticLibraryName.find(item))
1177 // This matches a static library file name.
1178 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1179 fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
1180 this->ExtractStaticLibraryName.match(1).c_str(),
1181 this->ExtractStaticLibraryName.match(2).c_str(),
1182 this->ExtractStaticLibraryName.match(3).c_str());
1183 #endif
1184 // Set the link type to static.
1185 this->SetCurrentLinkType(LinkStatic);
1187 // Use just the library name so the linker will search.
1188 lib = this->ExtractStaticLibraryName.match(2);
1190 else if(this->ExtractAnyLibraryName.find(item))
1192 // This matches a library file name.
1193 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1194 fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
1195 this->ExtractAnyLibraryName.match(1).c_str(),
1196 this->ExtractAnyLibraryName.match(2).c_str(),
1197 this->ExtractAnyLibraryName.match(3).c_str());
1198 #endif
1199 // Restore the target link type since this item does not specify
1200 // one.
1201 this->SetCurrentLinkType(this->StartLinkType);
1203 // Use just the library name so the linker will search.
1204 lib = this->ExtractAnyLibraryName.match(2);
1206 else if(item[0] == '-' || item[0] == '$' || item[0] == '`')
1208 // if this is a -l option then we might need to warn about
1209 // CMP0003 so put it in OldUserFlagItems, if it is not a -l
1210 // or -Wl,-l (-framework -pthread), then allow it without a
1211 // CMP0003 as -L will not affect those other linker flags
1212 if(item.find("-l") == 0 || item.find("-Wl,-l") == 0)
1214 // This is a linker option provided by the user.
1215 this->OldUserFlagItems.push_back(item);
1218 // Restore the target link type since this item does not specify
1219 // one.
1220 this->SetCurrentLinkType(this->StartLinkType);
1222 // Use the item verbatim.
1223 this->Items.push_back(Item(item, false));
1224 return;
1226 else
1228 // This is a name specified by the user.
1229 if(pathNotKnown)
1231 this->OldUserFlagItems.push_back(item);
1234 // We must ask the linker to search for a library with this name.
1235 // Restore the target link type since this item does not specify
1236 // one.
1237 this->SetCurrentLinkType(this->StartLinkType);
1238 lib = item;
1241 // Create an option to ask the linker to search for the library.
1242 std::string out = this->LibLinkFlag;
1243 out += lib;
1244 out += this->LibLinkSuffix;
1245 this->Items.push_back(Item(out, false));
1247 // Here we could try to find the library the linker will find and
1248 // add a runtime information entry for it. It would probably not be
1249 // reliable and we want to encourage use of full paths for library
1250 // specification.
1253 //----------------------------------------------------------------------------
1254 void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
1256 // Try to separate the framework name and path.
1257 if(!this->SplitFramework.find(item.c_str()))
1259 cmOStringStream e;
1260 e << "Could not parse framework path \"" << item << "\" "
1261 << "linked by target " << this->Target->GetName() << ".";
1262 cmSystemTools::Error(e.str().c_str());
1263 return;
1266 // Add the directory portion to the framework search path.
1267 this->AddFrameworkPath(this->SplitFramework.match(1));
1269 // Add the item using the -framework option.
1270 std::string fw = "-framework ";
1271 fw += this->SplitFramework.match(2);
1272 this->Items.push_back(Item(fw, false));
1275 //----------------------------------------------------------------------------
1276 void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
1278 #ifdef __APPLE__
1279 if(cmSystemTools::IsPathToFramework(item.c_str()))
1281 this->AddFrameworkItem(item);
1283 else
1284 #endif
1286 this->DropDirectoryItem(item);
1290 //----------------------------------------------------------------------------
1291 void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
1293 // A full path to a directory was found as a link item. Warn the
1294 // user.
1295 cmOStringStream e;
1296 e << "WARNING: Target \"" << this->Target->GetName()
1297 << "\" requests linking to directory \"" << item << "\". "
1298 << "Targets may link only to libraries. "
1299 << "CMake is dropping the item.";
1300 cmSystemTools::Message(e.str().c_str());
1303 //----------------------------------------------------------------------------
1304 void cmComputeLinkInformation::ComputeFrameworkInfo()
1306 // Avoid adding system framework paths. See "man ld" on OS X.
1307 this->FrameworkPathsEmmitted.insert("/Library/Frameworks");
1308 this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks");
1309 this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks");
1311 // Regular expression to extract a framework path and name.
1312 this->SplitFramework.compile("(.*)/(.*)\\.framework$");
1315 //----------------------------------------------------------------------------
1316 void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
1318 if(this->FrameworkPathsEmmitted.insert(p).second)
1320 this->FrameworkPaths.push_back(p);
1324 //----------------------------------------------------------------------------
1325 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
1327 // This platform will use the path to a library as its soname if the
1328 // library is given via path and was not built with an soname. If
1329 // this is a shared library that might be the case.
1330 std::string file = cmSystemTools::GetFilenameName(item);
1331 if(this->ExtractSharedLibraryName.find(file))
1333 // If we can guess the soname fairly reliably then assume the
1334 // library has one. Otherwise assume the library has no builtin
1335 // soname.
1336 std::string soname;
1337 if(!cmSystemTools::GuessLibrarySOName(item, soname))
1339 this->AddSharedLibNoSOName(item);
1340 return true;
1343 return false;
1346 //----------------------------------------------------------------------------
1347 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
1349 // We have a full path to a shared library with no soname. We need
1350 // to ask the linker to locate the item because otherwise the path
1351 // we give to it will be embedded in the target linked. Then at
1352 // runtime the dynamic linker will search for the library using the
1353 // path instead of just the name.
1354 std::string file = cmSystemTools::GetFilenameName(item);
1355 this->AddUserItem(file, false);
1357 // Make sure the link directory ordering will find the library.
1358 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1361 //----------------------------------------------------------------------------
1362 void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
1363 std::string const& file)
1365 // Do not depend on things that do not exist.
1366 std::vector<std::string>::iterator i =
1367 std::find(this->Depends.begin(), this->Depends.end(), item);
1368 if(i != this->Depends.end())
1370 this->Depends.erase(i);
1373 // Tell the linker to search for the item and provide the proper
1374 // path for it. Do not contribute to any CMP0003 warning (do not
1375 // put in OldLinkDirItems or OldUserFlagItems).
1376 this->AddUserItem(file, false);
1377 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1379 // Produce any needed message.
1380 switch(this->Target->GetPolicyStatusCMP0008())
1382 case cmPolicies::WARN:
1384 // Print the warning at most once for this item.
1385 std::string wid = "CMP0008-WARNING-GIVEN-";
1386 wid += item;
1387 if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
1389 this->CMakeInstance->SetProperty(wid.c_str(), "1");
1390 cmOStringStream w;
1391 w << (this->Makefile->GetPolicies()
1392 ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n"
1393 << "Target \"" << this->Target->GetName() << "\" links to item\n"
1394 << " " << item << "\n"
1395 << "which is a full-path but not a valid library file name.";
1396 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1397 this->Target->GetBacktrace());
1400 case cmPolicies::OLD:
1401 // OLD behavior does not warn.
1402 break;
1403 case cmPolicies::NEW:
1404 // NEW behavior will not get here.
1405 break;
1406 case cmPolicies::REQUIRED_IF_USED:
1407 case cmPolicies::REQUIRED_ALWAYS:
1409 cmOStringStream e;
1410 e << (this->Makefile->GetPolicies()->
1411 GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n"
1412 << "Target \"" << this->Target->GetName() << "\" links to item\n"
1413 << " " << item << "\n"
1414 << "which is a full-path but not a valid library file name.";
1415 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1416 this->Target->GetBacktrace());
1418 break;
1422 //----------------------------------------------------------------------------
1423 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1425 // Support broken projects if necessary.
1426 if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
1427 !this->OldLinkDirMode)
1429 return true;
1432 // Enforce policy constraints.
1433 switch(this->Target->GetPolicyStatusCMP0003())
1435 case cmPolicies::WARN:
1436 if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1438 this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
1439 cmOStringStream w;
1440 this->PrintLinkPolicyDiagnosis(w);
1441 this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
1442 this->Target->GetBacktrace());
1444 case cmPolicies::OLD:
1445 // OLD behavior is to add the paths containing libraries with
1446 // known full paths as link directories.
1447 break;
1448 case cmPolicies::NEW:
1449 // Should never happen due to assignment of OldLinkDirMode
1450 return true;
1451 case cmPolicies::REQUIRED_IF_USED:
1452 case cmPolicies::REQUIRED_ALWAYS:
1454 cmOStringStream e;
1455 e << (this->Makefile->GetPolicies()->
1456 GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
1457 this->PrintLinkPolicyDiagnosis(e);
1458 this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
1459 this->Target->GetBacktrace());
1460 return false;
1464 // Add the link directories for full path items.
1465 for(std::vector<std::string>::const_iterator
1466 i = this->OldLinkDirItems.begin();
1467 i != this->OldLinkDirItems.end(); ++i)
1469 this->OrderLinkerSearchPath->AddLinkLibrary(*i);
1471 return true;
1474 //----------------------------------------------------------------------------
1475 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
1477 // Tell the user what to do.
1478 os << "Policy CMP0003 should be set before this line. "
1479 << "Add code such as\n"
1480 << " if(COMMAND cmake_policy)\n"
1481 << " cmake_policy(SET CMP0003 NEW)\n"
1482 << " endif(COMMAND cmake_policy)\n"
1483 << "as early as possible but after the most recent call to "
1484 << "cmake_minimum_required or cmake_policy(VERSION). ";
1486 // List the items that might need the old-style paths.
1487 os << "This warning appears because target \""
1488 << this->Target->GetName() << "\" "
1489 << "links to some libraries for which the linker must search:\n";
1491 // Format the list of unknown items to be as short as possible while
1492 // still fitting in the allowed width (a true solution would be the
1493 // bin packing problem if we were allowed to change the order).
1494 std::string::size_type max_size = 76;
1495 std::string line;
1496 const char* sep = " ";
1497 for(std::vector<std::string>::const_iterator
1498 i = this->OldUserFlagItems.begin();
1499 i != this->OldUserFlagItems.end(); ++i)
1501 // If the addition of another item will exceed the limit then
1502 // output the current line and reset it. Note that the separator
1503 // is either " " or ", " which is always 2 characters.
1504 if(!line.empty() && (line.size() + i->size() + 2) > max_size)
1506 os << line << "\n";
1507 sep = " ";
1508 line = "";
1510 line += sep;
1511 line += *i;
1512 // Convert to the other separator.
1513 sep = ", ";
1515 if(!line.empty())
1517 os << line << "\n";
1521 // List the paths old behavior is adding.
1522 os << "and other libraries with known full path:\n";
1523 std::set<cmStdString> emitted;
1524 for(std::vector<std::string>::const_iterator
1525 i = this->OldLinkDirItems.begin();
1526 i != this->OldLinkDirItems.end(); ++i)
1528 if(emitted.insert(cmSystemTools::GetFilenamePath(*i)).second)
1530 os << " " << *i << "\n";
1534 // Explain.
1535 os << "CMake is adding directories in the second list to the linker "
1536 << "search path in case they are needed to find libraries from the "
1537 << "first list (for backwards compatibility with CMake 2.4). "
1538 << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1539 << "behavior explicitly. "
1540 << "Run \"cmake --help-policy CMP0003\" for more information.";
1543 //----------------------------------------------------------------------------
1544 std::vector<std::string> const&
1545 cmComputeLinkInformation::GetRuntimeSearchPath()
1547 return this->OrderRuntimeSearchPath->GetOrderedDirectories();
1550 //----------------------------------------------------------------------------
1551 void
1552 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
1553 cmTarget* target)
1555 // Libraries with unknown type must be handled using just the file
1556 // on disk.
1557 if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
1559 this->AddLibraryRuntimeInfo(fullPath);
1560 return;
1563 // Skip targets that are not shared libraries (modules cannot be linked).
1564 if(target->GetType() != cmTarget::SHARED_LIBRARY)
1566 return;
1569 // Try to get the soname of the library. Only files with this name
1570 // could possibly conflict.
1571 std::string soName = target->GetSOName(this->Config);
1572 const char* soname = soName.empty()? 0 : soName.c_str();
1574 // Include this library in the runtime path ordering.
1575 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
1576 if(this->LinkWithRuntimePath)
1578 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
1582 //----------------------------------------------------------------------------
1583 void
1584 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
1586 // Get the name of the library from the file name.
1587 std::string file = cmSystemTools::GetFilenameName(fullPath);
1588 if(!this->ExtractSharedLibraryName.find(file.c_str()))
1590 // On some platforms (AIX) a shared library may look static.
1591 if(this->ArchivesMayBeShared)
1593 if(!this->ExtractStaticLibraryName.find(file.c_str()))
1595 // This is not the name of a shared library or archive.
1596 return;
1599 else
1601 // This is not the name of a shared library.
1602 return;
1606 // Include this library in the runtime path ordering.
1607 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
1608 if(this->LinkWithRuntimePath)
1610 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
1614 //----------------------------------------------------------------------------
1615 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
1616 bool for_install)
1618 // Select whether to generate runtime search directories.
1619 bool outputRuntime =
1620 !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
1622 // Select whether to generate an rpath for the install tree or the
1623 // build tree.
1624 bool linking_for_install =
1625 (for_install ||
1626 this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1627 bool use_install_rpath =
1628 (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
1629 linking_for_install);
1630 bool use_build_rpath =
1631 (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
1632 !linking_for_install);
1633 bool use_link_rpath =
1634 outputRuntime && linking_for_install &&
1635 this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1637 // Construct the RPATH.
1638 if(use_install_rpath)
1640 const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
1641 cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
1643 if(use_build_rpath || use_link_rpath)
1645 std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
1646 for(std::vector<std::string>::const_iterator ri = rdirs.begin();
1647 ri != rdirs.end(); ++ri)
1649 // Put this directory in the rpath if using build-tree rpath
1650 // support or if using the link path as an rpath.
1651 if(use_build_rpath)
1653 runtimeDirs.push_back(*ri);
1655 else if(use_link_rpath)
1657 // Do not add any path inside the source or build tree.
1658 const char* topSourceDir = this->Makefile->GetHomeDirectory();
1659 const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
1660 if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
1661 !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
1662 !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
1663 !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
1665 runtimeDirs.push_back(*ri);
1671 // Add runtime paths required by the platform to always be
1672 // present. This is done even when skipping rpath support.
1673 cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs);
1676 //----------------------------------------------------------------------------
1677 std::string cmComputeLinkInformation::GetRPathString(bool for_install)
1679 // Get the directories to use.
1680 std::vector<std::string> runtimeDirs;
1681 this->GetRPath(runtimeDirs, for_install);
1683 // Concatenate the paths.
1684 std::string rpath;
1685 const char* sep = "";
1686 for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
1687 ri != runtimeDirs.end(); ++ri)
1689 // Separate from previous path.
1690 rpath += sep;
1691 sep = this->GetRuntimeSep().c_str();
1693 // Add this path.
1694 rpath += *ri;
1697 // If the rpath will be replaced at install time make sure it is
1698 // long enough now.
1699 if(!for_install && this->RuntimeUseChrpath)
1701 std::string::size_type minLength = this->GetChrpathString().length();
1702 while(rpath.length() < minLength)
1704 rpath += this->GetRuntimeSep();
1708 return rpath;
1711 //----------------------------------------------------------------------------
1712 std::string cmComputeLinkInformation::GetChrpathString()
1714 if(!this->RuntimeUseChrpath)
1716 return "";
1719 return this->GetRPathString(true);