BUG: fix some bad changes in progress calc
[cmake.git] / Source / cmComputeLinkInformation.cxx
blob8b593ab5593c3d935a2a68d5517a4b20aa37de40
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmComputeLinkInformation.cxx,v $
5 Language: C++
6 Date: $Date: 2008-03-02 19:35:23 $
7 Version: $Revision: 1.24 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmComputeLinkInformation.h"
19 #include "cmComputeLinkDepends.h"
20 #include "cmOrderDirectories.h"
22 #include "cmGlobalGenerator.h"
23 #include "cmLocalGenerator.h"
24 #include "cmMakefile.h"
25 #include "cmTarget.h"
26 #include "cmake.h"
28 #include <ctype.h>
30 //#define CM_COMPUTE_LINK_INFO_DEBUG
33 Notes about linking on various platforms:
35 ------------------------------------------------------------------------------
37 Linux, FreeBSD, Mac OS X, IRIX, Sun, Windows:
39 Linking to libraries using the full path works fine.
41 ------------------------------------------------------------------------------
43 On AIX, more work is needed.
45 The "-bnoipath" option is needed. From "man ld":
47 Note: If you specify a shared object, or an archive file
48 containing a shared object, with an absolute or relative path
49 name, instead of with the -lName flag, the path name is
50 included in the import file ID string in the loader section of
51 the output file. You can override this behavior with the
52 -bnoipath option.
54 noipath
56 For shared objects listed on the command-line, rather than
57 specified with the -l flag, use a null path component when
58 listing the shared object in the loader section of the
59 output file. A null path component is always used for
60 shared objects specified with the -l flag. This option
61 does not affect the specification of a path component by
62 using a line beginning with #! in an import file. The
63 default is the ipath option.
65 This prevents the full path specified on the compile line from being
66 compiled directly into the binary.
68 By default the linker places -L paths in the embedded runtime path.
69 In order to implement CMake's RPATH interface correctly, we need the
70 -blibpath:Path option. From "man ld":
72 libpath:Path
74 Uses Path as the library path when writing the loader section
75 of the output file. Path is neither checked for validity nor
76 used when searching for libraries specified by the -l flag.
77 Path overrides any library paths generated when the -L flag is
78 used.
80 If you do not specify any -L flags, or if you specify the
81 nolibpath option, the default library path information is
82 written in the loader section of the output file. The default
83 library path information is the value of the LIBPATH
84 environment variable if it is defined, and /usr/lib:/lib,
85 otherwise.
87 We can pass -Wl,-blibpath:/usr/lib:/lib always to avoid the -L stuff
88 and not break when the user sets LIBPATH. Then if we want to add an
89 rpath we insert it into the option before /usr/lib.
91 ------------------------------------------------------------------------------
93 On HP-UX, more work is needed. There are differences between
94 versions.
96 ld: 92453-07 linker linker ld B.10.33 990520
98 Linking with a full path works okay for static and shared libraries.
99 The linker seems to always put the full path to where the library
100 was found in the binary whether using a full path or -lfoo syntax.
101 Transitive link dependencies work just fine due to the full paths.
103 It has the "-l:libfoo.sl" option. The +nodefaultrpath is accepted
104 but not documented and does not seem to do anything. There is no
105 +forceload option.
107 ld: 92453-07 linker ld HP Itanium(R) B.12.41 IPF/IPF
109 Linking with a full path works okay for static libraries.
111 Linking with a full path works okay for shared libraries. However
112 dependent (transitive) libraries of those linked directly must be
113 either found with an rpath stored in the direct dependencies or
114 found in -L paths as if they were specified with "-l:libfoo.sl"
115 (really "-l:<soname>"). The search matches that of the dynamic
116 loader but only with -L paths. In other words, if we have an
117 executable that links to shared library bar which links to shared
118 library foo, the link line for the exe must contain
120 /dir/with/bar/libbar.sl -L/dir/with/foo
122 It does not matter whether the exe wants to link to foo directly or
123 whether /dir/with/foo/libfoo.sl is listed. The -L path must still
124 be present. It should match the runtime path computed for the
125 executable taking all directly and transitively linked libraries
126 into account.
128 The "+nodefaultrpath" option should be used to avoid getting -L
129 paths in the rpath unless we add our own rpath with +b. This means
130 that skip-build-rpath should use this option.
132 See documentation in "man ld", "man dld.so", and
133 http://docs.hp.com/en/B2355-90968/creatingandusinglibraries.htm
135 +[no]defaultrpath
136 +defaultrpath is the default. Include any paths that are
137 specified with -L in the embedded path, unless you specify the
138 +b option. If you use +b, only the path list specified by +b is
139 in the embedded path.
141 The +nodefaultrpath option removes all library paths that were
142 specified with the -L option from the embedded path. The linker
143 searches the library paths specified by the -L option at link
144 time. At run time, the only library paths searched are those
145 specified by the environment variables LD_LIBRARY_PATH and
146 SHLIB_PATH, library paths specified by the +b linker option, and
147 finally the default library paths.
149 +rpathfirst
150 This option will cause the paths specified in RPATH (embedded
151 path) to be used before the paths specified in LD_LIBRARY_PATH
152 or SHLIB_PATH, in searching for shared libraries. This changes
153 the default search order of LD_LIBRARY_PATH, SHLIB_PATH, and
154 RPATH (embedded path).
156 ------------------------------------------------------------------------------
157 Notes about dependent (transitive) shared libraries:
159 On non-Windows systems shared libraries may have transitive
160 dependencies. In order to support LINK_INTERFACE_LIBRARIES we must
161 support linking to a shared library without listing all the libraries
162 to which it links. Some linkers want to be able to find the
163 transitive dependencies (dependent libraries) of shared libraries
164 listed on the command line.
166 - On Windows, DLLs are not directly linked, and the import libraries
167 have no transitive dependencies.
169 - On Mac, we need to actually list the transitive dependencies.
170 Otherwise when using -isysroot for universal binaries it cannot
171 find the dependent libraries. Listing them on the command line
172 tells the linker where to find them, but unfortunately also links
173 the library.
175 - On HP-UX, the linker wants to find the transitive dependencies of
176 shared libraries in the -L paths even if the dependent libraries
177 are given on the link line.
179 - On AIX the transitive dependencies are not needed.
181 - On SGI, the linker wants to find the transitive dependencies of
182 shared libraries in the -L paths if they are not given on the link
183 line. Transitive linking can be disabled using the options
185 -no_transitive_link -Wl,-no_transitive_link
187 which disable it. Both options must be given when invoking the
188 linker through the compiler.
190 - On Sun, the linker wants to find the transitive dependencies of
191 shared libraries in the -L paths if they are not given on the link
192 line.
194 - On Linux, FreeBSD, and QNX:
196 The linker wants to find the transitive dependencies of shared
197 libraries in the "-rpath-link" paths option if they have not been
198 given on the link line. The option is like rpath but just for
199 link time:
201 -Wl,-rpath-link,"/path1:/path2"
203 For -rpath-link, we need a separate runtime path ordering pass
204 including just the dependent libraries that are not linked.
206 For -L paths on non-HP, we can do the same thing as with rpath-link
207 but put the results in -L paths. The paths should be listed at the
208 end to avoid conflicting with user search paths (?).
210 For -L paths on HP, we should do a runtime path ordering pass with
211 all libraries, both linked and non-linked. Even dependent
212 libraries that are also linked need to be listed in -L paths.
214 In our implementation we add all dependent libraries to the runtime
215 path computation. Then the auto-generated RPATH will find everything.
217 ------------------------------------------------------------------------------
218 Notes about shared libraries with not builtin soname:
220 Some UNIX shared libraries may be created with no builtin soname. On
221 some platforms such libraries cannot be linked using the path to their
222 location because the linker will copy the path into the field used to
223 find the library at runtime.
225 Apple: ../libfoo.dylib ==> libfoo.dylib # ok, uses install_name
226 SGI: ../libfoo.so ==> libfoo.so # ok
227 AIX: ../libfoo.so ==> libfoo.so # ok
228 Linux: ../libfoo.so ==> ../libfoo.so # bad
229 HP-UX: ../libfoo.so ==> ../libfoo.so # bad
230 Sun: ../libfoo.so ==> ../libfoo.so # bad
231 FreeBSD: ../libfoo.so ==> ../libfoo.so # bad
233 In order to link these libraries we need to use the old-style split
234 into -L.. and -lfoo options. This should be fairly safe because most
235 problems with -lfoo options were related to selecting shared libraries
236 instead of static but in this case we want the shared lib. Link
237 directory ordering needs to be done to make sure these shared
238 libraries are found first. There should be very few restrictions
239 because this need be done only for shared libraries without soname-s.
243 //----------------------------------------------------------------------------
244 cmComputeLinkInformation
245 ::cmComputeLinkInformation(cmTarget* target, const char* config)
247 // Store context information.
248 this->Target = target;
249 this->Makefile = this->Target->GetMakefile();
250 this->LocalGenerator = this->Makefile->GetLocalGenerator();
251 this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
252 this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
254 // The configuration being linked.
255 this->Config = config;
257 // Allocate internals.
258 this->OrderLinkerSearchPath =
259 new cmOrderDirectories(this->GlobalGenerator, target->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.
267 this->LinkLanguage =
268 this->Target->GetLinkerLanguage(this->GlobalGenerator);
269 if(!this->LinkLanguage)
271 // The Compute method will do nothing, so skip the rest of the
272 // initialization.
273 return;
276 // Check whether we should use an import library for linking a target.
277 this->UseImportLibrary =
278 this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
280 // On platforms without import libraries there may be a special flag
281 // to use when creating a plugin (module) that obtains symbols from
282 // the program that will load it.
283 this->LoaderFlag = 0;
284 if(!this->UseImportLibrary &&
285 this->Target->GetType() == cmTarget::MODULE_LIBRARY)
287 std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
288 loader_flag_var += this->LinkLanguage;
289 loader_flag_var += "_FLAG";
290 this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var.c_str());
293 // Get options needed to link libraries.
294 this->LibLinkFlag =
295 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
296 this->LibLinkFileFlag =
297 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
298 this->LibLinkSuffix =
299 this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
301 // Get options needed to specify RPATHs.
302 this->RuntimeUseChrpath = false;
303 if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
305 const char* tType =
306 ((this->Target->GetType() == cmTarget::EXECUTABLE)?
307 "EXECUTABLE" : "SHARED_LIBRARY");
308 std::string rtVar = "CMAKE_";
309 rtVar += tType;
310 rtVar += "_RUNTIME_";
311 rtVar += this->LinkLanguage;
312 rtVar += "_FLAG";
313 std::string rtSepVar = rtVar + "_SEP";
314 this->RuntimeFlag = this->Makefile->GetSafeDefinition(rtVar.c_str());
315 this->RuntimeSep = this->Makefile->GetSafeDefinition(rtSepVar.c_str());
316 this->RuntimeAlways =
317 (this->Makefile->
318 GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
319 this->RuntimeUseChrpath = this->Target->IsChrpathUsed();
321 // Get options needed to help find dependent libraries.
322 std::string rlVar = "CMAKE_";
323 rlVar += tType;
324 rlVar += "_RPATH_LINK_";
325 rlVar += this->LinkLanguage;
326 rlVar += "_FLAG";
327 this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar.c_str());
330 // Check if we need to include the runtime search path at link time.
332 std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
333 var += this->LinkLanguage;
334 var += "_WITH_RUNTIME_PATH";
335 this->LinkWithRuntimePath = this->Makefile->IsOn(var.c_str());
338 // Check the platform policy for missing soname case.
339 this->NoSONameUsesPath =
340 this->Makefile->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
342 // Get link type information.
343 this->ComputeLinkTypeInfo();
345 // Setup the link item parser.
346 this->ComputeItemParserInfo();
348 // Setup framework support.
349 this->ComputeFrameworkInfo();
351 // Choose a mode for dealing with shared library dependencies.
352 this->SharedDependencyMode = SharedDepModeNone;
353 if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES"))
355 this->SharedDependencyMode = SharedDepModeLink;
357 else if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS"))
359 this->SharedDependencyMode = SharedDepModeLibDir;
361 else if(!this->RPathLinkFlag.empty())
363 this->SharedDependencyMode = SharedDepModeDir;
364 this->OrderDependentRPath =
365 new cmOrderDirectories(this->GlobalGenerator, target->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 // Initial state.
400 this->HaveUserFlagItem = false;
402 // Decide whether to enable compatible library search path mode.
403 // There exists code that effectively does
405 // /path/to/libA.so -lB
407 // where -lB is meant to link to /path/to/libB.so. This is broken
408 // because it specified -lB without specifying a link directory (-L)
409 // in which to search for B. This worked in CMake 2.4 and below
410 // because -L/path/to would be added by the -L/-l split for A. In
411 // order to support such projects we need to add the directories
412 // containing libraries linked with a full path to the -L path.
413 this->OldLinkDirMode = false;
414 if(this->Makefile->IsOn("CMAKE_LINK_OLD_PATHS") ||
415 this->Makefile->GetLocalGenerator()
416 ->NeedBackwardsCompatibility(2, 4))
418 this->OldLinkDirMode = true;
422 //----------------------------------------------------------------------------
423 cmComputeLinkInformation::~cmComputeLinkInformation()
425 delete this->OrderLinkerSearchPath;
426 delete this->OrderRuntimeSearchPath;
427 delete this->OrderDependentRPath;
430 //----------------------------------------------------------------------------
431 cmComputeLinkInformation::ItemVector const&
432 cmComputeLinkInformation::GetItems()
434 return this->Items;
437 //----------------------------------------------------------------------------
438 std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
440 return this->OrderLinkerSearchPath->GetOrderedDirectories();
443 //----------------------------------------------------------------------------
444 std::string cmComputeLinkInformation::GetRPathLinkString()
446 // If there is no separate linker runtime search flag (-rpath-link)
447 // there is no reason to compute a string.
448 if(!this->OrderDependentRPath)
450 return "";
453 // Construct the linker runtime search path.
454 std::string rpath_link;
455 const char* sep = "";
456 std::vector<std::string> const& dirs =
457 this->OrderDependentRPath->GetOrderedDirectories();
458 for(std::vector<std::string>::const_iterator di = dirs.begin();
459 di != dirs.end(); ++di)
461 rpath_link += sep;
462 sep = ":";
463 rpath_link += *di;
465 return rpath_link;
468 //----------------------------------------------------------------------------
469 std::vector<std::string> const& cmComputeLinkInformation::GetDepends()
471 return this->Depends;
474 //----------------------------------------------------------------------------
475 std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
477 return this->FrameworkPaths;
480 //----------------------------------------------------------------------------
481 std::set<cmTarget*> const&
482 cmComputeLinkInformation::GetSharedLibrariesLinked()
484 return this->SharedLibrariesLinked;
487 //----------------------------------------------------------------------------
488 bool cmComputeLinkInformation::Compute()
490 // Skip targets that do not link.
491 if(!(this->Target->GetType() == cmTarget::EXECUTABLE ||
492 this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
493 this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
494 this->Target->GetType() == cmTarget::STATIC_LIBRARY))
496 return false;
499 // We require a link language for the target.
500 if(!this->LinkLanguage)
502 cmSystemTools::
503 Error("CMake can not determine linker language for target:",
504 this->Target->GetName());
505 return false;
508 // Compute the ordered link line items.
509 cmComputeLinkDepends cld(this->Target, this->Config);
510 cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
512 // Add the link line items.
513 for(cmComputeLinkDepends::EntryVector::const_iterator
514 lei = linkEntries.begin();
515 lei != linkEntries.end(); ++lei)
517 if(lei->IsSharedDep)
519 this->AddSharedDepItem(lei->Item, lei->Target);
521 else
523 this->AddItem(lei->Item, lei->Target);
527 // Restore the target link type so the correct system runtime
528 // libraries are found.
529 const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
530 if(cmSystemTools::IsOn(lss))
532 this->SetCurrentLinkType(LinkStatic);
534 else
536 this->SetCurrentLinkType(this->StartLinkType);
539 // Finish setting up linker search directories.
540 this->FinishLinkerSearchDirectories();
542 return true;
545 //----------------------------------------------------------------------------
546 void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
548 // Compute the proper name to use to link this library.
549 const char* config = this->Config;
550 bool impexe = (tgt && tgt->IsExecutableWithExports());
551 if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
553 // Skip linking to executables on platforms with no import
554 // libraries or loader flags.
555 return;
558 if(tgt && (tgt->GetType() == cmTarget::STATIC_LIBRARY ||
559 tgt->GetType() == cmTarget::SHARED_LIBRARY ||
560 tgt->GetType() == cmTarget::MODULE_LIBRARY ||
561 impexe))
563 // This is a CMake target. Ask the target for its real name.
564 if(impexe && this->LoaderFlag)
566 // This link item is an executable that may provide symbols
567 // used by this target. A special flag is needed on this
568 // platform. Add it now.
569 std::string linkItem;
570 linkItem = this->LoaderFlag;
571 std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
572 true);
573 linkItem += exe;
574 this->Items.push_back(Item(linkItem, true));
575 this->Depends.push_back(exe);
577 else
579 // Decide whether to use an import library.
580 bool implib =
581 (this->UseImportLibrary &&
582 (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
584 // Pass the full path to the target file.
585 std::string lib = tgt->GetFullPath(config, implib, true);
586 this->Depends.push_back(lib);
588 if(tgt->IsFrameworkOnApple())
590 // Frameworks on OS X need only the framework directory to
591 // link.
592 std::string fw = tgt->GetDirectory(config, implib);
593 this->AddFrameworkItem(fw);
595 else
597 this->AddTargetItem(lib, tgt);
598 this->AddLibraryRuntimeInfo(lib, tgt);
602 else
604 // This is not a CMake target. Use the name given.
605 if(cmSystemTools::FileIsFullPath(item.c_str()))
607 if(cmSystemTools::FileIsDirectory(item.c_str()))
609 // This is a directory.
610 this->AddDirectoryItem(item);
612 else
614 // Use the full path given to the library file.
615 this->Depends.push_back(item);
616 this->AddFullItem(item);
617 this->AddLibraryRuntimeInfo(item);
620 else
622 // This is a library or option specified by the user.
623 this->AddUserItem(item);
628 //----------------------------------------------------------------------------
629 void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
630 cmTarget* tgt)
632 // If dropping shared library dependencies, ignore them.
633 if(this->SharedDependencyMode == SharedDepModeNone)
635 return;
638 // The user may have incorrectly named an item. Skip items that are
639 // not full paths to shared libraries.
640 if(tgt)
642 // The target will provide a full path. Make sure it is a shared
643 // library.
644 if(tgt->GetType() != cmTarget::SHARED_LIBRARY)
646 return;
649 else
651 // Skip items that are not full paths. We will not be able to
652 // reliably specify them.
653 if(!cmSystemTools::FileIsFullPath(item.c_str()))
655 return;
658 // Get the name of the library from the file name.
659 std::string file = cmSystemTools::GetFilenameName(item);
660 if(!this->ExtractSharedLibraryName.find(file.c_str()))
662 // This is not the name of a shared library.
663 return;
667 // If in linking mode, just link to the shared library.
668 if(this->SharedDependencyMode == SharedDepModeLink)
670 this->AddItem(item, tgt);
671 return;
674 // Get a full path to the dependent shared library.
675 // Add it to the runtime path computation so that the target being
676 // linked will be able to find it.
677 std::string lib;
678 if(tgt)
680 lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
681 this->AddLibraryRuntimeInfo(lib, tgt);
683 else
685 lib = item;
686 this->AddLibraryRuntimeInfo(lib);
689 // Check if we need to include the dependent shared library in other
690 // path ordering.
691 cmOrderDirectories* order = 0;
692 if(this->SharedDependencyMode == SharedDepModeLibDir &&
693 !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */)
695 // Add the item to the linker search path.
696 order = this->OrderLinkerSearchPath;
698 else if(this->SharedDependencyMode == SharedDepModeDir)
700 // Add the item to the separate dependent library search path.
701 order = this->OrderDependentRPath;
703 if(order)
705 if(tgt)
707 std::string soName = tgt->GetSOName(this->Config);
708 const char* soname = soName.empty()? 0 : soName.c_str();
709 order->AddRuntimeLibrary(lib, soname);
711 else
713 order->AddRuntimeLibrary(lib);
718 //----------------------------------------------------------------------------
719 void cmComputeLinkInformation::ComputeLinkTypeInfo()
721 // Check whether archives may actually be shared libraries.
722 this->ArchivesMayBeShared =
723 this->CMakeInstance->GetPropertyAsBool(
724 "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
726 // First assume we cannot do link type stuff.
727 this->LinkTypeEnabled = false;
729 // Lookup link type selection flags.
730 const char* static_link_type_flag = 0;
731 const char* shared_link_type_flag = 0;
732 const char* target_type_str = 0;
733 switch(this->Target->GetType())
735 case cmTarget::EXECUTABLE: target_type_str = "EXE"; break;
736 case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
737 case cmTarget::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
738 default: break;
740 if(target_type_str)
742 std::string static_link_type_flag_var = "CMAKE_";
743 static_link_type_flag_var += target_type_str;
744 static_link_type_flag_var += "_LINK_STATIC_";
745 static_link_type_flag_var += this->LinkLanguage;
746 static_link_type_flag_var += "_FLAGS";
747 static_link_type_flag =
748 this->Makefile->GetDefinition(static_link_type_flag_var.c_str());
750 std::string shared_link_type_flag_var = "CMAKE_";
751 shared_link_type_flag_var += target_type_str;
752 shared_link_type_flag_var += "_LINK_DYNAMIC_";
753 shared_link_type_flag_var += this->LinkLanguage;
754 shared_link_type_flag_var += "_FLAGS";
755 shared_link_type_flag =
756 this->Makefile->GetDefinition(shared_link_type_flag_var.c_str());
759 // We can support link type switching only if all needed flags are
760 // known.
761 if(static_link_type_flag && *static_link_type_flag &&
762 shared_link_type_flag && *shared_link_type_flag)
764 this->LinkTypeEnabled = true;
765 this->StaticLinkTypeFlag = static_link_type_flag;
766 this->SharedLinkTypeFlag = shared_link_type_flag;
769 // TODO: Lookup the starting link type from the target (is it being
770 // linked statically?).
771 this->StartLinkType = LinkShared;
772 this->CurrentLinkType = this->StartLinkType;
775 //----------------------------------------------------------------------------
776 void cmComputeLinkInformation::ComputeItemParserInfo()
778 // Get possible library name prefixes.
779 cmMakefile* mf = this->Makefile;
780 this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
781 this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
783 // Import library names should be matched and treated as shared
784 // libraries for the purposes of linking.
785 this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
786 LinkShared);
787 this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
788 LinkStatic);
789 this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
790 LinkShared);
791 this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
792 LinkUnknown);
793 if(const char* linkSuffixes =
794 mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
796 std::vector<std::string> linkSuffixVec;
797 cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
798 for(std::vector<std::string>::iterator i = linkSuffixVec.begin();
799 i != linkSuffixVec.end(); ++i)
801 this->AddLinkExtension(i->c_str(), LinkUnknown);
805 // Compute a regex to match link extensions.
806 std::string libext = this->CreateExtensionRegex(this->LinkExtensions);
808 // Create regex to remove any library extension.
809 std::string reg("(.*)");
810 reg += libext;
811 this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
812 reg);
814 // Create a regex to match a library name. Match index 1 will be
815 // the prefix if it exists and empty otherwise. Match index 2 will
816 // be the library name. Match index 3 will be the library
817 // extension.
818 reg = "^(";
819 for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
820 p != this->LinkPrefixes.end(); ++p)
822 reg += *p;
823 reg += "|";
825 reg += ")";
826 reg += "([^/]*)";
828 // Create a regex to match any library name.
829 std::string reg_any = reg;
830 reg_any += libext;
831 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
832 fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
833 #endif
834 this->ExtractAnyLibraryName.compile(reg_any.c_str());
836 // Create a regex to match static library names.
837 if(!this->StaticLinkExtensions.empty())
839 std::string reg_static = reg;
840 reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
841 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
842 fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
843 #endif
844 this->ExtractStaticLibraryName.compile(reg_static.c_str());
847 // Create a regex to match shared library names.
848 if(!this->SharedLinkExtensions.empty())
850 std::string reg_shared = reg;
851 reg_shared += this->CreateExtensionRegex(this->SharedLinkExtensions);
852 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
853 fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
854 #endif
855 this->ExtractSharedLibraryName.compile(reg_shared.c_str());
859 //----------------------------------------------------------------------------
860 void cmComputeLinkInformation::AddLinkPrefix(const char* p)
862 if(p)
864 this->LinkPrefixes.insert(p);
868 //----------------------------------------------------------------------------
869 void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
871 if(e && *e)
873 if(type == LinkStatic)
875 this->StaticLinkExtensions.push_back(e);
877 if(type == LinkShared)
879 this->SharedLinkExtensions.push_back(e);
881 this->LinkExtensions.push_back(e);
885 //----------------------------------------------------------------------------
886 std::string
887 cmComputeLinkInformation
888 ::CreateExtensionRegex(std::vector<std::string> const& exts)
890 // Build a list of extension choices.
891 std::string libext = "(";
892 const char* sep = "";
893 for(std::vector<std::string>::const_iterator i = exts.begin();
894 i != exts.end(); ++i)
896 // Separate this choice from the previous one.
897 libext += sep;
898 sep = "|";
900 // Store this extension choice with the "." escaped.
901 libext += "\\";
902 #if defined(_WIN32) && !defined(__CYGWIN__)
903 libext += this->NoCaseExpression(i->c_str());
904 #else
905 libext += *i;
906 #endif
909 // Finish the list.
910 libext += ")$";
911 return libext;
914 //----------------------------------------------------------------------------
915 std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
917 std::string ret;
918 const char* s = str;
919 while(*s)
921 if(*s == '.')
923 ret += *s;
925 else
927 ret += "[";
928 ret += tolower(*s);
929 ret += toupper(*s);
930 ret += "]";
932 s++;
934 return ret;
937 //-------------------------------------------------------------------
938 void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
940 // If we are changing the current link type add the flag to tell the
941 // linker about it.
942 if(this->CurrentLinkType != lt)
944 this->CurrentLinkType = lt;
946 if(this->LinkTypeEnabled)
948 switch(this->CurrentLinkType)
950 case LinkStatic:
951 this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
952 break;
953 case LinkShared:
954 this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
955 break;
956 default:
957 break;
963 //----------------------------------------------------------------------------
964 void cmComputeLinkInformation::AddTargetItem(std::string const& item,
965 cmTarget* target)
967 // This is called to handle a link item that is a full path to a target.
968 // If the target is not a static library make sure the link type is
969 // shared. This is because dynamic-mode linking can handle both
970 // shared and static libraries but static-mode can handle only
971 // static libraries. If a previous user item changed the link type
972 // to static we need to make sure it is back to shared.
973 if(target->GetType() != cmTarget::STATIC_LIBRARY)
975 this->SetCurrentLinkType(LinkShared);
978 // Keep track of shared library targets linked.
979 if(target->GetType() == cmTarget::SHARED_LIBRARY)
981 this->SharedLibrariesLinked.insert(target);
984 // Handle case of an imported shared library with no soname.
985 if(this->NoSONameUsesPath &&
986 target->IsImportedSharedLibWithoutSOName(this->Config))
988 this->AddSharedLibNoSOName(item);
989 return;
992 // If this platform wants a flag before the full path, add it.
993 if(!this->LibLinkFileFlag.empty())
995 this->Items.push_back(Item(this->LibLinkFileFlag, false));
998 // Now add the full path to the library.
999 this->Items.push_back(Item(item, true));
1002 //----------------------------------------------------------------------------
1003 void cmComputeLinkInformation::AddFullItem(std::string const& item)
1005 // Check for the implicit link directory special case.
1006 if(this->CheckImplicitDirItem(item))
1008 return;
1011 // Check for case of shared library with no builtin soname.
1012 if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
1014 return;
1017 // This is called to handle a link item that is a full path.
1018 // If the target is not a static library make sure the link type is
1019 // shared. This is because dynamic-mode linking can handle both
1020 // shared and static libraries but static-mode can handle only
1021 // static libraries. If a previous user item changed the link type
1022 // to static we need to make sure it is back to shared.
1023 if(this->LinkTypeEnabled)
1025 std::string name = cmSystemTools::GetFilenameName(item);
1026 if(this->ExtractSharedLibraryName.find(name))
1028 this->SetCurrentLinkType(LinkShared);
1030 else if(!this->ExtractStaticLibraryName.find(item))
1032 // We cannot determine the type. Assume it is the target's
1033 // default type.
1034 this->SetCurrentLinkType(this->StartLinkType);
1038 // For compatibility with CMake 2.4 include the item's directory in
1039 // the linker search path.
1040 if(this->OldLinkDirMode)
1042 this->OldLinkDirItems.push_back(item);
1045 // If this platform wants a flag before the full path, add it.
1046 if(!this->LibLinkFileFlag.empty())
1048 this->Items.push_back(Item(this->LibLinkFileFlag, false));
1051 // Now add the full path to the library.
1052 this->Items.push_back(Item(item, true));
1055 //----------------------------------------------------------------------------
1056 bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
1058 // We only switch to a pathless item if the link type may be
1059 // enforced. Fortunately only platforms that support link types
1060 // seem to have magic per-architecture implicit link directories.
1061 if(!this->LinkTypeEnabled)
1063 return false;
1066 // Check if this item is in an implicit link directory.
1067 std::string dir = cmSystemTools::GetFilenamePath(item);
1068 if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
1070 // Only libraries in implicit link directories are converted to
1071 // pathless items.
1072 return false;
1075 // Only apply the policy below if the library file is one that can
1076 // be found by the linker.
1077 std::string file = cmSystemTools::GetFilenameName(item);
1078 if(!this->ExtractAnyLibraryName.find(file))
1080 return false;
1083 // Many system linkers support multiple architectures by
1084 // automatically selecting the implicit linker search path for the
1085 // current architecture. If the library appears in an implicit link
1086 // directory then just report the file name without the directory
1087 // portion. This will allow the system linker to locate the proper
1088 // library for the architecture at link time.
1089 this->AddUserItem(file);
1090 return true;
1093 //----------------------------------------------------------------------------
1094 void cmComputeLinkInformation::AddUserItem(std::string const& item)
1096 // This is called to handle a link item that does not match a CMake
1097 // target and is not a full path. We check here if it looks like a
1098 // library file name to automatically request the proper link type
1099 // from the linker. For example:
1101 // foo ==> -lfoo
1102 // libfoo.a ==> -Wl,-Bstatic -lfoo
1103 std::string lib;
1105 // Parse out the prefix, base, and suffix components of the
1106 // library name. If the name matches that of a shared or static
1107 // library then set the link type accordingly.
1109 // Search for shared library names first because some platforms
1110 // have shared libraries with names that match the static library
1111 // pattern. For example cygwin and msys use the convention
1112 // libfoo.dll.a for import libraries and libfoo.a for static
1113 // libraries. On AIX a library with the name libfoo.a can be
1114 // shared!
1115 if(this->ExtractSharedLibraryName.find(item))
1117 // This matches a shared library file name.
1118 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1119 fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
1120 this->ExtractSharedLibraryName.match(1).c_str(),
1121 this->ExtractSharedLibraryName.match(2).c_str(),
1122 this->ExtractSharedLibraryName.match(3).c_str());
1123 #endif
1124 // Set the link type to shared.
1125 this->SetCurrentLinkType(LinkShared);
1127 // Use just the library name so the linker will search.
1128 lib = this->ExtractSharedLibraryName.match(2);
1130 else if(this->ExtractStaticLibraryName.find(item))
1132 // This matches a static library file name.
1133 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1134 fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
1135 this->ExtractStaticLibraryName.match(1).c_str(),
1136 this->ExtractStaticLibraryName.match(2).c_str(),
1137 this->ExtractStaticLibraryName.match(3).c_str());
1138 #endif
1139 // Set the link type to static.
1140 this->SetCurrentLinkType(LinkStatic);
1142 // Use just the library name so the linker will search.
1143 lib = this->ExtractStaticLibraryName.match(2);
1145 else if(this->ExtractAnyLibraryName.find(item))
1147 // This matches a library file name.
1148 #ifdef CM_COMPUTE_LINK_INFO_DEBUG
1149 fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
1150 this->ExtractAnyLibraryName.match(1).c_str(),
1151 this->ExtractAnyLibraryName.match(2).c_str(),
1152 this->ExtractAnyLibraryName.match(3).c_str());
1153 #endif
1154 // Restore the target link type since this item does not specify
1155 // one.
1156 this->SetCurrentLinkType(this->StartLinkType);
1158 // Use just the library name so the linker will search.
1159 lib = this->ExtractAnyLibraryName.match(2);
1161 else if(item[0] == '-' || item[0] == '$' || item[0] == '`')
1163 // This is a linker option provided by the user.
1164 this->HaveUserFlagItem = true;
1166 // Restore the target link type since this item does not specify
1167 // one.
1168 this->SetCurrentLinkType(this->StartLinkType);
1170 // Use the item verbatim.
1171 this->Items.push_back(Item(item, false));
1172 return;
1174 else
1176 // This is a name specified by the user.
1177 this->HaveUserFlagItem = true;
1179 // We must ask the linker to search for a library with this name.
1180 // Restore the target link type since this item does not specify
1181 // one.
1182 this->SetCurrentLinkType(this->StartLinkType);
1183 lib = item;
1186 // Create an option to ask the linker to search for the library.
1187 std::string out = this->LibLinkFlag;
1188 out += lib;
1189 out += this->LibLinkSuffix;
1190 this->Items.push_back(Item(out, false));
1192 // Here we could try to find the library the linker will find and
1193 // add a runtime information entry for it. It would probably not be
1194 // reliable and we want to encourage use of full paths for library
1195 // specification.
1198 //----------------------------------------------------------------------------
1199 void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
1201 // Try to separate the framework name and path.
1202 if(!this->SplitFramework.find(item.c_str()))
1204 cmOStringStream e;
1205 e << "Could not parse framework path \"" << item << "\" "
1206 << "linked by target " << this->Target->GetName() << ".";
1207 cmSystemTools::Error(e.str().c_str());
1208 return;
1211 // Add the directory portion to the framework search path.
1212 this->AddFrameworkPath(this->SplitFramework.match(1));
1214 // Add the item using the -framework option.
1215 std::string fw = "-framework ";
1216 fw += this->SplitFramework.match(2);
1217 this->Items.push_back(Item(fw, false));
1220 //----------------------------------------------------------------------------
1221 void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
1223 #ifdef __APPLE__
1224 if(cmSystemTools::IsPathToFramework(item.c_str()))
1226 this->AddFrameworkItem(item);
1228 else
1229 #endif
1231 this->DropDirectoryItem(item);
1235 //----------------------------------------------------------------------------
1236 void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
1238 // A full path to a directory was found as a link item. Warn the
1239 // user.
1240 cmOStringStream e;
1241 e << "WARNING: Target \"" << this->Target->GetName()
1242 << "\" requests linking to directory \"" << item << "\". "
1243 << "Targets may link only to libraries. "
1244 << "CMake is dropping the item.";
1245 cmSystemTools::Message(e.str().c_str());
1248 //----------------------------------------------------------------------------
1249 void cmComputeLinkInformation::ComputeFrameworkInfo()
1251 // Avoid adding system framework paths. See "man ld" on OS X.
1252 this->FrameworkPathsEmmitted.insert("/Library/Frameworks");
1253 this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks");
1254 this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks");
1256 // Regular expression to extract a framework path and name.
1257 this->SplitFramework.compile("(.*)/(.*)\\.framework$");
1260 //----------------------------------------------------------------------------
1261 void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
1263 if(this->FrameworkPathsEmmitted.insert(p).second)
1265 this->FrameworkPaths.push_back(p);
1269 //----------------------------------------------------------------------------
1270 bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
1272 // This platform will use the path to a library as its soname if the
1273 // library is given via path and was not built with an soname. If
1274 // this is a shared library that might be the case.
1275 std::string file = cmSystemTools::GetFilenameName(item);
1276 if(this->ExtractSharedLibraryName.find(file))
1278 // If we can guess the soname fairly reliably then assume the
1279 // library has one. Otherwise assume the library has no builtin
1280 // soname.
1281 std::string soname;
1282 if(!cmSystemTools::GuessLibrarySOName(item, soname))
1284 this->AddSharedLibNoSOName(item);
1285 return true;
1288 return false;
1291 //----------------------------------------------------------------------------
1292 void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
1294 // We have a full path to a shared library with no soname. We need
1295 // to ask the linker to locate the item because otherwise the path
1296 // we give to it will be embedded in the target linked. Then at
1297 // runtime the dynamic linker will search for the library using the
1298 // path instead of just the name.
1299 std::string file = cmSystemTools::GetFilenameName(item);
1300 this->AddUserItem(file);
1302 // Make sure the link directory ordering will find the library.
1303 this->OrderLinkerSearchPath->AddLinkLibrary(item);
1306 //----------------------------------------------------------------------------
1307 void cmComputeLinkInformation::FinishLinkerSearchDirectories()
1309 // Support broken projects if necessary.
1310 if(this->HaveUserFlagItem && this->OldLinkDirMode)
1312 for(std::vector<std::string>::const_iterator
1313 i = this->OldLinkDirItems.begin();
1314 i != this->OldLinkDirItems.end(); ++i)
1316 this->OrderLinkerSearchPath->AddLinkLibrary(*i);
1321 //----------------------------------------------------------------------------
1322 std::vector<std::string> const&
1323 cmComputeLinkInformation::GetRuntimeSearchPath()
1325 return this->OrderRuntimeSearchPath->GetOrderedDirectories();
1328 //----------------------------------------------------------------------------
1329 void
1330 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
1331 cmTarget* target)
1333 // Skip targets that are not shared libraries (modules cannot be linked).
1334 if(target->GetType() != cmTarget::SHARED_LIBRARY)
1336 return;
1339 // Try to get the soname of the library. Only files with this name
1340 // could possibly conflict.
1341 std::string soName = target->GetSOName(this->Config);
1342 const char* soname = soName.empty()? 0 : soName.c_str();
1344 // Include this library in the runtime path ordering.
1345 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
1346 if(this->LinkWithRuntimePath)
1348 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
1352 //----------------------------------------------------------------------------
1353 void
1354 cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
1356 // Get the name of the library from the file name.
1357 std::string file = cmSystemTools::GetFilenameName(fullPath);
1358 if(!this->ExtractSharedLibraryName.find(file.c_str()))
1360 // On some platforms (AIX) a shared library may look static.
1361 if(this->ArchivesMayBeShared)
1363 if(!this->ExtractStaticLibraryName.find(file.c_str()))
1365 // This is not the name of a shared library or archive.
1366 return;
1369 else
1371 // This is not the name of a shared library.
1372 return;
1376 // Include this library in the runtime path ordering.
1377 this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
1378 if(this->LinkWithRuntimePath)
1380 this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
1384 //----------------------------------------------------------------------------
1385 void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
1386 bool for_install)
1388 // Select whether to generate runtime search directories.
1389 bool outputRuntime =
1390 !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
1392 // Select whether to generate an rpath for the install tree or the
1393 // build tree.
1394 bool linking_for_install =
1395 (for_install ||
1396 this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
1397 bool use_install_rpath =
1398 (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
1399 linking_for_install);
1400 bool use_build_rpath =
1401 (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
1402 !linking_for_install);
1403 bool use_link_rpath =
1404 outputRuntime && linking_for_install &&
1405 this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
1407 // Construct the RPATH.
1408 if(use_install_rpath)
1410 const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
1411 cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
1413 if(use_build_rpath || use_link_rpath)
1415 std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
1416 for(std::vector<std::string>::const_iterator ri = rdirs.begin();
1417 ri != rdirs.end(); ++ri)
1419 // Put this directory in the rpath if using build-tree rpath
1420 // support or if using the link path as an rpath.
1421 if(use_build_rpath)
1423 runtimeDirs.push_back(*ri);
1425 else if(use_link_rpath)
1427 // Do not add any path inside the source or build tree.
1428 const char* topSourceDir = this->Makefile->GetHomeDirectory();
1429 const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
1430 if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
1431 !cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
1432 !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
1433 !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
1435 runtimeDirs.push_back(*ri);
1441 // Add runtime paths required by the platform to always be
1442 // present. This is done even when skipping rpath support.
1443 cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs);
1446 //----------------------------------------------------------------------------
1447 std::string cmComputeLinkInformation::GetRPathString(bool for_install)
1449 // Get the directories to use.
1450 std::vector<std::string> runtimeDirs;
1451 this->GetRPath(runtimeDirs, for_install);
1453 // Concatenate the paths.
1454 std::string rpath;
1455 const char* sep = "";
1456 for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin();
1457 ri != runtimeDirs.end(); ++ri)
1459 // Separate from previous path.
1460 rpath += sep;
1461 sep = this->GetRuntimeSep().c_str();
1463 // Add this path.
1464 rpath += *ri;
1467 // If the rpath will be replaced at install time make sure it is
1468 // long enough now.
1469 if(!for_install && this->RuntimeUseChrpath)
1471 std::string::size_type minLength = this->GetChrpathString().length();
1472 while(rpath.length() < minLength)
1474 rpath += this->GetRuntimeSep();
1478 return rpath;
1481 //----------------------------------------------------------------------------
1482 std::string cmComputeLinkInformation::GetChrpathString()
1484 if(!this->RuntimeUseChrpath)
1486 return "";
1489 return this->GetRPathString(true);