~ubuntu-branches/ubuntu/lucid/cmake/lucid

« back to all changes in this revision

Viewing changes to Source/cmMakefileTargetGenerator.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Artur Rona
  • Date: 2009-12-16 11:11:54 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20091216111154-6accvv6yq86h2hkc
Tags: 2.8.0-5ubuntu1
* Merge from debian testing (LP: #497349). Remaining changes:
  - Keep the Replaces: on cmake-data to cover the Kubuntu version from
    Jaunty in case someone decides to do an (unsupported) Jaunty->Lucid
    upgrade.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*=========================================================================
2
 
 
3
 
  Program:   CMake - Cross-Platform Makefile Generator
4
 
  Module:    $RCSfile: cmMakefileTargetGenerator.cxx,v $
5
 
  Language:  C++
6
 
  Date:      $Date: 2009-03-23 17:58:48 $
7
 
  Version:   $Revision: 1.93.2.8 $
8
 
 
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.
11
 
 
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.
15
 
 
16
 
=========================================================================*/
 
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
============================================================================*/
17
12
#include "cmMakefileTargetGenerator.h"
18
13
 
19
14
#include "cmGeneratedFileStream.h"
43
38
  this->LocalGenerator =
44
39
    static_cast<cmLocalUnixMakefileGenerator3*>(
45
40
      this->Makefile->GetLocalGenerator());
 
41
  this->ConfigName = this->LocalGenerator->ConfigurationName.c_str();
46
42
  this->GlobalGenerator =
47
43
    static_cast<cmGlobalUnixMakefileGenerator3*>(
48
44
      this->LocalGenerator->GetGlobalGenerator());
 
45
  cmake* cm = this->GlobalGenerator->GetCMakeInstance();
 
46
  this->NoRuleMessages = false;
 
47
  if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES"))
 
48
    {
 
49
    this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
 
50
    }
49
51
}
50
52
 
51
53
cmMakefileTargetGenerator *
90
92
  this->BuildFileNameFull += "/build.make";
91
93
 
92
94
  // Construct the rule file name.
93
 
  this->ProgressFileName = this->TargetBuildDirectory;
94
 
  this->ProgressFileName += "/progress.make";
95
95
  this->ProgressFileNameFull = this->TargetBuildDirectoryFull;
96
96
  this->ProgressFileNameFull += "/progress.make";
97
97
 
170
170
        // This is an external object file.  Just add it.
171
171
        this->ExternalObjects.push_back((*source)->GetFullPath());
172
172
        }
 
173
      else if(cmSystemTools::UpperCase((*source)->GetExtension()) == "DEF")
 
174
        {
 
175
        this->ModuleDefinitionFile = (*source)->GetFullPath();
 
176
        }
173
177
      else
174
178
        {
175
179
        // We only get here if a source file is not an external object
195
199
                     cmLocalGenerator::HOME_OUTPUT,
196
200
                     cmLocalGenerator::MAKEFILE)
197
201
    << "\n\n";
198
 
  
199
 
  // Include the progress variables for the target.
200
 
  *this->BuildFileStream
201
 
    << "# Include the progress variables for this target.\n"
202
 
    << this->LocalGenerator->IncludeDirective << " "
203
 
    << this->Convert(this->ProgressFileNameFull.c_str(),
204
 
                     cmLocalGenerator::HOME_OUTPUT,
205
 
                     cmLocalGenerator::MAKEFILE)
206
 
    << "\n\n";
 
202
 
 
203
  if(!this->NoRuleMessages)
 
204
    {
 
205
    // Include the progress variables for the target.
 
206
    *this->BuildFileStream
 
207
      << "# Include the progress variables for this target.\n"
 
208
      << this->LocalGenerator->IncludeDirective << " "
 
209
      << this->Convert(this->ProgressFileNameFull.c_str(),
 
210
                       cmLocalGenerator::HOME_OUTPUT,
 
211
                       cmLocalGenerator::MAKEFILE)
 
212
      << "\n\n";
 
213
    }
207
214
 
208
215
  // make sure the depend file exists
209
216
  if (!cmSystemTools::FileExists(dependFileNameFull.c_str()))
284
291
    this->LocalGenerator->AppendDefines
285
292
      (defines, this->Target->GetProperty(defPropName.c_str()), lang);
