1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmComputeLinkInformation.cxx,v $
6 Date: $Date: 2008-04-08 04:06:46 $
7 Version: $Revision: 1.33 $
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
->GetName(),
260 "linker search path");
261 this->OrderRuntimeSearchPath
=
262 new cmOrderDirectories(this->GlobalGenerator
, target
->GetName(),
263 "runtime search path");
264 this->OrderDependentRPath
= 0;
266 // Get the language used for linking this target.
268 this->Target
->GetLinkerLanguage(this->GlobalGenerator
);
269 if(!this->LinkLanguage
)
271 // The Compute method will do nothing, so skip the rest of the
276 // Check whether we should use an import library for linking a target.
277 this->UseImportLibrary
=
278 this->Makefile
->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
280 // On platforms without import libraries there may be a special flag
281 // to use when creating a plugin (module) that obtains symbols from
282 // the program that will load it.
283 this->LoaderFlag
= 0;
284 if(!this->UseImportLibrary
&&
285 this->Target
->GetType() == cmTarget::MODULE_LIBRARY
)
287 std::string loader_flag_var
= "CMAKE_SHARED_MODULE_LOADER_";
288 loader_flag_var
+= this->LinkLanguage
;
289 loader_flag_var
+= "_FLAG";
290 this->LoaderFlag
= this->Makefile
->GetDefinition(loader_flag_var
.c_str());
293 // Get options needed to link libraries.
295 this->Makefile
->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
296 this->LibLinkFileFlag
=
297 this->Makefile
->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
298 this->LibLinkSuffix
=
299 this->Makefile
->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
301 // Get options needed to specify RPATHs.
302 this->RuntimeUseChrpath
= false;
303 if(this->Target
->GetType() != cmTarget::STATIC_LIBRARY
)
306 ((this->Target
->GetType() == cmTarget::EXECUTABLE
)?
307 "EXECUTABLE" : "SHARED_LIBRARY");
308 std::string rtVar
= "CMAKE_";
310 rtVar
+= "_RUNTIME_";
311 rtVar
+= this->LinkLanguage
;
313 std::string rtSepVar
= rtVar
+ "_SEP";
314 this->RuntimeFlag
= this->Makefile
->GetSafeDefinition(rtVar
.c_str());
315 this->RuntimeSep
= this->Makefile
->GetSafeDefinition(rtSepVar
.c_str());
316 this->RuntimeAlways
=
318 GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
319 this->RuntimeUseChrpath
= this->Target
->IsChrpathUsed();
321 // Get options needed to help find dependent libraries.
322 std::string rlVar
= "CMAKE_";
324 rlVar
+= "_RPATH_LINK_";
325 rlVar
+= this->LinkLanguage
;
327 this->RPathLinkFlag
= this->Makefile
->GetSafeDefinition(rlVar
.c_str());
330 // Check if we need to include the runtime search path at link time.
332 std::string var
= "CMAKE_SHARED_LIBRARY_LINK_";
333 var
+= this->LinkLanguage
;
334 var
+= "_WITH_RUNTIME_PATH";
335 this->LinkWithRuntimePath
= this->Makefile
->IsOn(var
.c_str());
338 // Check the platform policy for missing soname case.
339 this->NoSONameUsesPath
=
340 this->Makefile
->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
342 // Get link type information.
343 this->ComputeLinkTypeInfo();
345 // Setup the link item parser.
346 this->ComputeItemParserInfo();
348 // Setup framework support.
349 this->ComputeFrameworkInfo();
351 // Choose a mode for dealing with shared library dependencies.
352 this->SharedDependencyMode
= SharedDepModeNone
;
353 if(this->Makefile
->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES"))
355 this->SharedDependencyMode
= SharedDepModeLink
;
357 else if(this->Makefile
->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS"))
359 this->SharedDependencyMode
= SharedDepModeLibDir
;
361 else if(!this->RPathLinkFlag
.empty())
363 this->SharedDependencyMode
= SharedDepModeDir
;
364 this->OrderDependentRPath
=
365 new cmOrderDirectories(this->GlobalGenerator
, target
->GetName(),
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()
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
)
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
)
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
))
502 // We require a link language for the target.
503 if(!this->LinkLanguage
)
506 Error("CMake can not determine linker language for target:",
507 this->Target
->GetName());
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
)
523 this->AddSharedDepItem(lei
->Item
, lei
->Target
);
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
);
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
549 std::set
<cmTarget
*> const& wrongItems
= cld
.GetOldWrongConfigItems();
550 for(std::set
<cmTarget
*>::const_iterator i
= wrongItems
.begin();
551 i
!= wrongItems
.end(); ++i
)
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())
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.
584 if(tgt
&& (tgt
->GetType() == cmTarget::STATIC_LIBRARY
||
585 tgt
->GetType() == cmTarget::SHARED_LIBRARY
||
586 tgt
->GetType() == cmTarget::MODULE_LIBRARY
||
589 // This is a CMake target. Ask the target for its real name.
590 if(impexe
&& this->LoaderFlag
)
592 // This link item is an executable that may provide symbols
593 // used by this target. A special flag is needed on this
594 // platform. Add it now.
595 std::string linkItem
;
596 linkItem
= this->LoaderFlag
;
597 std::string exe
= tgt
->GetFullPath(config
, this->UseImportLibrary
,
600 this->Items
.push_back(Item(linkItem
, true));
601 this->Depends
.push_back(exe
);
605 // Decide whether to use an import library.
607 (this->UseImportLibrary
&&
608 (impexe
|| tgt
->GetType() == cmTarget::SHARED_LIBRARY
));
610 // Pass the full path to the target file.
611 std::string lib
= tgt
->GetFullPath(config
, implib
, true);
612 this->Depends
.push_back(lib
);
614 this->AddTargetItem(lib
, tgt
);
615 this->AddLibraryRuntimeInfo(lib
, tgt
);
620 // This is not a CMake target. Use the name given.
621 if(cmSystemTools::FileIsFullPath(item
.c_str()))
623 if(cmSystemTools::FileIsDirectory(item
.c_str()))
625 // This is a directory.
626 this->AddDirectoryItem(item
);
630 // Use the full path given to the library file.
631 this->Depends
.push_back(item
);
632 this->AddFullItem(item
);
633 this->AddLibraryRuntimeInfo(item
);
638 // This is a library or option specified by the user.
639 this->AddUserItem(item
);
644 //----------------------------------------------------------------------------
645 void cmComputeLinkInformation::AddSharedDepItem(std::string
const& item
,
648 // If dropping shared library dependencies, ignore them.
649 if(this->SharedDependencyMode
== SharedDepModeNone
)
654 // The user may have incorrectly named an item. Skip items that are
655 // not full paths to shared libraries.
658 // The target will provide a full path. Make sure it is a shared
660 if(tgt
->GetType() != cmTarget::SHARED_LIBRARY
)
667 // Skip items that are not full paths. We will not be able to
668 // reliably specify them.
669 if(!cmSystemTools::FileIsFullPath(item
.c_str()))
674 // Get the name of the library from the file name.
675 std::string file
= cmSystemTools::GetFilenameName(item
);
676 if(!this->ExtractSharedLibraryName
.find(file
.c_str()))
678 // This is not the name of a shared library.
683 // If in linking mode, just link to the shared library.
684 if(this->SharedDependencyMode
== SharedDepModeLink
)
686 this->AddItem(item
, tgt
);
690 // Get a full path to the dependent shared library.
691 // Add it to the runtime path computation so that the target being
692 // linked will be able to find it.
696 lib
= tgt
->GetFullPath(this->Config
, this->UseImportLibrary
);
697 this->AddLibraryRuntimeInfo(lib
, tgt
);
702 this->AddLibraryRuntimeInfo(lib
);
705 // Check if we need to include the dependent shared library in other
707 cmOrderDirectories
* order
= 0;
708 if(this->SharedDependencyMode
== SharedDepModeLibDir
&&
709 !this->LinkWithRuntimePath
/* AddLibraryRuntimeInfo adds it */)
711 // Add the item to the linker search path.
712 order
= this->OrderLinkerSearchPath
;
714 else if(this->SharedDependencyMode
== SharedDepModeDir
)
716 // Add the item to the separate dependent library search path.
717 order
= this->OrderDependentRPath
;
723 std::string soName
= tgt
->GetSOName(this->Config
);
724 const char* soname
= soName
.empty()? 0 : soName
.c_str();
725 order
->AddRuntimeLibrary(lib
, soname
);
729 order
->AddRuntimeLibrary(lib
);
734 //----------------------------------------------------------------------------
735 void cmComputeLinkInformation::ComputeLinkTypeInfo()
737 // Check whether archives may actually be shared libraries.
738 this->ArchivesMayBeShared
=
739 this->CMakeInstance
->GetPropertyAsBool(
740 "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
742 // First assume we cannot do link type stuff.
743 this->LinkTypeEnabled
= false;
745 // Lookup link type selection flags.
746 const char* static_link_type_flag
= 0;
747 const char* shared_link_type_flag
= 0;
748 const char* target_type_str
= 0;
749 switch(this->Target
->GetType())
751 case cmTarget::EXECUTABLE
: target_type_str
= "EXE"; break;
752 case cmTarget::SHARED_LIBRARY
: target_type_str
= "SHARED_LIBRARY"; break;
753 case cmTarget::MODULE_LIBRARY
: target_type_str
= "SHARED_MODULE"; break;
758 std::string static_link_type_flag_var
= "CMAKE_";
759 static_link_type_flag_var
+= target_type_str
;
760 static_link_type_flag_var
+= "_LINK_STATIC_";
761 static_link_type_flag_var
+= this->LinkLanguage
;
762 static_link_type_flag_var
+= "_FLAGS";
763 static_link_type_flag
=
764 this->Makefile
->GetDefinition(static_link_type_flag_var
.c_str());
766 std::string shared_link_type_flag_var
= "CMAKE_";
767 shared_link_type_flag_var
+= target_type_str
;
768 shared_link_type_flag_var
+= "_LINK_DYNAMIC_";
769 shared_link_type_flag_var
+= this->LinkLanguage
;
770 shared_link_type_flag_var
+= "_FLAGS";
771 shared_link_type_flag
=
772 this->Makefile
->GetDefinition(shared_link_type_flag_var
.c_str());
775 // We can support link type switching only if all needed flags are
777 if(static_link_type_flag
&& *static_link_type_flag
&&
778 shared_link_type_flag
&& *shared_link_type_flag
)
780 this->LinkTypeEnabled
= true;
781 this->StaticLinkTypeFlag
= static_link_type_flag
;
782 this->SharedLinkTypeFlag
= shared_link_type_flag
;
785 // TODO: Lookup the starting link type from the target (is it being
786 // linked statically?).
787 this->StartLinkType
= LinkShared
;
788 this->CurrentLinkType
= this->StartLinkType
;
791 //----------------------------------------------------------------------------
792 void cmComputeLinkInformation::ComputeItemParserInfo()
794 // Get possible library name prefixes.
795 cmMakefile
* mf
= this->Makefile
;
796 this->AddLinkPrefix(mf
->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
797 this->AddLinkPrefix(mf
->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
799 // Import library names should be matched and treated as shared
800 // libraries for the purposes of linking.
801 this->AddLinkExtension(mf
->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
803 this->AddLinkExtension(mf
->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
805 this->AddLinkExtension(mf
->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
807 this->AddLinkExtension(mf
->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
809 if(const char* linkSuffixes
=
810 mf
->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
812 std::vector
<std::string
> linkSuffixVec
;
813 cmSystemTools::ExpandListArgument(linkSuffixes
, linkSuffixVec
);
814 for(std::vector
<std::string
>::iterator i
= linkSuffixVec
.begin();
815 i
!= linkSuffixVec
.end(); ++i
)
817 this->AddLinkExtension(i
->c_str(), LinkUnknown
);
821 // Compute a regex to match link extensions.
822 std::string libext
= this->CreateExtensionRegex(this->LinkExtensions
);
824 // Create regex to remove any library extension.
825 std::string
reg("(.*)");
827 this->OrderLinkerSearchPath
->SetLinkExtensionInfo(this->LinkExtensions
,
830 // Create a regex to match a library name. Match index 1 will be
831 // the prefix if it exists and empty otherwise. Match index 2 will
832 // be the library name. Match index 3 will be the library
835 for(std::set
<cmStdString
>::iterator p
= this->LinkPrefixes
.begin();
836 p
!= this->LinkPrefixes
.end(); ++p
)
844 // Create a regex to match any library name.
845 std::string reg_any
= reg
;
847 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
848 fprintf(stderr
, "any regex [%s]\n", reg_any
.c_str());
850 this->ExtractAnyLibraryName
.compile(reg_any
.c_str());
852 // Create a regex to match static library names.
853 if(!this->StaticLinkExtensions
.empty())
855 std::string reg_static
= reg
;
856 reg_static
+= this->CreateExtensionRegex(this->StaticLinkExtensions
);
857 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
858 fprintf(stderr
, "static regex [%s]\n", reg_static
.c_str());
860 this->ExtractStaticLibraryName
.compile(reg_static
.c_str());
863 // Create a regex to match shared library names.
864 if(!this->SharedLinkExtensions
.empty())
866 std::string reg_shared
= reg
;
867 reg_shared
+= this->CreateExtensionRegex(this->SharedLinkExtensions
);
868 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
869 fprintf(stderr
, "shared regex [%s]\n", reg_shared
.c_str());
871 this->ExtractSharedLibraryName
.compile(reg_shared
.c_str());
875 //----------------------------------------------------------------------------
876 void cmComputeLinkInformation::AddLinkPrefix(const char* p
)
880 this->LinkPrefixes
.insert(p
);
884 //----------------------------------------------------------------------------
885 void cmComputeLinkInformation::AddLinkExtension(const char* e
, LinkType type
)
889 if(type
== LinkStatic
)
891 this->StaticLinkExtensions
.push_back(e
);
893 if(type
== LinkShared
)
895 this->SharedLinkExtensions
.push_back(e
);
897 this->LinkExtensions
.push_back(e
);
901 //----------------------------------------------------------------------------
903 cmComputeLinkInformation
904 ::CreateExtensionRegex(std::vector
<std::string
> const& exts
)
906 // Build a list of extension choices.
907 std::string libext
= "(";
908 const char* sep
= "";
909 for(std::vector
<std::string
>::const_iterator i
= exts
.begin();
910 i
!= exts
.end(); ++i
)
912 // Separate this choice from the previous one.
916 // Store this extension choice with the "." escaped.
918 #if defined(_WIN32) && !defined(__CYGWIN__)
919 libext
+= this->NoCaseExpression(i
->c_str());
930 //----------------------------------------------------------------------------
931 std::string
cmComputeLinkInformation::NoCaseExpression(const char* str
)
953 //-------------------------------------------------------------------
954 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt
)
956 // If we are changing the current link type add the flag to tell the
958 if(this->CurrentLinkType
!= lt
)
960 this->CurrentLinkType
= lt
;
962 if(this->LinkTypeEnabled
)
964 switch(this->CurrentLinkType
)
967 this->Items
.push_back(Item(this->StaticLinkTypeFlag
, false));
970 this->Items
.push_back(Item(this->SharedLinkTypeFlag
, false));
979 //----------------------------------------------------------------------------
980 void cmComputeLinkInformation::AddTargetItem(std::string
const& item
,
983 // This is called to handle a link item that is a full path to a target.
984 // If the target is not a static library make sure the link type is
985 // shared. This is because dynamic-mode linking can handle both
986 // shared and static libraries but static-mode can handle only
987 // static libraries. If a previous user item changed the link type
988 // to static we need to make sure it is back to shared.
989 if(target
->GetType() != cmTarget::STATIC_LIBRARY
)
991 this->SetCurrentLinkType(LinkShared
);
994 // Keep track of shared library targets linked.
995 if(target
->GetType() == cmTarget::SHARED_LIBRARY
)
997 this->SharedLibrariesLinked
.insert(target
);
1000 // Handle case of an imported shared library with no soname.
1001 if(this->NoSONameUsesPath
&&
1002 target
->IsImportedSharedLibWithoutSOName(this->Config
))
1004 this->AddSharedLibNoSOName(item
);
1008 // If this platform wants a flag before the full path, add it.
1009 if(!this->LibLinkFileFlag
.empty())
1011 this->Items
.push_back(Item(this->LibLinkFileFlag
, false));
1014 // For compatibility with CMake 2.4 include the item's directory in
1015 // the linker search path.
1016 if(this->OldLinkDirMode
&& !target
->IsFrameworkOnApple() &&
1017 this->OldLinkDirMask
.find(cmSystemTools::GetFilenamePath(item
)) ==
1018 this->OldLinkDirMask
.end())
1020 this->OldLinkDirItems
.push_back(item
);
1023 // Now add the full path to the library.
1024 this->Items
.push_back(Item(item
, true));
1027 //----------------------------------------------------------------------------
1028 void cmComputeLinkInformation::AddFullItem(std::string
const& item
)
1030 // Check for the implicit link directory special case.
1031 if(this->CheckImplicitDirItem(item
))
1036 // Check for case of shared library with no builtin soname.
1037 if(this->NoSONameUsesPath
&& this->CheckSharedLibNoSOName(item
))
1042 // This is called to handle a link item that is a full path.
1043 // If the target is not a static library make sure the link type is
1044 // shared. This is because dynamic-mode linking can handle both
1045 // shared and static libraries but static-mode can handle only
1046 // static libraries. If a previous user item changed the link type
1047 // to static we need to make sure it is back to shared.
1048 if(this->LinkTypeEnabled
)
1050 std::string name
= cmSystemTools::GetFilenameName(item
);
1051 if(this->ExtractSharedLibraryName
.find(name
))
1053 this->SetCurrentLinkType(LinkShared
);
1055 else if(!this->ExtractStaticLibraryName
.find(item
))
1057 // We cannot determine the type. Assume it is the target's
1059 this->SetCurrentLinkType(this->StartLinkType
);
1063 // For compatibility with CMake 2.4 include the item's directory in
1064 // the linker search path.
1065 if(this->OldLinkDirMode
&&
1066 this->OldLinkDirMask
.find(cmSystemTools::GetFilenamePath(item
)) ==
1067 this->OldLinkDirMask
.end())
1069 this->OldLinkDirItems
.push_back(item
);
1072 // If this platform wants a flag before the full path, add it.
1073 if(!this->LibLinkFileFlag
.empty())
1075 this->Items
.push_back(Item(this->LibLinkFileFlag
, false));
1078 // Now add the full path to the library.
1079 this->Items
.push_back(Item(item
, true));
1082 //----------------------------------------------------------------------------
1083 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string
const& item
)
1085 // We only switch to a pathless item if the link type may be
1086 // enforced. Fortunately only platforms that support link types
1087 // seem to have magic per-architecture implicit link directories.
1088 if(!this->LinkTypeEnabled
)
1093 // Check if this item is in an implicit link directory.
1094 std::string dir
= cmSystemTools::GetFilenamePath(item
);
1095 if(this->ImplicitLinkDirs
.find(dir
) == this->ImplicitLinkDirs
.end())
1097 // Only libraries in implicit link directories are converted to
1102 // Only apply the policy below if the library file is one that can
1103 // be found by the linker.
1104 std::string file
= cmSystemTools::GetFilenameName(item
);
1105 if(!this->ExtractAnyLibraryName
.find(file
))
1110 // Many system linkers support multiple architectures by
1111 // automatically selecting the implicit linker search path for the
1112 // current architecture. If the library appears in an implicit link
1113 // directory then just report the file name without the directory
1114 // portion. This will allow the system linker to locate the proper
1115 // library for the architecture at link time.
1116 this->AddUserItem(file
);
1120 //----------------------------------------------------------------------------
1121 void cmComputeLinkInformation::AddUserItem(std::string
const& item
)
1123 // This is called to handle a link item that does not match a CMake
1124 // target and is not a full path. We check here if it looks like a
1125 // library file name to automatically request the proper link type
1126 // from the linker. For example:
1129 // libfoo.a ==> -Wl,-Bstatic -lfoo
1132 // Parse out the prefix, base, and suffix components of the
1133 // library name. If the name matches that of a shared or static
1134 // library then set the link type accordingly.
1136 // Search for shared library names first because some platforms
1137 // have shared libraries with names that match the static library
1138 // pattern. For example cygwin and msys use the convention
1139 // libfoo.dll.a for import libraries and libfoo.a for static
1140 // libraries. On AIX a library with the name libfoo.a can be
1142 if(this->ExtractSharedLibraryName
.find(item
))
1144 // This matches a shared library file name.
1145 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1146 fprintf(stderr
, "shared regex matched [%s] [%s] [%s]\n",
1147 this->ExtractSharedLibraryName
.match(1).c_str(),
1148 this->ExtractSharedLibraryName
.match(2).c_str(),
1149 this->ExtractSharedLibraryName
.match(3).c_str());
1151 // Set the link type to shared.
1152 this->SetCurrentLinkType(LinkShared
);
1154 // Use just the library name so the linker will search.
1155 lib
= this->ExtractSharedLibraryName
.match(2);
1157 else if(this->ExtractStaticLibraryName
.find(item
))
1159 // This matches a static library file name.
1160 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1161 fprintf(stderr
, "static regex matched [%s] [%s] [%s]\n",
1162 this->ExtractStaticLibraryName
.match(1).c_str(),
1163 this->ExtractStaticLibraryName
.match(2).c_str(),
1164 this->ExtractStaticLibraryName
.match(3).c_str());
1166 // Set the link type to static.
1167 this->SetCurrentLinkType(LinkStatic
);
1169 // Use just the library name so the linker will search.
1170 lib
= this->ExtractStaticLibraryName
.match(2);
1172 else if(this->ExtractAnyLibraryName
.find(item
))
1174 // This matches a library file name.
1175 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1176 fprintf(stderr
, "any regex matched [%s] [%s] [%s]\n",
1177 this->ExtractAnyLibraryName
.match(1).c_str(),
1178 this->ExtractAnyLibraryName
.match(2).c_str(),
1179 this->ExtractAnyLibraryName
.match(3).c_str());
1181 // Restore the target link type since this item does not specify
1183 this->SetCurrentLinkType(this->StartLinkType
);
1185 // Use just the library name so the linker will search.
1186 lib
= this->ExtractAnyLibraryName
.match(2);
1188 else if(item
[0] == '-' || item
[0] == '$' || item
[0] == '`')
1190 if(item
.find("-framework") != 0)
1192 // This is a linker option provided by the user.
1193 this->OldUserFlagItems
.push_back(item
);
1196 // Restore the target link type since this item does not specify
1198 this->SetCurrentLinkType(this->StartLinkType
);
1200 // Use the item verbatim.
1201 this->Items
.push_back(Item(item
, false));
1206 // This is a name specified by the user.
1207 this->OldUserFlagItems
.push_back(item
);
1209 // We must ask the linker to search for a library with this name.
1210 // Restore the target link type since this item does not specify
1212 this->SetCurrentLinkType(this->StartLinkType
);
1216 // Create an option to ask the linker to search for the library.
1217 std::string out
= this->LibLinkFlag
;
1219 out
+= this->LibLinkSuffix
;
1220 this->Items
.push_back(Item(out
, false));
1222 // Here we could try to find the library the linker will find and
1223 // add a runtime information entry for it. It would probably not be
1224 // reliable and we want to encourage use of full paths for library
1228 //----------------------------------------------------------------------------
1229 void cmComputeLinkInformation::AddFrameworkItem(std::string
const& item
)
1231 // Try to separate the framework name and path.
1232 if(!this->SplitFramework
.find(item
.c_str()))
1235 e
<< "Could not parse framework path \"" << item
<< "\" "
1236 << "linked by target " << this->Target
->GetName() << ".";
1237 cmSystemTools::Error(e
.str().c_str());
1241 // Add the directory portion to the framework search path.
1242 this->AddFrameworkPath(this->SplitFramework
.match(1));
1244 // Add the item using the -framework option.
1245 std::string fw
= "-framework ";
1246 fw
+= this->SplitFramework
.match(2);
1247 this->Items
.push_back(Item(fw
, false));
1250 //----------------------------------------------------------------------------
1251 void cmComputeLinkInformation::AddDirectoryItem(std::string
const& item
)
1254 if(cmSystemTools::IsPathToFramework(item
.c_str()))
1256 this->AddFrameworkItem(item
);
1261 this->DropDirectoryItem(item
);
1265 //----------------------------------------------------------------------------
1266 void cmComputeLinkInformation::DropDirectoryItem(std::string
const& item
)
1268 // A full path to a directory was found as a link item. Warn the
1271 e
<< "WARNING: Target \"" << this->Target
->GetName()
1272 << "\" requests linking to directory \"" << item
<< "\". "
1273 << "Targets may link only to libraries. "
1274 << "CMake is dropping the item.";
1275 cmSystemTools::Message(e
.str().c_str());
1278 //----------------------------------------------------------------------------
1279 void cmComputeLinkInformation::ComputeFrameworkInfo()
1281 // Avoid adding system framework paths. See "man ld" on OS X.
1282 this->FrameworkPathsEmmitted
.insert("/Library/Frameworks");
1283 this->FrameworkPathsEmmitted
.insert("/Network/Library/Frameworks");
1284 this->FrameworkPathsEmmitted
.insert("/System/Library/Frameworks");
1286 // Regular expression to extract a framework path and name.
1287 this->SplitFramework
.compile("(.*)/(.*)\\.framework$");
1290 //----------------------------------------------------------------------------
1291 void cmComputeLinkInformation::AddFrameworkPath(std::string
const& p
)
1293 if(this->FrameworkPathsEmmitted
.insert(p
).second
)
1295 this->FrameworkPaths
.push_back(p
);
1299 //----------------------------------------------------------------------------
1300 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string
const& item
)
1302 // This platform will use the path to a library as its soname if the
1303 // library is given via path and was not built with an soname. If
1304 // this is a shared library that might be the case.
1305 std::string file
= cmSystemTools::GetFilenameName(item
);
1306 if(this->ExtractSharedLibraryName
.find(file
))
1308 // If we can guess the soname fairly reliably then assume the
1309 // library has one. Otherwise assume the library has no builtin
1312 if(!cmSystemTools::GuessLibrarySOName(item
, soname
))
1314 this->AddSharedLibNoSOName(item
);
1321 //----------------------------------------------------------------------------
1322 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string
const& item
)
1324 // We have a full path to a shared library with no soname. We need
1325 // to ask the linker to locate the item because otherwise the path
1326 // we give to it will be embedded in the target linked. Then at
1327 // runtime the dynamic linker will search for the library using the
1328 // path instead of just the name.
1329 std::string file
= cmSystemTools::GetFilenameName(item
);
1330 this->AddUserItem(file
);
1332 // Make sure the link directory ordering will find the library.
1333 this->OrderLinkerSearchPath
->AddLinkLibrary(item
);
1336 //----------------------------------------------------------------------------
1337 bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
1339 // Support broken projects if necessary.
1340 if(this->OldLinkDirItems
.empty() || this->OldUserFlagItems
.empty() ||
1341 !this->OldLinkDirMode
)
1346 // Enforce policy constraints.
1347 switch(this->Target
->GetPolicyStatusCMP0003())
1349 case cmPolicies::WARN
:
1350 if(!this->CMakeInstance
->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
1352 this->CMakeInstance
->SetProperty("CMP0003-WARNING-GIVEN", "1");
1354 this->PrintLinkPolicyDiagnosis(w
);
1355 this->CMakeInstance
->IssueMessage(cmake::AUTHOR_WARNING
, w
.str(),
1356 this->Target
->GetBacktrace());
1358 case cmPolicies::OLD
:
1359 // OLD behavior is to add the paths containing libraries with
1360 // known full paths as link directories.
1362 case cmPolicies::NEW
:
1363 // Should never happen due to assignment of OldLinkDirMode
1365 case cmPolicies::REQUIRED_IF_USED
:
1366 case cmPolicies::REQUIRED_ALWAYS
:
1369 e
<< (this->Makefile
->GetPolicies()->
1370 GetRequiredPolicyError(cmPolicies::CMP0003
)) << "\n";
1371 this->PrintLinkPolicyDiagnosis(e
);
1372 this->CMakeInstance
->IssueMessage(cmake::FATAL_ERROR
, e
.str(),
1373 this->Target
->GetBacktrace());
1378 // Add the link directories for full path items.
1379 for(std::vector
<std::string
>::const_iterator
1380 i
= this->OldLinkDirItems
.begin();
1381 i
!= this->OldLinkDirItems
.end(); ++i
)
1383 this->OrderLinkerSearchPath
->AddLinkLibrary(*i
);
1388 //----------------------------------------------------------------------------
1389 void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream
& os
)
1391 // Tell the user what to do.
1392 os
<< "Policy CMP0003 should be set before this line. "
1393 << "Add code such as\n"
1394 << " if(COMMAND cmake_policy)\n"
1395 << " cmake_policy(SET CMP0003 NEW)\n"
1396 << " endif(COMMAND cmake_policy)\n"
1397 << "as early as possible but after the most recent call to "
1398 << "cmake_minimum_required or cmake_policy(VERSION). ";
1400 // List the items that might need the old-style paths.
1401 os
<< "This warning appears because target \""
1402 << this->Target
->GetName() << "\" "
1403 << "links to some libraries for which the linker must search:\n";
1405 // Format the list of unknown items to be as short as possible while
1406 // still fitting in the allowed width (a true solution would be the
1407 // bin packing problem if we were allowed to change the order).
1408 std::string::size_type max_size
= 76;
1410 const char* sep
= " ";
1411 for(std::vector
<std::string
>::const_iterator
1412 i
= this->OldUserFlagItems
.begin();
1413 i
!= this->OldUserFlagItems
.end(); ++i
)
1415 // If the addition of another item will exceed the limit then
1416 // output the current line and reset it. Note that the separator
1417 // is either " " or ", " which is always 2 characters.
1418 if(!line
.empty() && (line
.size() + i
->size() + 2) > max_size
)
1426 // Convert to the other separator.
1435 // List the paths old behavior is adding.
1436 os
<< "and other libraries with known full path:\n";
1437 std::set
<cmStdString
> emitted
;
1438 for(std::vector
<std::string
>::const_iterator
1439 i
= this->OldLinkDirItems
.begin();
1440 i
!= this->OldLinkDirItems
.end(); ++i
)
1442 if(emitted
.insert(cmSystemTools::GetFilenamePath(*i
)).second
)
1444 os
<< " " << *i
<< "\n";
1449 os
<< "CMake is adding directories in the second list to the linker "
1450 << "search path in case they are needed to find libraries from the "
1451 << "first list (for backwards compatibility with CMake 2.4). "
1452 << "Set policy CMP0003 to OLD or NEW to enable or disable this "
1453 << "behavior explicitly. "
1454 << "Run \"cmake --help-policy CMP0003\" for more information.";
1457 //----------------------------------------------------------------------------
1458 std::vector
<std::string
> const&
1459 cmComputeLinkInformation::GetRuntimeSearchPath()
1461 return this->OrderRuntimeSearchPath
->GetOrderedDirectories();
1464 //----------------------------------------------------------------------------
1466 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string
const& fullPath
,
1469 // Skip targets that are not shared libraries (modules cannot be linked).
1470 if(target
->GetType() != cmTarget::SHARED_LIBRARY
)
1475 // Try to get the soname of the library. Only files with this name
1476 // could possibly conflict.
1477 std::string soName
= target
->GetSOName(this->Config
);
1478 const char* soname
= soName
.empty()? 0 : soName
.c_str();
1480 // Include this library in the runtime path ordering.
1481 this->OrderRuntimeSearchPath
->AddRuntimeLibrary(fullPath
, soname
);
1482 if(this->LinkWithRuntimePath
)
1484 this->OrderLinkerSearchPath
->AddRuntimeLibrary(fullPath
, soname
);
1488 //----------------------------------------------------------------------------
1490 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string
const& fullPath
)
1492 // Get the name of the library from the file name.
1493 std::string file
= cmSystemTools::GetFilenameName(fullPath
);
1494 if(!this->ExtractSharedLibraryName
.find(file
.c_str()))
1496 // On some platforms (AIX) a shared library may look static.
1497 if(this->ArchivesMayBeShared
)
1499 if(!this->ExtractStaticLibraryName
.find(file
.c_str()))
1501 // This is not the name of a shared library or archive.
1507 // This is not the name of a shared library.
1512 // Include this library in the runtime path ordering.
1513 this->OrderRuntimeSearchPath
->AddRuntimeLibrary(fullPath
);
1514 if(this->LinkWithRuntimePath
)
1516 this->OrderLinkerSearchPath
->AddRuntimeLibrary(fullPath
);
1520 //----------------------------------------------------------------------------
1521 void cmComputeLinkInformation::GetRPath(std::vector
<std::string
>& runtimeDirs
,
1524 // Select whether to generate runtime search directories.
1525 bool outputRuntime
=
1526 !this->Makefile
->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag
.empty();
1528 // Select whether to generate an rpath for the install tree or the
1530 bool linking_for_install
=
1532 this->Target
->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1533 bool use_install_rpath
=
1534 (outputRuntime
&& this->Target
->HaveInstallTreeRPATH() &&
1535 linking_for_install
);
1536 bool use_build_rpath
=
1537 (outputRuntime
&& this->Target
->HaveBuildTreeRPATH() &&
1538 !linking_for_install
);
1539 bool use_link_rpath
=
1540 outputRuntime
&& linking_for_install
&&
1541 this->Target
->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1543 // Construct the RPATH.
1544 if(use_install_rpath
)
1546 const char* install_rpath
= this->Target
->GetProperty("INSTALL_RPATH");
1547 cmSystemTools::ExpandListArgument(install_rpath
, runtimeDirs
);
1549 if(use_build_rpath
|| use_link_rpath
)
1551 std::vector
<std::string
> const& rdirs
= this->GetRuntimeSearchPath();
1552 for(std::vector
<std::string
>::const_iterator ri
= rdirs
.begin();
1553 ri
!= rdirs
.end(); ++ri
)
1555 // Put this directory in the rpath if using build-tree rpath
1556 // support or if using the link path as an rpath.
1559 runtimeDirs
.push_back(*ri
);
1561 else if(use_link_rpath
)
1563 // Do not add any path inside the source or build tree.
1564 const char* topSourceDir
= this->Makefile
->GetHomeDirectory();
1565 const char* topBinaryDir
= this->Makefile
->GetHomeOutputDirectory();
1566 if(!cmSystemTools::ComparePath(ri
->c_str(), topSourceDir
) &&
1567 !cmSystemTools::ComparePath(ri
->c_str(), topBinaryDir
) &&
1568 !cmSystemTools::IsSubDirectory(ri
->c_str(), topSourceDir
) &&
1569 !cmSystemTools::IsSubDirectory(ri
->c_str(), topBinaryDir
))
1571 runtimeDirs
.push_back(*ri
);
1577 // Add runtime paths required by the platform to always be
1578 // present. This is done even when skipping rpath support.
1579 cmSystemTools::ExpandListArgument(this->RuntimeAlways
.c_str(), runtimeDirs
);
1582 //----------------------------------------------------------------------------
1583 std::string
cmComputeLinkInformation::GetRPathString(bool for_install
)
1585 // Get the directories to use.
1586 std::vector
<std::string
> runtimeDirs
;
1587 this->GetRPath(runtimeDirs
, for_install
);
1589 // Concatenate the paths.
1591 const char* sep
= "";
1592 for(std::vector
<std::string
>::const_iterator ri
= runtimeDirs
.begin();
1593 ri
!= runtimeDirs
.end(); ++ri
)
1595 // Separate from previous path.
1597 sep
= this->GetRuntimeSep().c_str();
1603 // If the rpath will be replaced at install time make sure it is
1605 if(!for_install
&& this->RuntimeUseChrpath
)
1607 std::string::size_type minLength
= this->GetChrpathString().length();
1608 while(rpath
.length() < minLength
)
1610 rpath
+= this->GetRuntimeSep();
1617 //----------------------------------------------------------------------------
1618 std::string
cmComputeLinkInformation::GetChrpathString()
1620 if(!this->RuntimeUseChrpath
)
1625 return this->GetRPathString(true);