Imported Upstream version 2.8.12.2
[platform/upstream/cmake.git] / Source / cmInstallTargetGenerator.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmInstallTargetGenerator.h"
13
14 #include "cmComputeLinkInformation.h"
15 #include "cmGlobalGenerator.h"
16 #include "cmLocalGenerator.h"
17 #include "cmMakefile.h"
18 #include "cmake.h"
19
20 #include <assert.h>
21
22 //----------------------------------------------------------------------------
23 cmInstallTargetGenerator
24 ::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib,
25                            const char* file_permissions,
26                            std::vector<std::string> const& configurations,
27                            const char* component, bool optional):
28   cmInstallGenerator(dest, configurations, component), Target(&t),
29   ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional)
30 {
31   this->ActionsPerConfig = true;
32   this->NamelinkMode = NamelinkModeNone;
33   this->Target->SetHaveInstallRule(true);
34 }
35
36 //----------------------------------------------------------------------------
37 cmInstallTargetGenerator
38 ::~cmInstallTargetGenerator()
39 {
40 }
41
42 //----------------------------------------------------------------------------
43 void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
44 {
45   // Warn if installing an exclude-from-all target.
46   if(this->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
47     {
48     cmOStringStream msg;
49     msg << "WARNING: Target \"" << this->Target->GetName()
50         << "\" has EXCLUDE_FROM_ALL set and will not be built by default "
51         << "but an install rule has been provided for it.  CMake does "
52         << "not define behavior for this case.";
53     cmSystemTools::Message(msg.str().c_str(), "Warning");
54     }
55
56   // Perform the main install script generation.
57   this->cmInstallGenerator::GenerateScript(os);
58 }
59
60 //----------------------------------------------------------------------------
61 void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
62                                                        const char* config,
63                                                        Indent const& indent)
64 {
65   // Compute the build tree directory from which to copy the target.
66   std::string fromDirConfig;
67   if(this->Target->NeedRelinkBeforeInstall(config))
68     {
69     fromDirConfig = this->Target->GetMakefile()->GetStartOutputDirectory();
70     fromDirConfig += cmake::GetCMakeFilesDirectory();
71     fromDirConfig += "/CMakeRelink.dir/";
72     }
73   else
74     {
75     fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
76     fromDirConfig += "/";
77     }
78   std::string toDir = this->GetInstallDestination();
79   toDir += "/";
80
81   // Compute the list of files to install for this target.
82   std::vector<std::string> filesFrom;
83   std::vector<std::string> filesTo;
84   std::string literal_args;
85   cmTarget::TargetType targetType = this->Target->GetType();
86   cmInstallType type = cmInstallType();
87   switch(targetType)
88     {
89     case cmTarget::EXECUTABLE: type = cmInstallType_EXECUTABLE; break;
90     case cmTarget::STATIC_LIBRARY: type = cmInstallType_STATIC_LIBRARY; break;
91     case cmTarget::SHARED_LIBRARY: type = cmInstallType_SHARED_LIBRARY; break;
92     case cmTarget::MODULE_LIBRARY: type = cmInstallType_MODULE_LIBRARY; break;
93     case cmTarget::OBJECT_LIBRARY:
94     case cmTarget::UTILITY:
95     case cmTarget::GLOBAL_TARGET:
96     case cmTarget::UNKNOWN_LIBRARY:
97       this->Target->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
98         "cmInstallTargetGenerator created with non-installable target.");
99       return;
100     }
101   if(targetType == cmTarget::EXECUTABLE)
102     {
103     // There is a bug in cmInstallCommand if this fails.
104     assert(this->NamelinkMode == NamelinkModeNone);
105
106     std::string targetName;
107     std::string targetNameReal;
108     std::string targetNameImport;
109     std::string targetNamePDB;
110     this->Target->GetExecutableNames(targetName, targetNameReal,
111                                      targetNameImport, targetNamePDB,
112                                      config);
113     if(this->ImportLibrary)
114       {
115       std::string from1 = fromDirConfig + targetNameImport;
116       std::string to1 = toDir + targetNameImport;
117       filesFrom.push_back(from1);
118       filesTo.push_back(to1);
119       std::string targetNameImportLib;
120       if(this->Target->GetImplibGNUtoMS(targetNameImport,
121                                         targetNameImportLib))
122         {
123         filesFrom.push_back(fromDirConfig + targetNameImportLib);
124         filesTo.push_back(toDir + targetNameImportLib);
125         }
126
127       // An import library looks like a static library.
128       type = cmInstallType_STATIC_LIBRARY;
129       }
130     else
131       {
132       std::string from1 = fromDirConfig + targetName;
133       std::string to1 = toDir + targetName;
134
135       // Handle OSX Bundles.
136       if(this->Target->IsAppBundleOnApple())
137         {
138         // Install the whole app bundle directory.
139         type = cmInstallType_DIRECTORY;
140         literal_args += " USE_SOURCE_PERMISSIONS";
141         from1 += ".app";
142
143         // Tweaks apply to the binary inside the bundle.
144         to1 += ".app/Contents/MacOS/";
145         to1 += targetName;
146         }
147       else
148         {
149         // Tweaks apply to the real file, so list it first.
150         if(targetNameReal != targetName)
151           {
152           std::string from2 = fromDirConfig + targetNameReal;
153           std::string to2 = toDir += targetNameReal;
154           filesFrom.push_back(from2);
155           filesTo.push_back(to2);
156           }
157         }
158
159       filesFrom.push_back(from1);
160       filesTo.push_back(to1);
161       }
162     }
163   else
164     {
165     std::string targetName;
166     std::string targetNameSO;
167     std::string targetNameReal;
168     std::string targetNameImport;
169     std::string targetNamePDB;
170     this->Target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
171                                   targetNameImport, targetNamePDB,
172                                   config);
173     if(this->ImportLibrary)
174       {
175       // There is a bug in cmInstallCommand if this fails.
176       assert(this->NamelinkMode == NamelinkModeNone);
177
178       std::string from1 = fromDirConfig + targetNameImport;
179       std::string to1 = toDir + targetNameImport;
180       filesFrom.push_back(from1);
181       filesTo.push_back(to1);
182       std::string targetNameImportLib;
183       if(this->Target->GetImplibGNUtoMS(targetNameImport,
184                                         targetNameImportLib))
185         {
186         filesFrom.push_back(fromDirConfig + targetNameImportLib);
187         filesTo.push_back(toDir + targetNameImportLib);
188         }
189
190       // An import library looks like a static library.
191       type = cmInstallType_STATIC_LIBRARY;
192       }
193     else if(this->Target->IsFrameworkOnApple())
194       {
195       // There is a bug in cmInstallCommand if this fails.
196       assert(this->NamelinkMode == NamelinkModeNone);
197
198       // Install the whole framework directory.
199       type = cmInstallType_DIRECTORY;
200       literal_args += " USE_SOURCE_PERMISSIONS";
201
202       std::string from1 = fromDirConfig + targetName;
203       from1 = cmSystemTools::GetFilenamePath(from1);
204
205       // Tweaks apply to the binary inside the bundle.
206       std::string to1 = toDir + targetNameReal;
207
208       filesFrom.push_back(from1);
209       filesTo.push_back(to1);
210       }
211     else
212       {
213       bool haveNamelink = false;
214
215       // Library link name.
216       std::string fromName = fromDirConfig + targetName;
217       std::string toName = toDir + targetName;
218
219       // Library interface name.
220       std::string fromSOName;
221       std::string toSOName;
222       if(targetNameSO != targetName)
223         {
224         haveNamelink = true;
225         fromSOName = fromDirConfig + targetNameSO;
226         toSOName = toDir + targetNameSO;
227         }
228
229       // Library implementation name.
230       std::string fromRealName;
231       std::string toRealName;
232       if(targetNameReal != targetName &&
233          targetNameReal != targetNameSO)
234         {
235         haveNamelink = true;
236         fromRealName = fromDirConfig + targetNameReal;
237         toRealName = toDir + targetNameReal;
238         }
239
240       // Add the names based on the current namelink mode.
241       if(haveNamelink)
242         {
243         // With a namelink we need to check the mode.
244         if(this->NamelinkMode == NamelinkModeOnly)
245           {
246           // Install the namelink only.
247           filesFrom.push_back(fromName);
248           filesTo.push_back(toName);
249           }
250         else
251           {
252           // Install the real file if it has its own name.
253           if(!fromRealName.empty())
254             {
255             filesFrom.push_back(fromRealName);
256             filesTo.push_back(toRealName);
257             }
258
259           // Install the soname link if it has its own name.
260           if(!fromSOName.empty())
261             {
262             filesFrom.push_back(fromSOName);
263             filesTo.push_back(toSOName);
264             }
265
266           // Install the namelink if it is not to be skipped.
267           if(this->NamelinkMode != NamelinkModeSkip)
268             {
269             filesFrom.push_back(fromName);
270             filesTo.push_back(toName);
271             }
272           }
273         }
274       else
275         {
276         // Without a namelink there will be only one file.  Install it
277         // if this is not a namelink-only rule.
278         if(this->NamelinkMode != NamelinkModeOnly)
279           {
280           filesFrom.push_back(fromName);
281           filesTo.push_back(toName);
282           }
283         }
284       }
285     }
286
287   // If this fails the above code is buggy.
288   assert(filesFrom.size() == filesTo.size());
289
290   // Skip this rule if no files are to be installed for the target.
291   if(filesFrom.empty())
292     {
293     return;
294     }
295
296   // Add pre-installation tweaks.
297   this->AddTweak(os, indent, config, filesTo,
298                  &cmInstallTargetGenerator::PreReplacementTweaks);
299
300   // Write code to install the target file.
301   const char* no_dir_permissions = 0;
302   const char* no_rename = 0;
303   bool optional = this->Optional || this->ImportLibrary;
304   this->AddInstallRule(os, type, filesFrom,
305                        optional,
306                        this->FilePermissions.c_str(), no_dir_permissions,
307                        no_rename, literal_args.c_str(),
308                        indent);
309
310   // Add post-installation tweaks.
311   this->AddTweak(os, indent, config, filesTo,
312                  &cmInstallTargetGenerator::PostReplacementTweaks);
313 }
314
315 //----------------------------------------------------------------------------
316 std::string
317 cmInstallTargetGenerator::GetInstallFilename(const char* config) const
318 {
319   NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
320   return
321     cmInstallTargetGenerator::GetInstallFilename(this->Target, config,
322                                                  nameType);
323 }
324
325 //----------------------------------------------------------------------------
326 std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
327                                                          const char* config,
328                                                          NameType nameType)
329 {
330   std::string fname;
331   // Compute the name of the library.
332   if(target->GetType() == cmTarget::EXECUTABLE)
333     {
334     std::string targetName;
335     std::string targetNameReal;
336     std::string targetNameImport;
337     std::string targetNamePDB;
338     target->GetExecutableNames(targetName, targetNameReal,
339                                targetNameImport, targetNamePDB,
340                                config);
341     if(nameType == NameImplib)
342       {
343       // Use the import library name.
344       if(!target->GetImplibGNUtoMS(targetNameImport, fname,
345                                    "${CMAKE_IMPORT_LIBRARY_SUFFIX}"))
346         {
347         fname = targetNameImport;
348         }
349       }
350     else if(nameType == NameReal)
351       {
352       // Use the canonical name.
353       fname = targetNameReal;
354       }
355     else
356       {
357       // Use the canonical name.
358       fname = targetName;
359       }
360     }
361   else
362     {
363     std::string targetName;
364     std::string targetNameSO;
365     std::string targetNameReal;
366     std::string targetNameImport;
367     std::string targetNamePDB;
368     target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
369                             targetNameImport, targetNamePDB, config);
370     if(nameType == NameImplib)
371       {
372       // Use the import library name.
373       if(!target->GetImplibGNUtoMS(targetNameImport, fname,
374                                    "${CMAKE_IMPORT_LIBRARY_SUFFIX}"))
375         {
376         fname = targetNameImport;
377         }
378       }
379     else if(nameType == NameSO)
380       {
381       // Use the soname.
382       fname = targetNameSO;
383       }
384     else if(nameType == NameReal)
385       {
386       // Use the real name.
387       fname = targetNameReal;
388       }
389     else
390       {
391       // Use the canonical name.
392       fname = targetName;
393       }
394     }
395
396   return fname;
397 }
398
399 //----------------------------------------------------------------------------
400 void
401 cmInstallTargetGenerator
402 ::AddTweak(std::ostream& os, Indent const& indent, const char* config,
403            std::string const& file, TweakMethod tweak)
404 {
405   cmOStringStream tw;
406   (this->*tweak)(tw, indent.Next(), config, file);
407   std::string tws = tw.str();
408   if(!tws.empty())
409     {
410     os << indent << "IF(EXISTS \"" << file << "\" AND\n"
411        << indent << "   NOT IS_SYMLINK \"" << file << "\")\n";
412     os << tws;
413     os << indent << "ENDIF()\n";
414     }
415 }
416
417 //----------------------------------------------------------------------------
418 void
419 cmInstallTargetGenerator
420 ::AddTweak(std::ostream& os, Indent const& indent, const char* config,
421            std::vector<std::string> const& files, TweakMethod tweak)
422 {
423   if(files.size() == 1)
424     {
425     // Tweak a single file.
426     this->AddTweak(os, indent, config, this->GetDestDirPath(files[0]), tweak);
427     }
428   else
429     {
430     // Generate a foreach loop to tweak multiple files.
431     cmOStringStream tw;
432     this->AddTweak(tw, indent.Next(), config, "${file}", tweak);
433     std::string tws = tw.str();
434     if(!tws.empty())
435       {
436       Indent indent2 = indent.Next().Next();
437       os << indent << "FOREACH(file\n";
438       for(std::vector<std::string>::const_iterator i = files.begin();
439           i != files.end(); ++i)
440         {
441         os << indent2 << "\"" << this->GetDestDirPath(*i) << "\"\n";
442         }
443       os << indent2 << ")\n";
444       os << tws;
445       os << indent << "ENDFOREACH()\n";
446       }
447     }
448 }
449
450 //----------------------------------------------------------------------------
451 std::string cmInstallTargetGenerator::GetDestDirPath(std::string const& file)
452 {
453   // Construct the path of the file on disk after installation on
454   // which tweaks may be performed.
455   std::string toDestDirPath = "$ENV{DESTDIR}";
456   if(file[0] != '/' && file[0] != '$')
457     {
458     toDestDirPath += "/";
459     }
460   toDestDirPath += file;
461   return toDestDirPath;
462 }
463
464 //----------------------------------------------------------------------------
465 void cmInstallTargetGenerator::PreReplacementTweaks(std::ostream& os,
466                                                     Indent const& indent,
467                                                     const char* config,
468                                                     std::string const& file)
469 {
470   this->AddRPathCheckRule(os, indent, config, file);
471 }
472
473 //----------------------------------------------------------------------------
474 void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os,
475                                                      Indent const& indent,
476                                                      const char* config,
477                                                      std::string const& file)
478 {
479   this->AddInstallNamePatchRule(os, indent, config, file);
480   this->AddChrpathPatchRule(os, indent, config, file);
481   this->AddRanlibRule(os, indent, file);
482   this->AddStripRule(os, indent, file);
483 }
484
485 //----------------------------------------------------------------------------
486 void
487 cmInstallTargetGenerator
488 ::AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
489                           const char* config, std::string const& toDestDirPath)
490 {
491   if(this->ImportLibrary ||
492      !(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
493        this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
494        this->Target->GetType() == cmTarget::EXECUTABLE))
495     {
496     return;
497     }
498
499   // Fix the install_name settings in installed binaries.
500   std::string installNameTool =
501     this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
502
503   if(!installNameTool.size())
504     {
505     return;
506     }
507
508   // Build a map of build-tree install_name to install-tree install_name for
509   // shared libraries linked to this target.
510   std::map<cmStdString, cmStdString> install_name_remap;
511   if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config))
512     {
513     std::set<cmTarget*> const& sharedLibs = cli->GetSharedLibrariesLinked();
514     for(std::set<cmTarget*>::const_iterator j = sharedLibs.begin();
515         j != sharedLibs.end(); ++j)
516       {
517       cmTarget* tgt = *j;
518
519       // The install_name of an imported target does not change.
520       if(tgt->IsImported())
521         {
522         continue;
523         }
524
525       // If the build tree and install tree use different path
526       // components of the install_name field then we need to create a
527       // mapping to be applied after installation.
528       std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
529       std::string for_install = tgt->GetInstallNameDirForInstallTree();
530       if(for_build != for_install)
531         {
532         // The directory portions differ.  Append the filename to
533         // create the mapping.
534         std::string fname =
535           this->GetInstallFilename(tgt, config, NameSO);
536
537         // Map from the build-tree install_name.
538         for_build += fname;
539
540         // Map to the install-tree install_name.
541         for_install += fname;
542
543         // Store the mapping entry.
544         install_name_remap[for_build] = for_install;
545         }
546       }
547     }
548
549   // Edit the install_name of the target itself if necessary.
550   std::string new_id;
551   if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
552     {
553     std::string for_build =
554       this->Target->GetInstallNameDirForBuildTree(config);
555     std::string for_install =
556       this->Target->GetInstallNameDirForInstallTree();
557
558     if(this->Target->IsFrameworkOnApple() && for_install.empty())
559       {
560       // Frameworks seem to have an id corresponding to their own full
561       // path.
562       // ...
563       // for_install = fullDestPath_without_DESTDIR_or_name;
564       }
565
566     // If the install name will change on installation set the new id
567     // on the installed file.
568     if(for_build != for_install)
569       {
570       // Prepare to refer to the install-tree install_name.
571       new_id = for_install;
572       new_id += this->GetInstallFilename(this->Target, config, NameSO);
573       }
574     }
575
576   // Write a rule to run install_name_tool to set the install-tree
577   // install_name value and references.
578   if(!new_id.empty() || !install_name_remap.empty())
579     {
580     os << indent << "EXECUTE_PROCESS(COMMAND \"" << installNameTool;
581     os << "\"";
582     if(!new_id.empty())
583       {
584       os << "\n" << indent << "  -id \"" << new_id << "\"";
585       }
586     for(std::map<cmStdString, cmStdString>::const_iterator
587           i = install_name_remap.begin();
588         i != install_name_remap.end(); ++i)
589       {
590       os << "\n" << indent << "  -change \""
591          << i->first << "\" \"" << i->second << "\"";
592       }
593     os << "\n" << indent << "  \"" << toDestDirPath << "\")\n";
594     }
595 }
596
597 //----------------------------------------------------------------------------
598 void
599 cmInstallTargetGenerator
600 ::AddRPathCheckRule(std::ostream& os, Indent const& indent,
601                     const char* config, std::string const& toDestDirPath)
602 {
603   // Skip the chrpath if the target does not need it.
604   if(this->ImportLibrary || !this->Target->IsChrpathUsed(config))
605     {
606     return;
607     }
608
609   // Skip if on Apple
610   if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
611     {
612     return;
613     }
614
615   // Get the link information for this target.
616   // It can provide the RPATH.
617   cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
618   if(!cli)
619     {
620     return;
621     }
622
623   // Get the install RPATH from the link information.
624   std::string newRpath = cli->GetChrpathString();
625
626   // Write a rule to remove the installed file if its rpath is not the
627   // new rpath.  This is needed for existing build/install trees when
628   // the installed rpath changes but the file is not rebuilt.
629   os << indent << "FILE(RPATH_CHECK\n"
630      << indent << "     FILE \"" << toDestDirPath << "\"\n"
631      << indent << "     RPATH \"" << newRpath << "\")\n";
632 }
633
634 //----------------------------------------------------------------------------
635 void
636 cmInstallTargetGenerator
637 ::AddChrpathPatchRule(std::ostream& os, Indent const& indent,
638                       const char* config, std::string const& toDestDirPath)
639 {
640   // Skip the chrpath if the target does not need it.
641   if(this->ImportLibrary || !this->Target->IsChrpathUsed(config))
642     {
643     return;
644     }
645
646   // Get the link information for this target.
647   // It can provide the RPATH.
648   cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
649   if(!cli)
650     {
651     return;
652     }
653
654   if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
655     {
656     // If using install_name_tool, set up the rules to modify the rpaths.
657     std::string installNameTool =
658       this->Target->GetMakefile()->
659       GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
660
661     std::vector<std::string> oldRuntimeDirs, newRuntimeDirs;
662     cli->GetRPath(oldRuntimeDirs, false);
663     cli->GetRPath(newRuntimeDirs, true);
664
665     // Note: These are separate commands to avoid install_name_tool
666     // corruption on 10.6.
667     for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
668         i != oldRuntimeDirs.end(); ++i)
669       {
670       os << indent << "execute_process(COMMAND " << installNameTool << "\n";
671       os << indent << "  -delete_rpath \"" << *i << "\"\n";
672       os << indent << "  \"" << toDestDirPath << "\")\n";
673       }
674
675     for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
676         i != newRuntimeDirs.end(); ++i)
677       {
678       os << indent << "execute_process(COMMAND " << installNameTool << "\n";
679       os << indent << "  -add_rpath \"" << *i << "\"\n";
680       os << indent << "  \"" << toDestDirPath << "\")\n";
681       }
682     }
683   else
684     {
685     // Construct the original rpath string to be replaced.
686     std::string oldRpath = cli->GetRPathString(false);
687
688     // Get the install RPATH from the link information.
689     std::string newRpath = cli->GetChrpathString();
690
691     // Skip the rule if the paths are identical
692     if(oldRpath == newRpath)
693       {
694       return;
695       }
696
697     // Write a rule to run chrpath to set the install-tree RPATH
698     if(newRpath.empty())
699       {
700       os << indent << "FILE(RPATH_REMOVE\n"
701          << indent << "     FILE \"" << toDestDirPath << "\")\n";
702       }
703     else
704       {
705       os << indent << "FILE(RPATH_CHANGE\n"
706          << indent << "     FILE \"" << toDestDirPath << "\"\n"
707          << indent << "     OLD_RPATH \"" << oldRpath << "\"\n"
708          << indent << "     NEW_RPATH \"" << newRpath << "\")\n";
709       }
710     }
711 }
712
713 //----------------------------------------------------------------------------
714 void
715 cmInstallTargetGenerator::AddStripRule(std::ostream& os,
716                                        Indent const& indent,
717                                        const std::string& toDestDirPath)
718 {
719
720   // don't strip static and import libraries, because it removes the only
721   // symbol table they have so you can't link to them anymore
722   if(this->Target->GetType()==cmTarget::STATIC_LIBRARY || this->ImportLibrary)
723     {
724     return;
725     }
726
727   // Don't handle OSX Bundles.
728   if(this->Target->GetMakefile()->IsOn("APPLE") &&
729      this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
730     {
731     return;
732     }
733
734   if(! this->Target->GetMakefile()->IsSet("CMAKE_STRIP"))
735     {
736     return;
737     }
738
739   os << indent << "IF(CMAKE_INSTALL_DO_STRIP)\n";
740   os << indent << "  EXECUTE_PROCESS(COMMAND \""
741      << this->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
742      << "\" \"" << toDestDirPath << "\")\n";
743   os << indent << "ENDIF(CMAKE_INSTALL_DO_STRIP)\n";
744 }
745
746 //----------------------------------------------------------------------------
747 void
748 cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
749                                         Indent const& indent,
750                                         const std::string& toDestDirPath)
751 {
752   // Static libraries need ranlib on this platform.
753   if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
754     {
755     return;
756     }
757
758   // Perform post-installation processing on the file depending
759   // on its type.
760   if(!this->Target->GetMakefile()->IsOn("APPLE"))
761     {
762     return;
763     }
764
765   std::string ranlib =
766     this->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
767   if(ranlib.empty())
768     {
769     return;
770     }
771
772   os << indent << "EXECUTE_PROCESS(COMMAND \""
773      << ranlib << "\" \"" << toDestDirPath << "\")\n";
774 }