286
293
 
287
 
    // Add language-specific flags.
288
 
    this->LocalGenerator
289
 
      ->AddLanguageFlags(flags, lang,
290
 
                         this->LocalGenerator->ConfigurationName.c_str());
 
294
    // Add language feature flags.
 
295
    this->AddFeatureFlags(flags, lang);
291
296
 
292
297
    // Fortran-specific flags computed for this target.
293
298
    if(*l == "Fortran")
571
576
  sourceFile = this->Convert(sourceFile.c_str(),
572
577
                             cmLocalGenerator::NONE,
573
578
                             cmLocalGenerator::SHELL);
574
 
  std::string objectFile = this->Convert(obj.c_str(),
575
 
                                         cmLocalGenerator::START_OUTPUT,
576
 
                                         cmLocalGenerator::SHELL);
577
579
 
578
580
  // Construct the build message.
579
581
  std::vector<std::string> no_commands;
580
582
  std::vector<std::string> commands;
581
583
 
582
584
  // add in a progress call if needed
583
 
  std::string progressDir = this->Makefile->GetHomeOutputDirectory();
584
 
  progressDir += cmake::GetCMakeFilesDirectory();
585
 
  cmOStringStream progCmd;
586
 
  progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
587
 
  progCmd << this->LocalGenerator->Convert(progressDir.c_str(),
588
 
                                           cmLocalGenerator::FULL,
589
 
                                           cmLocalGenerator::SHELL);
590
 
  this->NumberOfProgressActions++;
591
 
  progCmd << " $(CMAKE_PROGRESS_" 
592
 
          << this->NumberOfProgressActions 
593
 
          << ")";
594
 
  commands.push_back(progCmd.str());
595
 
 
596
 
  std::string buildEcho = "Building ";
597
 
  buildEcho += lang;
598
 
  buildEcho += " object ";
599
 
  buildEcho += relativeObj;
600
 
  this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
601
 
                                   cmLocalUnixMakefileGenerator3::EchoBuild);
602
 
 
603
 
  // Construct the compile rules.
604
 
  std::string compileRuleVar = "CMAKE_";
605
 
  compileRuleVar += lang;
606
 
  compileRuleVar += "_COMPILE_OBJECT";
607
 
  std::string compileRule =
608
 
    this->Makefile->GetRequiredDefinition(compileRuleVar.c_str());
609
 
  std::vector<std::string> compileCommands;
610
 
  cmSystemTools::ExpandListArgument(compileRule, compileCommands);
611
 
 
612
 
  // Change the command working directory to the local build tree.
613
 
  this->LocalGenerator->CreateCDCommand
614
 
    (compileCommands,
615
 
     this->Makefile->GetStartOutputDirectory(),
616
 
     cmLocalGenerator::HOME_OUTPUT);
617
 
  commands.insert(commands.end(),
618
 
                  compileCommands.begin(), compileCommands.end());
 
585
  this->AppendProgress(commands);
 
586
 
 
587
  if(!this->NoRuleMessages)
 
588
    {
 
589
    std::string buildEcho = "Building ";
 
590
    buildEcho += lang;
 
591
    buildEcho += " object ";
 
592
    buildEcho += relativeObj;
 
593
    this->LocalGenerator->AppendEcho
 
594
      (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild);
 
595
    }
619
596
 
620
597
  std::string targetOutPathPDB;
621
598
  {
622
599
  std::string targetFullPathPDB;
623
 
  const char* configName = this->LocalGenerator->ConfigurationName.c_str();
624
600
  if(this->Target->GetType() == cmTarget::EXECUTABLE ||
625
601
     this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
626
602
     this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
627
603
     this->Target->GetType() == cmTarget::MODULE_LIBRARY)
628
604
    {
629
 
    targetFullPathPDB = this->Target->GetDirectory();
 
605
    targetFullPathPDB = this->Target->GetDirectory(this->ConfigName);
630
606
    targetFullPathPDB += "/";
631
 
    targetFullPathPDB += this->Target->GetPDBName(configName);
 
607
    targetFullPathPDB += this->Target->GetPDBName(this->ConfigName);
632
608
    }
633
609
  targetOutPathPDB =
634
 
    this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::FULL,
 
610
    this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
635
611
                  cmLocalGenerator::SHELL);
