cmInstallTargetGenerator.cxx 22.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "cmInstallTargetGenerator.h"

19
#include "cmComputeLinkInformation.h"
20
21
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
22
#include "cmMakefile.h"
23
#include "cmake.h"
24

25
26
#include <assert.h>

27
28
//----------------------------------------------------------------------------
cmInstallTargetGenerator
29
::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib,
30
                           const char* file_permissions,
31
                           std::vector<std::string> const& configurations,
32
                           const char* component, bool optional):
33
34
  cmInstallGenerator(dest, configurations, component), Target(&t),
  ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional)
35
{
36
  this->NamelinkMode = NamelinkModeNone;
37
  this->Target->SetHaveInstallRule(true);
38
39
40
41
42
43
44
45
46
47
48
}

//----------------------------------------------------------------------------
cmInstallTargetGenerator
::~cmInstallTargetGenerator()
{
}

//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
{
49
50
51
52
53
54
55
56
57
58
59
  // Warn if installing an exclude-from-all target.
  if(this->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
    {
    cmOStringStream msg;
    msg << "WARNING: Target \"" << this->Target->GetName()
        << "\" has EXCLUDE_FROM_ALL set and will not be built by default "
        << "but an install rule has been provided for it.  CMake does "
        << "not define behavior for this case.";
    cmSystemTools::Message(msg.str().c_str(), "Warning");
    }

60
  // Compute the build tree directory from which to copy the target.
61
  std::string& fromDir = this->FromDir;
62
63
64
  if(this->Target->NeedRelinkBeforeInstall())
    {
    fromDir = this->Target->GetMakefile()->GetStartOutputDirectory();
65
66
    fromDir += cmake::GetCMakeFilesDirectory();
    fromDir += "/CMakeRelink.dir/";
67
68
69
    }
  else
    {
70
    fromDir = this->Target->GetDirectory(0, this->ImportLibrary);
71
72
73
    fromDir += "/";
    }

74
75
76
77
78
79
80
81
  // Perform the main install script generation.
  this->cmInstallGenerator::GenerateScript(os);
}

//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScriptConfigs(std::ostream& os,
                                                     Indent const& indent)
{
82
83
  if(this->ConfigurationTypes->empty())
    {
84
85
86
87
    // In a single-configuration generator, only the install rule's
    // configuration test is important.  If that passes, the target is
    // installed regardless of for what configuration it was built.
    this->cmInstallGenerator::GenerateScriptConfigs(os, indent);
88
89
90
    }
  else
    {
91
92
93
94
    // In a multi-configuration generator, a separate rule is produced
    // in a block for each configuration that is built.  However, the
    // list of configurations is restricted to those for which this
    // install rule applies.
95
96
97
98
    for(std::vector<std::string>::const_iterator i =
          this->ConfigurationTypes->begin();
        i != this->ConfigurationTypes->end(); ++i)
      {
99
100
101
102
103
104
105
106
107
      const char* config = i->c_str();
      if(this->InstallsForConfig(config))
        {
        // Generate a per-configuration block.
        std::string config_test = this->CreateConfigTest(config);
        os << indent << "IF(" << config_test << ")\n";
        this->GenerateScriptForConfig(os, config, indent.Next());
        os << indent << "ENDIF(" << config_test << ")\n";
        }
108
109
      }
    }
110
}
111

112
113
114
115
116
117
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScriptActions(std::ostream& os,
                                                     Indent const& indent)
{
  // This is reached for single-configuration generators only.
  this->GenerateScriptForConfig(os, this->ConfigurationName, indent);
118
119
}

120
121
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
122
123
                                                       const char* config,
                                                       Indent const& indent)
