1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmComputeLinkInformation.cxx,v $
6 Date: $Date: 2009-08-24 17:15:47 $
7 Version: $Revision: 1.56 $
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"
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
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":
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
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,
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
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
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
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
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.
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
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
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
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
= this->Target
->GetLinkerLanguage(config
);
268 if(!this->LinkLanguage
)
270 // The Compute method will do nothing, so skip the rest of the
275 // Check whether we should use an import library for linking a target.
276 this->UseImportLibrary
=
277 this->Makefile
->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
279 // On platforms without import libraries there may be a special flag
280 // to use when creating a plugin (module) that obtains symbols from
281 // the program that will load it.
282 this->LoaderFlag
= 0;
283 if(!this->UseImportLibrary
&&
284 this->Target
->GetType() == cmTarget::MODULE_LIBRARY
)
286 std::string loader_flag_var
= "CMAKE_SHARED_MODULE_LOADER_";
287 loader_flag_var
+= this->LinkLanguage
;
288 loader_flag_var
+= "_FLAG";
289 this->LoaderFlag
= this->Makefile
->GetDefinition(loader_flag_var
.c_str());
292 // Get options needed to link libraries.
294 this->Makefile
->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
295 this->LibLinkFileFlag
=
296 this->Makefile
->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
297 this->LibLinkSuffix
=
298 this->Makefile
->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
300 // Get options needed to specify RPATHs.
301 this->RuntimeUseChrpath
= false;
302 if(this->Target
->GetType() != cmTarget::STATIC_LIBRARY
)
305 ((this->Target
->GetType() == cmTarget::EXECUTABLE
)?
306 "EXECUTABLE" : "SHARED_LIBRARY");
307 std::string rtVar
= "CMAKE_";
309 rtVar
+= "_RUNTIME_";
310 rtVar
+= this->LinkLanguage
;
312 std::string rtSepVar
= rtVar
+ "_SEP";
313 this->RuntimeFlag
= this->Makefile
->GetSafeDefinition(rtVar
.c_str());
314 this->RuntimeSep
= this->Makefile
->GetSafeDefinition(rtSepVar
.c_str());
315 this->RuntimeAlways
=
317 GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
318 this->RuntimeUseChrpath
= this->Target
->IsChrpathUsed(config
);
320 // Get options needed to help find dependent libraries.
321 std::string rlVar
= "CMAKE_";
323 rlVar
+= "_RPATH_LINK_";
324 rlVar
+= this->LinkLanguage
;
326 this->RPathLinkFlag
= this->Makefile
->GetSafeDefinition(rlVar
.c_str());
329 // Check if we need to include the runtime search path at link time.
331 std::string var
= "CMAKE_SHARED_LIBRARY_LINK_";
332 var
+= this->LinkLanguage
;
333 var
+= "_WITH_RUNTIME_PATH";
334 this->LinkWithRuntimePath
= this->Makefile
->IsOn(var
.c_str());
337 // Check the platform policy for missing soname case.
338 this->NoSONameUsesPath
=
339 this->Makefile
->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
341 // Get link type information.
342 this->ComputeLinkTypeInfo();
344 // Setup the link item parser.
345 this->ComputeItemParserInfo();
347 // Setup framework support.
348 this->ComputeFrameworkInfo();
350 // Choose a mode for dealing with shared library dependencies.
351 this->SharedDependencyMode
= SharedDepModeNone
;
352 if(this->Makefile
->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES"))
354 this->SharedDependencyMode
= SharedDepModeLink
;
356 else if(this->Makefile
->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS"))
358 this->SharedDependencyMode
= SharedDepModeLibDir
;
360 else if(!this->RPathLinkFlag
.empty())
362 this->SharedDependencyMode
= SharedDepModeDir
;
363 this->OrderDependentRPath
=
364 new cmOrderDirectories(this->GlobalGenerator
, target
,
365 "dependent library path");
368 // Add the search path entries requested by the user to path ordering.
369 this->OrderLinkerSearchPath
370 ->AddUserDirectories(this->Target
->GetLinkDirectories());
371 this->OrderRuntimeSearchPath
372 ->AddUserDirectories(this->Target
->GetLinkDirectories());
374 // Set up the implicit link directories.
375 this->LoadImplicitLinkInfo();
376 this->OrderLinkerSearchPath
377 ->SetImplicitDirectories(this->ImplicitLinkDirs
);
378 this->OrderRuntimeSearchPath
379 ->SetImplicitDirectories(this->ImplicitLinkDirs
);
380 if(this->OrderDependentRPath
)
382 this->OrderDependentRPath
383 ->SetImplicitDirectories(this->ImplicitLinkDirs
);
386 // Decide whether to enable compatible library search path mode.
387 // There exists code that effectively does
389 // /path/to/libA.so -lB
391 // where -lB is meant to link to /path/to/libB.so. This is broken
392 // because it specified -lB without specifying a link directory (-L)
393 // in which to search for B. This worked in CMake 2.4 and below
394 // because -L/path/to would be added by the -L/-l split for A. In
395 // order to support such projects we need to add the directories
396 // containing libraries linked with a full path to the -L path.
397 this->OldLinkDirMode
=
398 this->Target
->GetPolicyStatusCMP0003() != cmPolicies::NEW
;
399 if(this->OldLinkDirMode
)
401 // Construct a mask to not bother with this behavior for link
402 // directories already specified by the user.
403 std::vector
<std::string
> const& dirs
= this->Target
->GetLinkDirectories();
404 for(std::vector
<std::string
>::const_iterator di
= dirs
.begin();
405 di
!= dirs
.end(); ++di
)
407 this->OldLinkDirMask
.insert(*di
);
412 //----------------------------------------------------------------------------
413 cmComputeLinkInformation::~cmComputeLinkInformation()
415 delete this->OrderLinkerSearchPath
;
416 delete this->OrderRuntimeSearchPath
;
417 delete this->OrderDependentRPath
;
420 //----------------------------------------------------------------------------
421 cmComputeLinkInformation::ItemVector
const&
422 cmComputeLinkInformation::GetItems()
427 //----------------------------------------------------------------------------
428 std::vector
<std::string
> const& cmComputeLinkInformation::GetDirectories()
430 return this->OrderLinkerSearchPath
->GetOrderedDirectories();
433 //----------------------------------------------------------------------------
434 std::string
cmComputeLinkInformation::GetRPathLinkString()
436 // If there is no separate linker runtime search flag (-rpath-link)
437 // there is no reason to compute a string.
438 if(!this->OrderDependentRPath
)
443 // Construct the linker runtime search path.
444 std::string rpath_link
;
445 const char* sep
= "";
446 std::vector
<std::string
> const& dirs
=
447 this->OrderDependentRPath
->GetOrderedDirectories();
448 for(std::vector
<std::string
>::const_iterator di
= dirs
.begin();
449 di
!= dirs
.end(); ++di
)
458 //----------------------------------------------------------------------------
459 std::vector
<std::string
> const& cmComputeLinkInformation::GetDepends()
461 return this->Depends
;
464 //----------------------------------------------------------------------------
465 std::vector
<std::string
> const& cmComputeLinkInformation::GetFrameworkPaths()
467 return this->FrameworkPaths
;
470 //----------------------------------------------------------------------------
471 std::set
<cmTarget
*> const&
472 cmComputeLinkInformation::GetSharedLibrariesLinked()
474 return this->SharedLibrariesLinked
;
477 //----------------------------------------------------------------------------
478 bool cmComputeLinkInformation::Compute()
480 // Skip targets that do not link.
481 if(!(this->Target
->GetType() == cmTarget::EXECUTABLE
||
482 this->Target
->GetType() == cmTarget::SHARED_LIBRARY
||
483 this->Target
->GetType() == cmTarget::MODULE_LIBRARY
||
484 this->Target
->GetType() == cmTarget::STATIC_LIBRARY
))
489 // We require a link language for the target.
490 if(!this->LinkLanguage
)
493 Error("CMake can not determine linker language for target:",
494 this->Target
->GetName());
498 // Compute the ordered link line items.
499 cmComputeLinkDepends
cld(this->Target
, this->Config
);
500 cld
.SetOldLinkDirMode(this->OldLinkDirMode
);
501 cmComputeLinkDepends::EntryVector
const& linkEntries
= cld
.Compute();
503 // Add the link line items.
504 for(cmComputeLinkDepends::EntryVector::const_iterator
505 lei
= linkEntries
.begin();
506 lei
!= linkEntries
.end(); ++lei
)
510 this->AddSharedDepItem(lei
->Item
, lei
->Target
);
514 this->AddItem(lei
->Item
, lei
->Target
);
518 // Restore the target link type so the correct system runtime
519 // libraries are found.
520 const char* lss
= this->Target
->GetProperty("LINK_SEARCH_END_STATIC");
521 if(cmSystemTools::IsOn(lss
))
523 this->SetCurrentLinkType(LinkStatic
);
527 this->SetCurrentLinkType(this->StartLinkType
);
530 // Finish listing compatibility paths.
531 if(this->OldLinkDirMode
)
533 // For CMake 2.4 bug-compatibility we need to consider the output
534 // directories of targets linked in another configuration as link
536 std::set
<cmTarget
*> const& wrongItems
= cld
.GetOldWrongConfigItems();
537 for(std::set
<cmTarget
*>::const_iterator i
= wrongItems
.begin();
538 i
!= wrongItems
.end(); ++i
)
542 (this->UseImportLibrary
&&
543 (tgt
->GetType() == cmTarget::SHARED_LIBRARY
));
544 std::string lib
= tgt
->GetFullPath(this->Config
, implib
, true);
545 this->OldLinkDirItems
.push_back(lib
);
549 // Finish setting up linker search directories.
550 if(!this->FinishLinkerSearchDirectories())
555 // Add implicit language runtime libraries and directories.
556 this->AddImplicitLinkInfo();
561 //----------------------------------------------------------------------------
562 void cmComputeLinkInformation::AddImplicitLinkInfo()
564 // The link closure lists all languages whose implicit info is needed.
565 cmTarget::LinkClosure
const* lc
=this->Target
->GetLinkClosure(this->Config
);
566 for(std::vector
<std::string
>::const_iterator li
= lc
->Languages
.begin();
567 li
!= lc
->Languages
.end(); ++li
)
569 // Skip those of the linker language. They are implicit.
570 if(*li
!= this->LinkLanguage
)
572 this->AddImplicitLinkInfo(*li
);
577 //----------------------------------------------------------------------------
578 void cmComputeLinkInformation::AddImplicitLinkInfo(std::string
const& lang
)
580 // Add libraries for this language that are not implied by the
582 std::string libVar
= "CMAKE_";
584 libVar
+= "_IMPLICIT_LINK_LIBRARIES";
585 if(const char* libs
= this->Makefile
->GetDefinition(libVar
.c_str()))
587 std::vector
<std::string
> libsVec
;
588 cmSystemTools::ExpandListArgument(libs
, libsVec
);
589 for(std::vector
<std::string
>::const_iterator i
= libsVec
.begin();
590 i
!= libsVec
.end(); ++i
)
592 if(this->ImplicitLinkLibs
.find(*i
) == this->ImplicitLinkLibs
.end())
594 this->AddItem(i
->c_str(), 0);
599 // Add linker search paths for this language that are not
600 // implied by the linker language.
601 std::string dirVar
= "CMAKE_";
603 dirVar
+= "_IMPLICIT_LINK_DIRECTORIES";
604 if(const char* dirs
= this->Makefile
->GetDefinition(dirVar
.c_str()))
606 std::vector
<std::string
> dirsVec
;
607 cmSystemTools::ExpandListArgument(dirs
, dirsVec
);
608 this->OrderLinkerSearchPath
->AddLanguageDirectories(dirsVec
);
612 //----------------------------------------------------------------------------
613 void cmComputeLinkInformation::AddItem(std::string
const& item
, cmTarget
* tgt
)
615 // Compute the proper name to use to link this library.
616 const char* config
= this->Config
;
617 bool impexe
= (tgt
&& tgt
->IsExecutableWithExports());
618 if(impexe
&& !this->UseImportLibrary
&& !this->LoaderFlag
)
620 // Skip linking to executables on platforms with no import
621 // libraries or loader flags.
625 if(tgt
&& tgt
->IsLinkable())
627 // This is a CMake target. Ask the target for its real name.
628 if(impexe
&& this->LoaderFlag
)
630 // This link item is an executable that may provide symbols
631 // used by this target. A special flag is needed on this
632 // platform. Add it now.
633 std::string linkItem
;
634 linkItem
= this->LoaderFlag
;
635 std::string exe
= tgt
->GetFullPath(config
, this->UseImportLibrary
,
638 this->Items
.push_back(Item(linkItem
, true, tgt
));
639 this->Depends
.push_back(exe
);
643 // Decide whether to use an import library.
645 (this->UseImportLibrary
&&
646 (impexe
|| tgt
->GetType() == cmTarget::SHARED_LIBRARY
));
648 // Pass the full path to the target file.
649 std::string lib
= tgt
->GetFullPath(config
, implib
, true);
650 this->Depends
.push_back(lib
);
652 this->AddTargetItem(lib
, tgt
);
653 this->AddLibraryRuntimeInfo(lib
, tgt
);
658 // This is not a CMake target. Use the name given.
659 if(cmSystemTools::FileIsFullPath(item
.c_str()))
661 if(cmSystemTools::FileIsDirectory(item
.c_str()))
663 // This is a directory.
664 this->AddDirectoryItem(item
);
668 // Use the full path given to the library file.
669 this->Depends
.push_back(item
);
670 this->AddFullItem(item
);
671 this->AddLibraryRuntimeInfo(item
);
676 // This is a library or option specified by the user.
677 this->AddUserItem(item
, true);
682 //----------------------------------------------------------------------------
683 void cmComputeLinkInformation::AddSharedDepItem(std::string
const& item
,
686 // If dropping shared library dependencies, ignore them.
687 if(this->SharedDependencyMode
== SharedDepModeNone
)
692 // The user may have incorrectly named an item. Skip items that are
693 // not full paths to shared libraries.
696 // The target will provide a full path. Make sure it is a shared
698 if(tgt
->GetType() != cmTarget::SHARED_LIBRARY
)
705 // Skip items that are not full paths. We will not be able to
706 // reliably specify them.
707 if(!cmSystemTools::FileIsFullPath(item
.c_str()))
712 // Get the name of the library from the file name.
713 std::string file
= cmSystemTools::GetFilenameName(item
);
714 if(!this->ExtractSharedLibraryName
.find(file
.c_str()))
716 // This is not the name of a shared library.
721 // If in linking mode, just link to the shared library.
722 if(this->SharedDependencyMode
== SharedDepModeLink
)
724 this->AddItem(item
, tgt
);
728 // Get a full path to the dependent shared library.
729 // Add it to the runtime path computation so that the target being
730 // linked will be able to find it.
734 lib
= tgt
->GetFullPath(this->Config
, this->UseImportLibrary
);
735 this->AddLibraryRuntimeInfo(lib
, tgt
);
740 this->AddLibraryRuntimeInfo(lib
);
743 // Check if we need to include the dependent shared library in other
745 cmOrderDirectories
* order
= 0;
746 if(this->SharedDependencyMode
== SharedDepModeLibDir
&&
747 !this->LinkWithRuntimePath
/* AddLibraryRuntimeInfo adds it */)
749 // Add the item to the linker search path.
750 order
= this->OrderLinkerSearchPath
;
752 else if(this->SharedDependencyMode
== SharedDepModeDir
)
754 // Add the item to the separate dependent library search path.
755 order
= this->OrderDependentRPath
;
761 std::string soName
= tgt
->GetSOName(this->Config
);
762 const char* soname
= soName
.empty()? 0 : soName
.c_str();
763 order
->AddRuntimeLibrary(lib
, soname
);
767 order
->AddRuntimeLibrary(lib
);
772 //----------------------------------------------------------------------------
773 void cmComputeLinkInformation::ComputeLinkTypeInfo()
775 // Check whether archives may actually be shared libraries.
776 this->ArchivesMayBeShared
=
777 this->CMakeInstance
->GetPropertyAsBool(
778 "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
780 // First assume we cannot do link type stuff.
781 this->LinkTypeEnabled
= false;
783 // Lookup link type selection flags.
784 const char* static_link_type_flag
= 0;
785 const char* shared_link_type_flag
= 0;
786 const char* target_type_str
= 0;
787 switch(this->Target
->GetType())
789 case cmTarget::EXECUTABLE
: target_type_str
= "EXE"; break;
790 case cmTarget::SHARED_LIBRARY
: target_type_str
= "SHARED_LIBRARY"; break;
791 case cmTarget::MODULE_LIBRARY
: target_type_str
= "SHARED_MODULE"; break;
796 std::string static_link_type_flag_var
= "CMAKE_";
797 static_link_type_flag_var
+= target_type_str
;
798 static_link_type_flag_var
+= "_LINK_STATIC_";
799 static_link_type_flag_var
+= this->LinkLanguage
;
800 static_link_type_flag_var
+= "_FLAGS";
801 static_link_type_flag
=
802 this->Makefile
->GetDefinition(static_link_type_flag_var
.c_str());
804 std::string shared_link_type_flag_var
= "CMAKE_";
805 shared_link_type_flag_var
+= target_type_str
;
806 shared_link_type_flag_var
+= "_LINK_DYNAMIC_";
807 shared_link_type_flag_var
+= this->LinkLanguage
;
808 shared_link_type_flag_var
+= "_FLAGS";
809 shared_link_type_flag
=
810 this->Makefile
->GetDefinition(shared_link_type_flag_var
.c_str());
813 // We can support link type switching only if all needed flags are
815 if(static_link_type_flag
&& *static_link_type_flag
&&
816 shared_link_type_flag
&& *shared_link_type_flag
)
818 this->LinkTypeEnabled
= true;
819 this->StaticLinkTypeFlag
= static_link_type_flag
;
820 this->SharedLinkTypeFlag
= shared_link_type_flag
;
823 // TODO: Lookup the starting link type from the target (is it being
824 // linked statically?).
825 this->StartLinkType
= LinkShared
;
826 this->CurrentLinkType
= this->StartLinkType
;
829 //----------------------------------------------------------------------------
830 void cmComputeLinkInformation::ComputeItemParserInfo()
832 // Get possible library name prefixes.
833 cmMakefile
* mf
= this->Makefile
;
834 this->AddLinkPrefix(mf
->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
835 this->AddLinkPrefix(mf
->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
837 // Import library names should be matched and treated as shared
838 // libraries for the purposes of linking.
839 this->AddLinkExtension(mf
->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
841 this->AddLinkExtension(mf
->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
843 this->AddLinkExtension(mf
->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
845 this->AddLinkExtension(mf
->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
847 if(const char* linkSuffixes
=
848 mf
->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
850 std::vector
<std::string
> linkSuffixVec
;
851 cmSystemTools::ExpandListArgument(linkSuffixes
, linkSuffixVec
);
852 for(std::vector
<std::string
>::iterator i
= linkSuffixVec
.begin();
853 i
!= linkSuffixVec
.end(); ++i
)
855 this->AddLinkExtension(i
->c_str(), LinkUnknown
);
858 if(const char* sharedSuffixes
=
859 mf
->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES"))
861 std::vector
<std::string
> sharedSuffixVec
;
862 cmSystemTools::ExpandListArgument(sharedSuffixes
, sharedSuffixVec
);
863 for(std::vector
<std::string
>::iterator i
= sharedSuffixVec
.begin();
864 i
!= sharedSuffixVec
.end(); ++i
)
866 this->AddLinkExtension(i
->c_str(), LinkShared
);
870 // Compute a regex to match link extensions.
871 std::string libext
= this->CreateExtensionRegex(this->LinkExtensions
);
873 // Create regex to remove any library extension.
874 std::string
reg("(.*)");
876 this->OrderLinkerSearchPath
->SetLinkExtensionInfo(this->LinkExtensions
,
879 // Create a regex to match a library name. Match index 1 will be
880 // the prefix if it exists and empty otherwise. Match index 2 will
881 // be the library name. Match index 3 will be the library
884 for(std::set
<cmStdString
>::iterator p
= this->LinkPrefixes
.begin();
885 p
!= this->LinkPrefixes
.end(); ++p
)
893 // Create a regex to match any library name.
894 std::string reg_any
= reg
;
896 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
897 fprintf(stderr
, "any regex [%s]\n", reg_any
.c_str());
899 this->ExtractAnyLibraryName
.compile(reg_any
.c_str());
901 // Create a regex to match static library names.
902 if(!this->StaticLinkExtensions
.empty())
904 std::string reg_static
= reg
;
905 reg_static
+= this->CreateExtensionRegex(this->StaticLinkExtensions
);
906 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
907 fprintf(stderr
, "static regex [%s]\n", reg_static
.c_str());
909 this->ExtractStaticLibraryName
.compile(reg_static
.c_str());
912 // Create a regex to match shared library names.
913 if(!this->SharedLinkExtensions
.empty())
915 std::string reg_shared
= reg
;
916 this->SharedRegexString
=
917 this->CreateExtensionRegex(this->SharedLinkExtensions
);
918 reg_shared
+= this->SharedRegexString
;
919 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
920 fprintf(stderr
, "shared regex [%s]\n", reg_shared
.c_str());
922 this->ExtractSharedLibraryName
.compile(reg_shared
.c_str());
926 //----------------------------------------------------------------------------
927 void cmComputeLinkInformation::AddLinkPrefix(const char* p
)
931 this->LinkPrefixes
.insert(p
);
935 //----------------------------------------------------------------------------
936 void cmComputeLinkInformation::AddLinkExtension(const char* e
, LinkType type
)
940 if(type
== LinkStatic
)
942 this->StaticLinkExtensions
.push_back(e
);
944 if(type
== LinkShared
)
946 this->SharedLinkExtensions
.push_back(e
);
948 this->LinkExtensions
.push_back(e
);
952 //----------------------------------------------------------------------------
954 cmComputeLinkInformation
955 ::CreateExtensionRegex(std::vector
<std::string
> const& exts
)
957 // Build a list of extension choices.
958 std::string libext
= "(";
959 const char* sep
= "";
960 for(std::vector
<std::string
>::const_iterator i
= exts
.begin();
961 i
!= exts
.end(); ++i
)
963 // Separate this choice from the previous one.
967 // Store this extension choice with the "." escaped.
969 #if defined(_WIN32) && !defined(__CYGWIN__)
970 libext
+= this->NoCaseExpression(i
->c_str());
981 //----------------------------------------------------------------------------
982 std::string
cmComputeLinkInformation::NoCaseExpression(const char* str
)
1004 //-------------------------------------------------------------------
1005 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt
)
1007 // If we are changing the current link type add the flag to tell the
1009 if(this->CurrentLinkType
!= lt
)
1011 this->CurrentLinkType
= lt
;
1013 if(this->LinkTypeEnabled
)
1015 switch(this->CurrentLinkType
)
1018 this->Items
.push_back(Item(this->StaticLinkTypeFlag
, false));
1021 this->Items
.push_back(Item(this->SharedLinkTypeFlag
, false));
1030 //----------------------------------------------------------------------------
1031 void cmComputeLinkInformation::AddTargetItem(std::string
const& item
,
1034 // This is called to handle a link item that is a full path to a target.
1035 // If the target is not a static library make sure the link type is
1036 // shared. This is because dynamic-mode linking can handle both
1037 // shared and static libraries but static-mode can handle only
1038 // static libraries. If a previous user item changed the link type
1039 // to static we need to make sure it is back to shared.
1040 if(target
->GetType() != cmTarget::STATIC_LIBRARY
)
1042 this->SetCurrentLinkType(LinkShared
);
1045 // Keep track of shared library targets linked.
1046 if(target
->GetType() == cmTarget::SHARED_LIBRARY
)
1048 this->SharedLibrariesLinked
.insert(target
);
1051 // Handle case of an imported shared library with no soname.
1052 if(this->NoSONameUsesPath
&&
1053 target
->IsImportedSharedLibWithoutSOName(this->Config
))
1055 this->AddSharedLibNoSOName(item
);
1059 // If this platform wants a flag before the full path, add it.
1060 if(!this->LibLinkFileFlag
.empty())
1062 this->Items
.push_back(Item(this->LibLinkFileFlag
, false));
1065 // For compatibility with CMake 2.4 include the item's directory in
1066 // the linker search path.
1067 if(this->OldLinkDirMode
&& !target
->IsFrameworkOnApple() &&
1068 this->OldLinkDirMask
.find(cmSystemTools::GetFilenamePath(item
)) ==
1069 this->OldLinkDirMask
.end())
1071 this->OldLinkDirItems
.push_back(item
);
1074 // Now add the full path to the library.
1075 this->Items
.push_back(Item(item
, true, target
));
1078 //----------------------------------------------------------------------------
1079 void cmComputeLinkInformation::AddFullItem(std::string
const& item
)
1081 // Check for the implicit link directory special case.
1082 if(this->CheckImplicitDirItem(item
))
1087 // Check for case of shared library with no builtin soname.
1088 if(this->NoSONameUsesPath
&& this->CheckSharedLibNoSOName(item
))
1093 // Full path libraries should specify a valid library file name.
1094 // See documentation of CMP0008.
1095 if(this->Target
->GetPolicyStatusCMP0008() != cmPolicies::NEW
&&
1096 (strstr(this->GlobalGenerator
->GetName(), "Visual Studio") ||
1097 strstr(this->GlobalGenerator
->GetName(), "Xcode")))
1099 std::string file
= cmSystemTools::GetFilenameName(item
);
1100 if(!this->ExtractAnyLibraryName
.find(file
.c_str()))
1102 this->HandleBadFullItem(item
, file
);
1107 // This is called to handle a link item that is a full path.
1108 // If the target is not a static library make sure the link type is
1109 // shared. This is because dynamic-mode linking can handle both
1110 // shared and static libraries but static-mode can handle only
1111 // static libraries. If a previous user item changed the link type
1112 // to static we need to make sure it is back to shared.
1113 if(this->LinkTypeEnabled
)
1115 std::string name
= cmSystemTools::GetFilenameName(item
);
1116 if(this->ExtractSharedLibraryName
.find(name
))
1118 this->SetCurrentLinkType(LinkShared
);
1120 else if(!this->ExtractStaticLibraryName
.find(item
))
1122 // We cannot determine the type. Assume it is the target's
1124 this->SetCurrentLinkType(this->StartLinkType
);
1128 // For compatibility with CMake 2.4 include the item's directory in
1129 // the linker search path.
1130 if(this->OldLinkDirMode
&&
1131 this->OldLinkDirMask
.find(cmSystemTools::GetFilenamePath(item
)) ==
1132 this->OldLinkDirMask
.end())
1134 this->OldLinkDirItems
.push_back(item
);
1137 // If this platform wants a flag before the full path, add it.
1138 if(!this->LibLinkFileFlag
.empty())
1140 this->Items
.push_back(Item(this->LibLinkFileFlag
, false));
1143 // Now add the full path to the library.
1144 this->Items
.push_back(Item(item
, true));
1147 //----------------------------------------------------------------------------
1148 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string
const& item
)
1150 // We only switch to a pathless item if the link type may be
1151 // enforced. Fortunately only platforms that support link types
1152 // seem to have magic per-architecture implicit link directories.
1153 if(!this->LinkTypeEnabled
)
1158 // Check if this item is in an implicit link directory.
1159 std::string dir
= cmSystemTools::GetFilenamePath(item
);
1160 if(this->ImplicitLinkDirs
.find(dir
) == this->ImplicitLinkDirs
.end())
1162 // Only libraries in implicit link directories are converted to
1167 // Only apply the policy below if the library file is one that can
1168 // be found by the linker.
1169 std::string file
= cmSystemTools::GetFilenameName(item
);
1170 if(!this->ExtractAnyLibraryName
.find(file
))
1175 // Many system linkers support multiple architectures by
1176 // automatically selecting the implicit linker search path for the
1177 // current architecture. If the library appears in an implicit link
1178 // directory then just report the file name without the directory
1179 // portion. This will allow the system linker to locate the proper
1180 // library for the architecture at link time.
1181 this->AddUserItem(file
, false);
1183 // Make sure the link directory ordering will find the library.
1184 this->OrderLinkerSearchPath
->AddLinkLibrary(item
);
1189 //----------------------------------------------------------------------------
1190 void cmComputeLinkInformation::AddUserItem(std::string
const& item
,
1193 // This is called to handle a link item that does not match a CMake
1194 // target and is not a full path. We check here if it looks like a
1195 // library file name to automatically request the proper link type
1196 // from the linker. For example:
1199 // libfoo.a ==> -Wl,-Bstatic -lfoo
1201 // Pass flags through untouched.
1202 if(item
[0] == '-' || item
[0] == '$' || item
[0] == '`')
1204 // if this is a -l option then we might need to warn about
1205 // CMP0003 so put it in OldUserFlagItems, if it is not a -l
1206 // or -Wl,-l (-framework -pthread), then allow it without a
1207 // CMP0003 as -L will not affect those other linker flags
1208 if(item
.find("-l") == 0 || item
.find("-Wl,-l") == 0)
1210 // This is a linker option provided by the user.
1211 this->OldUserFlagItems
.push_back(item
);
1214 // Restore the target link type since this item does not specify
1216 this->SetCurrentLinkType(this->StartLinkType
);
1218 // Use the item verbatim.
1219 this->Items
.push_back(Item(item
, false));
1223 // Parse out the prefix, base, and suffix components of the
1224 // library name. If the name matches that of a shared or static
1225 // library then set the link type accordingly.
1227 // Search for shared library names first because some platforms
1228 // have shared libraries with names that match the static library
1229 // pattern. For example cygwin and msys use the convention
1230 // libfoo.dll.a for import libraries and libfoo.a for static
1231 // libraries. On AIX a library with the name libfoo.a can be
1234 if(this->ExtractSharedLibraryName
.find(item
))
1236 // This matches a shared library file name.
1237 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1238 fprintf(stderr
, "shared regex matched [%s] [%s] [%s]\n",
1239 this->ExtractSharedLibraryName
.match(1).c_str(),
1240 this->ExtractSharedLibraryName
.match(2).c_str(),
1241 this->ExtractSharedLibraryName
.match(3).c_str());
1243 // Set the link type to shared.
1244 this->SetCurrentLinkType(LinkShared
);
1246 // Use just the library name so the linker will search.
1247 lib
= this->ExtractSharedLibraryName
.match(2);
1249 else if(this->ExtractStaticLibraryName
.find(item
))
1251 // This matches a static library file name.
1252 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1253 fprintf(stderr
, "static regex matched [%s] [%s] [%s]\n",
1254 this->ExtractStaticLibraryName
.match(1).c_str(),
1255 this->ExtractStaticLibraryName
.match(2).c_str(),
1256 this->ExtractStaticLibraryName
.match(3).c_str());
1258 // Set the link type to static.
1259 this->SetCurrentLinkType(LinkStatic
);
1261 // Use just the library name so the linker will search.
1262 lib
= this->ExtractStaticLibraryName
.match(2);
1264 else if(this->ExtractAnyLibraryName
.find(item
))
1266 // This matches a library file name.
1267 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1268 fprintf(stderr
, "any regex matched [%s] [%s] [%s]\n",
1269 this->ExtractAnyLibraryName
.match(1).c_str(),
1270 this->ExtractAnyLibraryName
.match(2).c_str(),
1271 this->ExtractAnyLibraryName
.match(3).c_str());
1273 // Restore the target link type since this item does not specify
1275 this->SetCurrentLinkType(this->StartLinkType
);
1277 // Use just the library name so the linker will search.
1278 lib
= this->ExtractAnyLibraryName
.match(2);
1282 // This is a name specified by the user.
1285 this->OldUserFlagItems
.push_back(item
);
1288 // We must ask the linker to search for a library with this name.
1289 // Restore the target link type since this item does not specify
1291 this->SetCurrentLinkType(this->StartLinkType
);
1295 // Create an option to ask the linker to search for the library.
1296 std::string out
= this->LibLinkFlag
;
1298 out
+= this->LibLinkSuffix
;
1299 this->Items
.push_back(Item(out
, false));
1301 // Here we could try to find the library the linker will find and
1302 // add a runtime information entry for it. It would probably not be
1303 // reliable and we want to encourage use of full paths for library
1307 //----------------------------------------------------------------------------
1308 void cmComputeLinkInformation::AddFrameworkItem(std::string
const& item
)
1310 // Try to separate the framework name and path.
1311 if(!this->SplitFramework
.find(item
.c_str()))
1314 e
<< "Could not parse framework path \"" << item
<< "\" "
1315 << "linked by target " << this->Target
->GetName() << ".";
1316 cmSystemTools::Error(e
.str().c_str());
1320 // Add the directory portion to the framework search path.
1321 this->AddFrameworkPath(this->SplitFramework
.match(1));
1323 // Add the item using the -framework option.
1324 std::string fw
= "-framework ";
1325 fw
+= this->SplitFramework
.match(2);
1326 this->Items
.push_back(Item(fw
, false));
1329 //----------------------------------------------------------------------------
1330 void cmComputeLinkInformation::AddDirectoryItem(std::string
const& item
)
1333 if(cmSystemTools::IsPathToFramework(item
.c_str()))
1335 this->AddFrameworkItem(item
);
1340 this->DropDirectoryItem(item
);
1344 //----------------------------------------------------------------------------
1345 void cmComputeLinkInformation::DropDirectoryItem(std::string
const& item
)
1347 // A full path to a directory was found as a link item. Warn the
1350 e
<< "WARNING: Target \"" << this->Target
->GetName()
1351 << "\" requests linking to directory \"" << item
<< "\". "
1352 << "Targets may link only to libraries. "
1353 << "CMake is dropping the item.";
1354 cmSystemTools::Message(e
.str().c_str());
1357 //----------------------------------------------------------------------------
1358 void cmComputeLinkInformation::ComputeFrameworkInfo()
1360 // Avoid adding system framework paths. See "man ld" on OS X.
1361 this->FrameworkPathsEmmitted
.insert("/Library/Frameworks");
1362 this->FrameworkPathsEmmitted
.insert("/Network/Library/Frameworks");
1363 this->FrameworkPathsEmmitted
.insert("/System/Library/Frameworks");
1365 // Regular expression to extract a framework path and name.
1366 this->SplitFramework
.compile("(.*)/(.*)\\.framework$");
1369 //----------------------------------------------------------------------------
1370 void cmComputeLinkInformation::AddFrameworkPath(std::string
const& p
)
1372 if(this->FrameworkPathsEmmitted
.insert(p
).second
)
1374 this->FrameworkPaths
.push_back(p
);
1378 //----------------------------------------------------------------------------
1379 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string
const& item
)
1381 // This platform will use the path to a library as its soname if the
1382 // library is given via path and was not built with an soname. If
1383 // this is a shared library that might be the case.
1384 std::string file
= cmSystemTools::GetFilenameName(item
);
1385 if(this->ExtractSharedLibraryName
.find(file
))
1387 // If we can guess the soname fairly reliably then assume the
1388 // library has one. Otherwise assume the library has no builtin
1391 if(!cmSystemTools::GuessLibrarySOName(item
, soname
))
1393 this->AddSharedLibNoSOName(item
);
1400 //----------------------------------------------------------------------------
1401 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string
const& item
)
1403 // We have a full path to a shared library with no soname. We need
1404 // to ask the linker to locate the item because otherwise the path
1405 // we give to it will be embedded in the target linked. Then at
1406 // runtime the dynamic linker will search for the library using the
1407 // path instead of just the name.
1408 std::string file
= cmSystemTools::GetFilenameName(item
);
1409 this->AddUserItem(file
, false);
1411 // Make sure the link directory ordering will find the library.
1412 this->OrderLinkerSearchPath
->AddLinkLibrary(item
);
1415 //----------------------------------------------------------------------------
1416 void cmComputeLinkInformation::HandleBadFullItem(std::string
const& item
,
1417 std::string
const& file
)
1419 // Do not depend on things that do not exist.
1420 std::vector
<std::string
>::iterator i
=
1421 std::find(this->Depends
.begin(), this->Depends
.end(), item
);
1422 if(i
!= this->Depends
.end())
1424 this->Depends
.erase(i
);
1427 // Tell the linker to search for the item and provide the proper
1428 // path for it. Do not contribute to any CMP0003 warning (do not
1429 // put in OldLinkDirItems or OldUserFlagItems).
1430 this->AddUserItem(file
, false);
1431 this->OrderLinkerSearchPath
->AddLinkLibrary(item
);
1433 // Produce any needed message.
1434 switch(this->Target
->GetPolicyStatusCMP0008())
1436 case cmPolicies::WARN
:
1438 // Print the warning at most once for this item.
1439 std::string wid
= "CMP0008-WARNING-GIVEN-";
1441 if(!this->CMakeInstance
->GetPropertyAsBool(wid
.c_str()))
1443 this->CMakeInstance
->SetProperty(wid
.c_str(), "1");
1445 w
<< (this->Makefile
->GetPolicies()
1446 ->GetPolicyWarning(cmPolicies::CMP0008
)) << "\n"
1447 << "Target \"" << this->Target
->GetName() << "\" links to item\n"
1448 << " " << item
<< "\n"
1449 << "which is a full-path but not a valid library file name.";
1450 this->CMakeInstance
->IssueMessage(cmake::AUTHOR_WARNING
, w
.str(),
1451 this->Target
->GetBacktrace());
1454 case cmPolicies::OLD
:
1455 // OLD behavior does not warn.
1457 case cmPolicies::NEW
:
1458 // NEW behavior will not get here.
1460 case cmPolicies::REQUIRED_IF_USED
:
1461 case cmPolicies::REQUIRED_ALWAYS
:
1464 e
<< (this->Makefile
->GetPolicies()->
1465 GetRequiredPolicyError(cmPolicies::CMP0008
)) << "\n"
1466 << "Target \"" << this->Target
->GetName() << "\" links to item\n"
1467 << " " << item
<< "\n"
1468 << "which is a full-path but not a valid library file name.";
1469 this->CMakeInstance
->IssueMessage(cmake::FATAL_ERROR
, e
.str(),
1470 this->Target
->GetBacktrace());
1476 //----------------------------------------------------------------------------
1477 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1479 // Support broken projects if necessary.
1480 if(this->OldLinkDirItems
.empty() || this->OldUserFlagItems
.empty() ||
1481 !this->OldLinkDirMode
)
1486 // Enforce policy constraints.
1487 switch(this->Target
->GetPolicyStatusCMP0003())
1489 case cmPolicies::WARN
:
1490 if(!this->CMakeInstance
->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1492 this->CMakeInstance
->SetProperty("CMP0003-WARNING-GIVEN", "1");
1494 this->PrintLinkPolicyDiagnosis(w
);
1495 this->CMakeInstance
->IssueMessage(cmake::AUTHOR_WARNING
, w
.str(),
1496 this->Target
->GetBacktrace());
1498 case cmPolicies::OLD
:
1499 // OLD behavior is to add the paths containing libraries with
1500 // known full paths as link directories.
1502 case cmPolicies::NEW
:
1503 // Should never happen due to assignment of OldLinkDirMode
1505 case cmPolicies::REQUIRED_IF_USED
:
1506 case cmPolicies::REQUIRED_ALWAYS
:
1509 e
<< (this->Makefile
->GetPolicies()->
1510 GetRequiredPolicyError(cmPolicies::CMP0003
)) << "\n";
1511 this->PrintLinkPolicyDiagnosis(e
);
1512 this->CMakeInstance
->IssueMessage(cmake::FATAL_ERROR
, e
.str(),
1513 this->Target
->GetBacktrace());
1518 // Add the link directories for full path items.
1519 for(std::vector
<std::string
>::const_iterator
1520 i
= this->OldLinkDirItems
.begin();
1521 i
!= this->OldLinkDirItems
.end(); ++i
)
1523 this->OrderLinkerSearchPath
->AddLinkLibrary(*i
);
1528 //----------------------------------------------------------------------------
1529 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream
& os
)
1531 // Tell the user what to do.
1532 os
<< "Policy CMP0003 should be set before this line. "
1533 << "Add code such as\n"
1534 << " if(COMMAND cmake_policy)\n"
1535 << " cmake_policy(SET CMP0003 NEW)\n"
1536 << " endif(COMMAND cmake_policy)\n"
1537 << "as early as possible but after the most recent call to "
1538 << "cmake_minimum_required or cmake_policy(VERSION). ";
1540 // List the items that might need the old-style paths.
1541 os
<< "This warning appears because target \""
1542 << this->Target
->GetName() << "\" "
1543 << "links to some libraries for which the linker must search:\n";
1545 // Format the list of unknown items to be as short as possible while
1546 // still fitting in the allowed width (a true solution would be the
1547 // bin packing problem if we were allowed to change the order).
1548 std::string::size_type max_size
= 76;
1550 const char* sep
= " ";
1551 for(std::vector
<std::string
>::const_iterator
1552 i
= this->OldUserFlagItems
.begin();
1553 i
!= this->OldUserFlagItems
.end(); ++i
)
1555 // If the addition of another item will exceed the limit then
1556 // output the current line and reset it. Note that the separator
1557 // is either " " or ", " which is always 2 characters.
1558 if(!line
.empty() && (line
.size() + i
->size() + 2) > max_size
)
1566 // Convert to the other separator.
1575 // List the paths old behavior is adding.
1576 os
<< "and other libraries with known full path:\n";
1577 std::set
<cmStdString
> emitted
;
1578 for(std::vector
<std::string
>::const_iterator
1579 i
= this->OldLinkDirItems
.begin();
1580 i
!= this->OldLinkDirItems
.end(); ++i
)
1582 if(emitted
.insert(cmSystemTools::GetFilenamePath(*i
)).second
)
1584 os
<< " " << *i
<< "\n";
1589 os
<< "CMake is adding directories in the second list to the linker "
1590 << "search path in case they are needed to find libraries from the "
1591 << "first list (for backwards compatibility with CMake 2.4). "
1592 << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1593 << "behavior explicitly. "
1594 << "Run \"cmake --help-policy CMP0003\" for more information.";
1597 //----------------------------------------------------------------------------
1598 void cmComputeLinkInformation::LoadImplicitLinkInfo()
1600 std::vector
<std::string
> implicitDirVec
;
1602 // Get platform-wide implicit directories.
1603 if(const char* implicitLinks
=
1604 (this->Makefile
->GetDefinition
1605 ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
1607 cmSystemTools::ExpandListArgument(implicitLinks
, implicitDirVec
);
1610 // Get language-specific implicit directories.
1611 std::string implicitDirVar
= "CMAKE_";
1612 implicitDirVar
+= this->LinkLanguage
;
1613 implicitDirVar
+= "_IMPLICIT_LINK_DIRECTORIES";
1614 if(const char* implicitDirs
=
1615 this->Makefile
->GetDefinition(implicitDirVar
.c_str()))
1617 cmSystemTools::ExpandListArgument(implicitDirs
, implicitDirVec
);
1620 // Store implicit link directories.
1621 for(std::vector
<std::string
>::const_iterator i
= implicitDirVec
.begin();
1622 i
!= implicitDirVec
.end(); ++i
)
1624 this->ImplicitLinkDirs
.insert(*i
);
1627 // Get language-specific implicit libraries.
1628 std::vector
<std::string
> implicitLibVec
;
1629 std::string implicitLibVar
= "CMAKE_";
1630 implicitLibVar
+= this->LinkLanguage
;
1631 implicitLibVar
+= "_IMPLICIT_LINK_LIBRARIES";
1632 if(const char* implicitLibs
=
1633 this->Makefile
->GetDefinition(implicitLibVar
.c_str()))
1635 cmSystemTools::ExpandListArgument(implicitLibs
, implicitLibVec
);
1638 // Store implicit link libraries.
1639 for(std::vector
<std::string
>::const_iterator i
= implicitLibVec
.begin();
1640 i
!= implicitLibVec
.end(); ++i
)
1642 // Items starting in '-' but not '-l' are flags, not libraries,
1643 // and should not be filtered by this implicit list.
1644 std::string
const& item
= *i
;
1645 if(item
[0] != '-' || item
[1] == 'l')
1647 this->ImplicitLinkLibs
.insert(item
);
1652 //----------------------------------------------------------------------------
1653 std::vector
<std::string
> const&
1654 cmComputeLinkInformation::GetRuntimeSearchPath()
1656 return this->OrderRuntimeSearchPath
->GetOrderedDirectories();
1659 //----------------------------------------------------------------------------
1661 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string
const& fullPath
,
1664 // Libraries with unknown type must be handled using just the file
1666 if(target
->GetType() == cmTarget::UNKNOWN_LIBRARY
)
1668 this->AddLibraryRuntimeInfo(fullPath
);
1672 // Skip targets that are not shared libraries (modules cannot be linked).
1673 if(target
->GetType() != cmTarget::SHARED_LIBRARY
)
1678 // Try to get the soname of the library. Only files with this name
1679 // could possibly conflict.
1680 std::string soName
= target
->GetSOName(this->Config
);
1681 const char* soname
= soName
.empty()? 0 : soName
.c_str();
1683 // Include this library in the runtime path ordering.
1684 this->OrderRuntimeSearchPath
->AddRuntimeLibrary(fullPath
, soname
);
1685 if(this->LinkWithRuntimePath
)
1687 this->OrderLinkerSearchPath
->AddRuntimeLibrary(fullPath
, soname
);
1691 //----------------------------------------------------------------------------
1693 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string
const& fullPath
)
1695 // Get the name of the library from the file name.
1696 std::string file
= cmSystemTools::GetFilenameName(fullPath
);
1697 if(!this->ExtractSharedLibraryName
.find(file
.c_str()))
1699 // On some platforms (AIX) a shared library may look static.
1700 if(this->ArchivesMayBeShared
)
1702 if(!this->ExtractStaticLibraryName
.find(file
.c_str()))
1704 // This is not the name of a shared library or archive.
1710 // This is not the name of a shared library.
1715 // Include this library in the runtime path ordering.
1716 this->OrderRuntimeSearchPath
->AddRuntimeLibrary(fullPath
);
1717 if(this->LinkWithRuntimePath
)
1719 this->OrderLinkerSearchPath
->AddRuntimeLibrary(fullPath
);
1723 //----------------------------------------------------------------------------
1724 void cmComputeLinkInformation::GetRPath(std::vector
<std::string
>& runtimeDirs
,
1727 // Select whether to generate runtime search directories.
1728 bool outputRuntime
=
1729 !this->Makefile
->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag
.empty();
1731 // Select whether to generate an rpath for the install tree or the
1733 bool linking_for_install
=
1735 this->Target
->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1736 bool use_install_rpath
=
1737 (outputRuntime
&& this->Target
->HaveInstallTreeRPATH() &&
1738 linking_for_install
);
1739 bool use_build_rpath
=
1740 (outputRuntime
&& this->Target
->HaveBuildTreeRPATH() &&
1741 !linking_for_install
);
1742 bool use_link_rpath
=
1743 outputRuntime
&& linking_for_install
&&
1744 this->Target
->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1746 // Construct the RPATH.
1747 if(use_install_rpath
)
1749 const char* install_rpath
= this->Target
->GetProperty("INSTALL_RPATH");
1750 cmSystemTools::ExpandListArgument(install_rpath
, runtimeDirs
);
1752 if(use_build_rpath
|| use_link_rpath
)
1754 std::vector
<std::string
> const& rdirs
= this->GetRuntimeSearchPath();
1755 for(std::vector
<std::string
>::const_iterator ri
= rdirs
.begin();
1756 ri
!= rdirs
.end(); ++ri
)
1758 // Put this directory in the rpath if using build-tree rpath
1759 // support or if using the link path as an rpath.
1762 runtimeDirs
.push_back(*ri
);
1764 else if(use_link_rpath
)
1766 // Do not add any path inside the source or build tree.
1767 const char* topSourceDir
= this->Makefile
->GetHomeDirectory();
1768 const char* topBinaryDir
= this->Makefile
->GetHomeOutputDirectory();
1769 if(!cmSystemTools::ComparePath(ri
->c_str(), topSourceDir
) &&
1770 !cmSystemTools::ComparePath(ri
->c_str(), topBinaryDir
) &&
1771 !cmSystemTools::IsSubDirectory(ri
->c_str(), topSourceDir
) &&
1772 !cmSystemTools::IsSubDirectory(ri
->c_str(), topBinaryDir
))
1774 runtimeDirs
.push_back(*ri
);
1780 // Add runtime paths required by the platform to always be
1781 // present. This is done even when skipping rpath support.
1782 cmSystemTools::ExpandListArgument(this->RuntimeAlways
.c_str(), runtimeDirs
);
1785 //----------------------------------------------------------------------------
1786 std::string
cmComputeLinkInformation::GetRPathString(bool for_install
)
1788 // Get the directories to use.
1789 std::vector
<std::string
> runtimeDirs
;
1790 this->GetRPath(runtimeDirs
, for_install
);
1792 // Concatenate the paths.
1794 const char* sep
= "";
1795 for(std::vector
<std::string
>::const_iterator ri
= runtimeDirs
.begin();
1796 ri
!= runtimeDirs
.end(); ++ri
)
1798 // Separate from previous path.
1800 sep
= this->GetRuntimeSep().c_str();
1806 // If the rpath will be replaced at install time, prepare space.
1807 if(!for_install
&& this->RuntimeUseChrpath
)
1811 // Add one trailing separator so the linker does not re-use the
1812 // rpath .dynstr entry for a symbol name that happens to match
1813 // the end of the rpath string.
1814 rpath
+= this->GetRuntimeSep();
1817 // Make sure it is long enough to hold the replacement value.
1818 std::string::size_type minLength
= this->GetChrpathString().length();
1819 while(rpath
.length() < minLength
)
1821 rpath
+= this->GetRuntimeSep();
1828 //----------------------------------------------------------------------------
1829 std::string
cmComputeLinkInformation::GetChrpathString()
1831 if(!this->RuntimeUseChrpath
)
1836 return this->GetRPathString(true);