636
612
  }
637
613
  cmLocalGenerator::RuleVariables vars;
 
614
  vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
 
615
  vars.CMTarget = this->Target;
638
616
  vars.Language = lang;
639
617
  vars.TargetPDB = targetOutPathPDB.c_str();
640
618
  vars.Source = sourceFile.c_str();
651
629
  vars.Flags = flags.c_str();
652
630
  vars.Defines = defines.c_str();
653
631
 
 
632
  // Construct the compile rules.
 
633
  {
 
634
  std::string compileRuleVar = "CMAKE_";
 
635
  compileRuleVar += lang;
 
636
  compileRuleVar += "_COMPILE_OBJECT";
 
637
  std::string compileRule =
 
638
    this->Makefile->GetRequiredDefinition(compileRuleVar.c_str());
 
639
  std::vector<std::string> compileCommands;
 
640
  cmSystemTools::ExpandListArgument(compileRule, compileCommands);
 
641
 
654
642
  // Expand placeholders in the commands.
655
 
  for(std::vector<std::string>::iterator i = commands.begin();
656
 
      i != commands.end(); ++i)
 
643
  for(std::vector<std::string>::iterator i = compileCommands.begin();
 
644
      i != compileCommands.end(); ++i)
657
645
    {
658
646
    this->LocalGenerator->ExpandRuleVariables(*i, vars);
659
647
    }
660
648
 
 
649
  // Change the command working directory to the local build tree.
 
650
  this->LocalGenerator->CreateCDCommand
 
651
    (compileCommands,
 
652
     this->Makefile->GetStartOutputDirectory(),
 
653
     cmLocalGenerator::HOME_OUTPUT);
 
654
  commands.insert(commands.end(),
 
655
                  compileCommands.begin(), compileCommands.end());
 
656
  }
661
657
 
662
658
  // Write the rule.
663
659
  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