124
125
{
  // Compute the per-configuration directory containing the files.
126
  std::string fromDirConfig = this->FromDir;
127
128
  this->Target->GetMakefile()->GetLocalGenerator()->GetGlobalGenerator()
    ->AppendDirectoryForConfig("", config, "/", fromDirConfig);
129

130
  // Compute the full path to the main installed file for this target.
131
  NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
132
  std::string toInstallPath = this->GetInstallDestination();
133
  toInstallPath += "/";
134
  toInstallPath += this->GetInstallFilename(this->Target, config, nameType);
135

136
137
138
139
  // Track whether post-install operations should be added to the
  // script.
  bool tweakInstalledFile = true;

140
141
142
143
144
145
  // Compute the list of files to install for this target.
  std::vector<std::string> files;
  std::string literal_args;
  cmTarget::TargetType type = this->Target->GetType();
  if(type == cmTarget::EXECUTABLE)
    {
146
147
148
    // There is a bug in cmInstallCommand if this fails.
    assert(this->NamelinkMode == NamelinkModeNone);

149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
    std::string targetName;
    std::string targetNameReal;
    std::string targetNameImport;
    std::string targetNamePDB;
    this->Target->GetExecutableNames(targetName, targetNameReal,
                                     targetNameImport, targetNamePDB,
                                     config);
    if(this->ImportLibrary)
      {
      std::string from1 = fromDirConfig;
      from1 += targetNameImport;
      files.push_back(from1);

      // An import library looks like a static library.
      type = cmTarget::STATIC_LIBRARY;
      }
    else
166
      {
167
168
      std::string from1 = fromDirConfig;
      from1 += targetName;
169
170

      // Handle OSX Bundles.
171
      if(this->Target->IsAppBundleOnApple())
172
173
174
        {
        // Compute the source locations of the bundle executable and
        // Info.plist file.
175
176
        from1 += ".app";
        files.push_back(from1);
177
        type = cmTarget::INSTALL_DIRECTORY;
178
179
        // Need to apply install_name_tool and stripping to binary
        // inside bundle.
180
        toInstallPath += ".app/Contents/MacOS/";
181
182
        toInstallPath +=
          this->GetInstallFilename(this->Target, config, nameType);
183
        literal_args += " USE_SOURCE_PERMISSIONS";
184
185
186
        }
      else
        {
187
188
189
190
191
192
        // Operations done at install time on the installed file should
        // be done on the real file and not any of the symlinks.
        toInstallPath = this->GetInstallDestination();
        toInstallPath += "/";
        toInstallPath += targetNameReal;

193
194
195
196
197
198
199
        files.push_back(from1);
        if(targetNameReal != targetName)
          {
          std::string from2 = fromDirConfig;
          from2 += targetNameReal;
          files.push_back(from2);
          }
200
201
202
        }
      }
    }
203
  else
204
    {
205
206
207
208
209
210
211
212
213
214
    std::string targetName;
    std::string targetNameSO;
    std::string targetNameReal;
    std::string targetNameImport;
    std::string targetNamePDB;
    this->Target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
                                  targetNameImport, targetNamePDB,
                                  config);
    if(this->ImportLibrary)
      {
215
216
217
      // There is a bug in cmInstallCommand if this fails.
      assert(this->NamelinkMode == NamelinkModeNone);

218
219
220
221
222
223
224
      std::string from1 = fromDirConfig;
      from1 += targetNameImport;
      files.push_back(from1);

      // An import library looks like a static library.
      type = cmTarget::STATIC_LIBRARY;
      }
225
    else if(this->Target->IsFrameworkOnApple())
226
      {
227
228
229
      // There is a bug in cmInstallCommand if this fails.
      assert(this->NamelinkMode == NamelinkModeNone);

230
231
      // Compute the build tree location of the framework directory
      std::string from1 = fromDirConfig;
232
233
      from1 += targetName;
      from1 += ".framework";
234
235
236
237
238
239
      files.push_back(from1);

      type = cmTarget::INSTALL_DIRECTORY;

      // Need to apply install_name_tool and stripping to binary
      // inside framework.
240
241
242
      toInstallPath += ".framework/Versions/";
      toInstallPath += this->Target->GetFrameworkVersion();
      toInstallPath += "/";
243
      toInstallPath += this->GetInstallFilename(this->Target, config,
244
                                                NameNormal);
245
246
247

      literal_args += " USE_SOURCE_PERMISSIONS";
      }
248
249
    else
      {
250
251
252
253
254
255
256
257
258
259
260
261
262
      // Operations done at install time on the installed file should
      // be done on the real file and not any of the symlinks.
      toInstallPath = this->GetInstallDestination();
      toInstallPath += "/";
      toInstallPath += targetNameReal;

      // Construct the list of file names to install for this library.
      bool haveNamelink = false;
      std::string fromName;
      std::string fromSOName;
      std::string fromRealName;
      fromName = fromDirConfig;
      fromName += targetName;
263
264
      if(targetNameSO != targetName)
        {
265
266
267
        haveNamelink = true;
        fromSOName = fromDirConfig;
        fromSOName += targetNameSO;
268
269
270
271
        }
      if(targetNameReal != targetName &&
         targetNameReal != targetNameSO)
        {
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
        haveNamelink = true;
        fromRealName = fromDirConfig;
        fromRealName += targetNameReal;
        }

      // Add the names based on the current namelink mode.
      if(haveNamelink)
        {
        // With a namelink we need to check the mode.
        if(this->NamelinkMode == NamelinkModeOnly)
          {
          // Install the namelink only.
          files.push_back(fromName);
          tweakInstalledFile = false;
          }
        else
          {
          // Install the real file if it has its own name.
          if(!fromRealName.empty())
            {
            files.push_back(fromRealName);
            }

          // Install the soname link if it has its own name.
          if(!fromSOName.empty())
            {
            files.push_back(fromSOName);
            }

          // Install the namelink if it is not to be skipped.
          if(this->NamelinkMode != NamelinkModeSkip)
            {
            files.push_back(fromName);
            }
          }
        }
      else
        {
        // Without a namelink there will be only one file.  Install it
        // if this is not a namelink-only rule.
        if(this->NamelinkMode != NamelinkModeOnly)
          {
          files.push_back(fromName);
          }
316
317
        }
      }
318
319
    }