721
717
        {
722
718
        std::vector<std::string> preprocessCommands;
723
719
        cmSystemTools::ExpandListArgument(preprocessRule, preprocessCommands);
 
720
 
 
721
        std::string shellObjI =
 
722
          this->Convert(objI.c_str(),
 
723
                        cmLocalGenerator::NONE,
 
724
                        cmLocalGenerator::SHELL).c_str();
 
725
        vars.PreprocessedSource = shellObjI.c_str();
 
726
 
 
727
        // Expand placeholders in the commands.
 
728
        for(std::vector<std::string>::iterator i = preprocessCommands.begin();
 
729
            i != preprocessCommands.end(); ++i)
 
730
          {
 
731
          this->LocalGenerator->ExpandRuleVariables(*i, vars);
 
732
          }
 
733
 
724
734
        this->LocalGenerator->CreateCDCommand
725
735
          (preprocessCommands,
726
736
           this->Makefile->GetStartOutputDirectory(),
728
738
        commands.insert(commands.end(),
729
739
                        preprocessCommands.begin(),
730
740
                        preprocessCommands.end());
731
 
 
732
 
        std::string shellObjI =
733
 
          this->Convert(objI.c_str(),
734
 
                        cmLocalGenerator::NONE,
735
 
                        cmLocalGenerator::SHELL).c_str();
736
 
        vars.PreprocessedSource = shellObjI.c_str();
737
 
 
738
 
        // Expand placeholders in the commands.
739
 
        for(std::vector<std::string>::iterator i = commands.begin();
740
 
            i != commands.end(); ++i)
741
 
          {
742
 
          this->LocalGenerator->ExpandRuleVariables(*i, vars);
743
 
          }
744
741
        }
745
742
      else
746
743
        {
777
774
        {
778
775
        std::vector<std::string> assemblyCommands;
779
776
        cmSystemTools::ExpandListArgument(assemblyRule, assemblyCommands);
 
777
 
 
778
        std::string shellObjS =
 
779
          this->Convert(objS.c_str(),
 
780
                        cmLocalGenerator::NONE,
 
781
                        cmLocalGenerator::SHELL).c_str();
 
782
        vars.AssemblySource = shellObjS.c_str();
 
783
 
 
784
        // Expand placeholders in the commands.
 
785
        for(std::vector<std::string>::iterator i = assemblyCommands.begin();
 
786
            i != assemblyCommands.end(); ++i)
 
787
          {
 
788
          this->LocalGenerator->ExpandRuleVariables(*i, vars);
 
789
          }
 
790
 
780
791
        this->LocalGenerator->CreateCDCommand
781
792
          (assemblyCommands,
782
793
           this->Makefile->GetStartOutputDirectory(),
784
795
        commands.insert(commands.end(),
785
796
                        assemblyCommands.begin(),
786
797
                        assemblyCommands.end());
787
 
 
788
 
        std::string shellObjS =
789
 
          this->Convert(objS.c_str(),
790
 
                        cmLocalGenerator::NONE,
791
 
                        cmLocalGenerator::SHELL).c_str();
792
 
        vars.AssemblySource = shellObjS.c_str();
793
 
 
794
 
        // Expand placeholders in the commands.
795
 
        for(std::vector<std::string>::iterator i = commands.begin();
796
 
            i != commands.end(); ++i)
797
 
          {
798
 
          this->LocalGenerator->ExpandRuleVariables(*i, vars);
799
 
          }
800
798
        }
801
799
      else
802
800
        {
1102
1100
  if(!comment.empty())
1103
1101
    {
1104
1102
    // add in a progress call if needed
1105
 
    std::string progressDir = this->Makefile->GetHomeOutputDirectory();
1106
 
    progressDir += cmake::GetCMakeFilesDirectory();
1107
 
    cmOStringStream progCmd;
1108
 
    progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
1109
 
    progCmd << this->LocalGenerator->Convert(progressDir.c_str(),
1110
 
                                             cmLocalGenerator::FULL,
1111
 
                                             cmLocalGenerator::SHELL);
1112
 
    this->NumberOfProgressActions++;
1113
 
    progCmd << " $(CMAKE_PROGRESS_" 
1114
 
            << this->NumberOfProgressActions 
1115
 
            << ")";
1116
 
    commands.push_back(progCmd.str());
1117
 
    this->LocalGenerator
1118
 
      ->AppendEcho(commands, comment.c_str(),
1119
 
                   cmLocalUnixMakefileGenerator3::EchoGenerate);
 
1103
    this->AppendProgress(commands);
 
1104
    if(!this->NoRuleMessages)
 
1105
      {
 
1106
      this->LocalGenerator
 
1107
        ->AppendEcho(commands, comment.c_str(),
 
1108
                     cmLocalUnixMakefileGenerator3::EchoGenerate);
 
1109
      }
1120
1110
    }
1121
 
  // Below we need to skip over the echo and progress commands.
1122
 
  unsigned int skip = static_cast<unsigned int>(commands.size());
1123
1111
 
1124
1112
  // Now append the actual user-specified commands.
1125
 
  this->LocalGenerator->AppendCustomCommand(commands, cc);
 
1113
  cmOStringStream content;
 
1114
  this->LocalGenerator->AppendCustomCommand(commands, cc, this->Target, false,
 
1115
                                            cmLocalGenerator::HOME_OUTPUT,
 
1116
                                            &content);
1126
1117
 
1127
1118
  // Collect the dependencies.
1128
1119
  std::vector<std::string> depends;
1150
1141
  // If the rule has changed make sure the output is rebuilt.
1151
1142
  if(!symbolic)
1152
1143
    {
1153
 
    this->GlobalGenerator->AddRuleHash(cc.GetOutputs(),
1154
 
                                       commands.begin()+skip,
1155
 
                                       commands.end());
 
1144
    this->GlobalGenerator->AddRuleHash(cc.GetOutputs(), content.str());
1156
1145
    }
1157
1146
  }
1158
1147
 
1215
1204
 
1216
1205
//----------------------------------------------------------------------------
1217
1206
void
 
1207
cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands)
 
1208
{
 
1209
  this->NumberOfProgressActions++;
 
1210
  if(this->NoRuleMessages)
 
1211
    {
 
1212
    return;
 
1213
    }
 
1214
  std::string progressDir = this->Makefile->GetHomeOutputDirectory();
 
1215
  progressDir += cmake::GetCMakeFilesDirectory();
 
1216
  cmOStringStream progCmd;
 
1217
  progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
 
1218
  progCmd << this->LocalGenerator->Convert(progressDir.c_str(),
 
1219
                                           cmLocalGenerator::FULL,
 
1220
                                           cmLocalGenerator::SHELL);
 
1221
  progCmd << " $(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")";
 
1222
  commands.push_back(progCmd.str());
 
1223
}
 
1224
 
 
1225
//----------------------------------------------------------------------------
 
1226
void
1218
1227
cmMakefileTargetGenerator
1219
1228
::WriteObjectsVariable(std::string& variableName,
1220
1229
                       std::string& variableNameExternal)
1518
1527
    }