320
321
322
323
324
325
  // Skip this rule if no files are to be installed for the target.
  if(files.empty())
    {
    return;
    }

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  // Construct the path of the file on disk after installation on
  // which tweaks may be performed.
  std::string toDestDirPath = "$ENV{DESTDIR}";
  if(toInstallPath[0] != '/' && toInstallPath[0] != '$')
    {
    toDestDirPath += "/";
    }
  toDestDirPath += toInstallPath;

  // Add pre-installation tweaks.
  if(tweakInstalledFile)
    {
    // Collect tweaking rules.
    cmOStringStream tw;
    this->AddRPathCheckRule(tw, indent.Next(), config, toDestDirPath);
    std::string tws = tw.str();

    // Add the rules, if any.
    if(!tws.empty())
      {
      os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
      os << tws;
      os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
      }
    }

352
  // Write code to install the target file.
353
  const char* no_dir_permissions = 0;
354
  const char* no_rename = 0;
355
356
  const char* no_properties = 0;
  bool optional = this->Optional || this->ImportLibrary;
357
  this->AddInstallRule(os, type, files,
358
                       optional, no_properties,
359
                       this->FilePermissions.c_str(), no_dir_permissions,
360
361
                       no_rename, literal_args.c_str(),
                       indent);
362

363
  // Add post-installation tweaks.
364
365
  if(tweakInstalledFile)
    {
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
    // Collect tweaking rules.
    cmOStringStream tw;
    this->AddInstallNamePatchRule(tw, indent.Next(), config, toDestDirPath);
    this->AddChrpathPatchRule(tw, indent.Next(), config, toDestDirPath);
    this->AddRanlibRule(tw, indent.Next(), type, toDestDirPath);
    this->AddStripRule(tw, indent.Next(), type, toDestDirPath);
    std::string tws = tw.str();

    // Add the rules, if any.
    if(!tws.empty())
      {
      os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
      os << tws;
      os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
      }
381
    }
382
383
}

384
385
386
//----------------------------------------------------------------------------
std::string
cmInstallTargetGenerator::GetInstallFilename(const char* config) const
Alexander Neundorf's avatar
   
Alexander Neundorf committed
387
{
388
  NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
389
390
  return
    cmInstallTargetGenerator::GetInstallFilename(this->Target, config,
391
                                                 nameType);
Alexander Neundorf's avatar
   
Alexander Neundorf committed
392
393
}

Alexander Neundorf's avatar
   
Alexander Neundorf committed
394
395
396
//----------------------------------------------------------------------------
std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
                                                         const char* config,
397
                                                         NameType nameType)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
398
399
400
401
402
403
404
405
406
407
408
409
{
  std::string fname;
  // Compute the name of the library.
  if(target->GetType() == cmTarget::EXECUTABLE)
    {
    std::string targetName;
    std::string targetNameReal;
    std::string targetNameImport;
    std::string targetNamePDB;
    target->GetExecutableNames(targetName, targetNameReal,
                               targetNameImport, targetNamePDB,
                               config);
410
    if(nameType == NameImplib)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
411
412
413
414
      {
      // Use the import library name.
      fname = targetNameImport;
      }
415
416
417
418
419
    else if(nameType == NameReal)
      {
      // Use the canonical name.
      fname = targetNameReal;
      }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
    else
      {
      // Use the canonical name.
      fname = targetName;
      }
    }
  else
    {
    std::string targetName;
    std::string targetNameSO;
    std::string targetNameReal;
    std::string targetNameImport;
    std::string targetNamePDB;
    target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
                            targetNameImport, targetNamePDB, config);
435
    if(nameType == NameImplib)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
436
437
438
439
      {
      // Use the import library name.
      fname = targetNameImport;
      }
440
    else if(nameType == NameSO)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
441
442
443
444
      {
      // Use the soname.
      fname = targetNameSO;
      }
445
446
447
448
449
    else if(nameType == NameReal)
      {
      // Use the real name.
      fname = targetNameReal;
      }
Alexander Neundorf's avatar
   
Alexander Neundorf committed
450
451
452
453
454
455
456
457
458
459
    else
      {
      // Use the canonical name.
      fname = targetName;
      }
    }

  return fname;
}

460
461
462
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
463
::AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
464
                          const char* config, std::string const& toDestDirPath)
465
{
466
467
468
469
  if(this->ImportLibrary ||
     !(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
       this->Target->GetType() == cmTarget::MODULE_LIBRARY ||
       this->Target->GetType() == cmTarget::EXECUTABLE))
470
    {
471
    return;
472
    }
473

474
  // Fix the install_name settings in installed binaries.
475
  std::string installNameTool =
476
    this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
477

Alexander Neundorf's avatar
Alexander Neundorf committed
478
479
480
481
482
  if(!installNameTool.size())
    {
    return;
    }

483
484
485
  // Build a map of build-tree install_name to install-tree install_name for
  // shared libraries linked to this target.
  std::map<cmStdString, cmStdString> install_name_remap;
486
  if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config))
487
    {
488
489
490
    std::set<cmTarget*> const& sharedLibs = cli->GetSharedLibrariesLinked();
    for(std::set<cmTarget*>::const_iterator j = sharedLibs.begin();
        j != sharedLibs.end(); ++j)
491
      {
492
493
494
495
496
497
498
499
      cmTarget* tgt = *j;

      // The install_name of an imported target does not change.
      if(tgt->IsImported())
        {
        continue;
        }

500
501
502
503
504
      // If the build tree and install tree use different path
      // components of the install_name field then we need to create a
      // mapping to be applied after installation.
      std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
      std::string for_install = tgt->GetInstallNameDirForInstallTree(config);
505
506
507
508
509
      if(for_build != for_install)
        {
        // The directory portions differ.  Append the filename to
        // create the mapping.
        std::string fname =
510
          this->GetInstallFilename(tgt, config, NameSO);
511

512
513
        // Map from the build-tree install_name.
        for_build += fname;
514

515
        // Map to the install-tree install_name.
516
517
518
519
        for_install += fname;

        // Store the mapping entry.
        install_name_remap[for_build] = for_install;
520
521
522
523
524
525
526
527
        }
      }
    }

  // Edit the install_name of the target itself if necessary.
  std::string new_id;
  if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
    {
528
    std::string for_build =
Ken Martin's avatar
Ken Martin committed
529
      this->Target->GetInstallNameDirForBuildTree(config);
530
    std::string for_install =
Ken Martin's avatar
Ken Martin committed
531
      this->Target->GetInstallNameDirForInstallTree(config);
532
533

    if(this->Target->IsFrameworkOnApple() && for_install.empty())
534
      {
535
536
537
538
      // Frameworks seem to have an id corresponding to their own full
      // path.
      // ...
      // for_install = fullDestPath_without_DESTDIR_or_name;
539
      }
540
541
542

    // If the install name will change on installation set the new id
    // on the installed file.
543
544
545
546
    if(for_build != for_install)
      {
      // Prepare to refer to the install-tree install_name.
      new_id = for_install;
547
      new_id += this->GetInstallFilename(this->Target, config, NameSO);
548
549
550
551
552
553
554
      }
    }

  // Write a rule to run install_name_tool to set the install-tree
  // install_name value and references.
  if(!new_id.empty() || !install_name_remap.empty())
    {
555
    os << indent << "EXECUTE_PROCESS(COMMAND \"" << installNameTool;
Alexander Neundorf's avatar
   
Alexander Neundorf committed
556
    os << "\"";
557
558
    if(!new_id.empty())
      {
559
      os << "\n" << indent << "  -id \"" << new_id << "\"";
560
561
562
563
564
      }
    for(std::map<cmStdString, cmStdString>::const_iterator
          i = install_name_remap.begin();
        i != install_name_remap.end(); ++i)
      {
565
566
      os << "\n" << indent << "  -change \""
         << i->first << "\" \"" << i->second << "\"";
567
      }
568
    os << "\n" << indent << "  \"" << toDestDirPath << "\")\n";
569
570
    }
}
Alexander Neundorf's avatar
   
Alexander Neundorf committed
571