1519
1528
}
1520
1529
 
1521
 
void cmMakefileTargetGenerator::WriteProgressVariables(unsigned long total,
1522
 
                                                       unsigned long &current)
1523
 
{
1524
 
  cmGeneratedFileStream *progressFileStream = 
1525
 
    new cmGeneratedFileStream(this->ProgressFileNameFull.c_str());
1526
 
  if(!progressFileStream)
1527
 
    {
1528
 
    return;
1529
 
    }
1530
 
 
1531
 
  unsigned long num;
1532
 
  unsigned long i;
1533
 
  for (i = 1; i <= this->NumberOfProgressActions; ++i)
1534
 
    {
1535
 
    *progressFileStream
1536
 
      << "CMAKE_PROGRESS_" << i << " = ";
1537
 
    if (total <= 100)
1538
 
      {
1539
 
      num = i + current;
1540
 
      *progressFileStream << num;
1541
 
      this->LocalGenerator->ProgressFiles[this->Target->GetName()]
1542
 
        .push_back(num);
1543
 
      }
1544
 
    else if (((i+current)*100)/total > ((i-1+current)*100)/total)
1545
 
      {
1546
 
      num = ((i+current)*100)/total;
1547
 
      *progressFileStream << num;
1548
 
      this->LocalGenerator->ProgressFiles[this->Target->GetName()]
1549
 
        .push_back(num);
1550
 
      }
1551
 
    *progressFileStream << "\n";
1552
 
    }
1553
 
  *progressFileStream << "\n";
1554
 
  current += this->NumberOfProgressActions;
1555
 
  delete progressFileStream;
1556
 
}
1557
 
 
1558
1530
//----------------------------------------------------------------------------
1559
1531
void
1560
1532
cmMakefileTargetGenerator
1761
1733
      }
1762
1734
    }
1763
1735
}
 
1736
 
 
1737
//----------------------------------------------------------------------------
 
1738
void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
 
1739
{
 
1740
  if(this->ModuleDefinitionFile.empty())
 
1741
    {
 
1742
    return;
 
1743
    }
 
1744
 
 
1745
  // TODO: Create a per-language flag variable.
 
1746
  const char* defFileFlag =
 
1747
    this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
 
1748
  if(!defFileFlag)
 
1749
    {
 
1750
    return;
 
1751
    }
 
1752
 
 
1753
  // Append the flag and value.  Use ConvertToLinkReference to help
 
1754
  // vs6's "cl -link" pass it to the linker.
 
1755
  std::string flag = defFileFlag;
 
1756
  flag += (this->LocalGenerator->ConvertToLinkReference(
 
1757
             this->ModuleDefinitionFile.c_str()));
 
1758
  this->LocalGenerator->AppendFlags(flags, flag.c_str());
 
1759
}
 
1760
 
 
1761
//----------------------------------------------------------------------------
 
1762
const char* cmMakefileTargetGenerator::GetFeature(const char* feature)
 
1763
{
 
1764
  return this->Target->GetFeature(feature, this->ConfigName);
 
1765
}
 
1766
 
 
1767
//----------------------------------------------------------------------------
 
1768
bool cmMakefileTargetGenerator::GetFeatureAsBool(const char* feature)
 
1769
{
 
1770
  return cmSystemTools::IsOn(this->GetFeature(feature));
 
1771
}
 
1772
 
 
1773
//----------------------------------------------------------------------------
 
1774
void cmMakefileTargetGenerator::AddFeatureFlags(
 
1775
  std::string& flags, const char* lang
 
1776
  )
 
1777
{
 
1778
  // Add language-specific flags.
 
1779
  this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
 
1780
 
 
1781
  if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
 
1782
    {
 
1783
    this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
 
1784
    }
 
1785
}