572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
::AddRPathCheckRule(std::ostream& os, Indent const& indent,
                    const char* config, std::string const& toDestDirPath)
{
  // Skip the chrpath if the target does not need it.
  if(this->ImportLibrary || !this->Target->IsChrpathUsed())
    {
    return;
    }

  // Get the link information for this target.
  // It can provide the RPATH.
  cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
  if(!cli)
    {
    return;
    }

  // Get the install RPATH from the link information.
  std::string newRpath = cli->GetChrpathString();

  // Write a rule to remove the installed file if its rpath is not the
  // new rpath.  This is needed for existing build/install trees when
  // the installed rpath changes but the file is not rebuilt.
  os << indent << "FILE(RPATH_CHECK\n"
     << indent << "     FILE \"" << toDestDirPath << "\"\n"
     << indent << "     RPATH \"" << newRpath << "\")\n";
}

603
604
605
606
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
::AddChrpathPatchRule(std::ostream& os, Indent const& indent,
607
                      const char* config, std::string const& toDestDirPath)
608
{
609
610
  // Skip the chrpath if the target does not need it.
  if(this->ImportLibrary || !this->Target->IsChrpathUsed())
611
612
613
614
    {
    return;
    }

615
616
617
618
  // Get the link information for this target.
  // It can provide the RPATH.
  cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
  if(!cli)
619
620
621
622
    {
    return;
    }

623
624
625
  // Construct the original rpath string to be replaced.
  std::string oldRpath = cli->GetRPathString(false);

626
627
  // Get the install RPATH from the link information.
  std::string newRpath = cli->GetChrpathString();
628

629
630
631
632
633
634
  // Skip the rule if the paths are identical
  if(oldRpath == newRpath)
    {
    return;
    }

635
  // Write a rule to run chrpath to set the install-tree RPATH
636
637
638
639
640
641
642
643
644
645
646
647
  if(newRpath.empty())
    {
    os << indent << "FILE(RPATH_REMOVE\n"
       << indent << "     FILE \"" << toDestDirPath << "\")\n";
    }
  else
    {
    os << indent << "FILE(RPATH_CHANGE\n"
       << indent << "     FILE \"" << toDestDirPath << "\"\n"
       << indent << "     OLD_RPATH \"" << oldRpath << "\"\n"
       << indent << "     NEW_RPATH \"" << newRpath << "\")\n";
    }
648
649
}

650
651
652
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator::AddStripRule(std::ostream& os,
653
                                       Indent const& indent,
654
                                       cmTarget::TargetType type,
655
                                       const std::string& toDestDirPath)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
656
657
{

Alexander Neundorf's avatar
   
Alexander Neundorf committed
658
659
660
661
662
663
664
  // don't strip static libraries, because it removes the only symbol table
  // they have so you can't link to them anymore
  if(type == cmTarget::STATIC_LIBRARY)
    {
    return;
    }

Alexander Neundorf's avatar
   
Alexander Neundorf committed
665
666
667
668
669
670
671
672
673
674
675
676
  // Don't handle OSX Bundles.
  if(this->Target->GetMakefile()->IsOn("APPLE") &&
     this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
    {
    return;
    }

  if(! this->Target->GetMakefile()->IsSet("CMAKE_STRIP"))
    {
    return;
    }

677
678
  os << indent << "IF(CMAKE_INSTALL_DO_STRIP)\n";
  os << indent << "  EXECUTE_PROCESS(COMMAND \""
Alexander Neundorf's avatar
   
Alexander Neundorf committed
679
     << this->Target->GetMakefile()->GetDefinition("CMAKE_STRIP")
680
     << "\" \"" << toDestDirPath << "\")\n";
681
  os << indent << "ENDIF(CMAKE_INSTALL_DO_STRIP)\n";
Alexander Neundorf's avatar
   
Alexander Neundorf committed
682
683
}

684
685
686
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
687
                                        Indent const& indent,
688
                                        cmTarget::TargetType type,
689
                                        const std::string& toDestDirPath)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
690
691
692
693
694
695
696
697
698
699
700
701
702
703
{
  // Static libraries need ranlib on this platform.
  if(type != cmTarget::STATIC_LIBRARY)
    {
    return;
    }

  // Perform post-installation processing on the file depending
  // on its type.
  if(!this->Target->GetMakefile()->IsOn("APPLE"))
    {
    return;
    }

704
705
706
  std::string ranlib =
    this->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
  if(ranlib.empty())
Alexander Neundorf's avatar
   
Alexander Neundorf committed
707
708
709
710
    {
    return;
    }

711
  os << indent << "EXECUTE_PROCESS(COMMAND \""
712
     << ranlib << "\" \"" << toDestDirPath << "\")\n";
Alexander Neundorf's avatar
   
Alexander Neundorf committed
713
}