1
/*=========================================================================
3
Program: CMake - Cross-Platform Makefile Generator
4
Module: $RCSfile: cmMakefileTargetGenerator.cxx,v $
6
Date: $Date: 2009-03-23 17:58:48 $
7
Version: $Revision: 1.93.2.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.
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
=========================================================================*/
1
/*============================================================================
2
CMake - Cross Platform Makefile Generator
3
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5
Distributed under the OSI-approved BSD License (the "License");
6
see accompanying file Copyright.txt for details.
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"
19
14
#include "cmGeneratedFileStream.h"
195
199
cmLocalGenerator::HOME_OUTPUT,
196
200
cmLocalGenerator::MAKEFILE)
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)
203
if(!this->NoRuleMessages)
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)
208
215
// make sure the depend file exists
209
216
if (!cmSystemTools::FileExists(dependFileNameFull.c_str()))
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);
578
580
// Construct the build message.
579
581
std::vector<std::string> no_commands;
580
582
std::vector<std::string> commands;
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
594
commands.push_back(progCmd.str());
596
std::string buildEcho = "Building ";
598
buildEcho += " object ";
599
buildEcho += relativeObj;
600
this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
601
cmLocalUnixMakefileGenerator3::EchoBuild);
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);
612
// Change the command working directory to the local build tree.
613
this->LocalGenerator->CreateCDCommand
615
this->Makefile->GetStartOutputDirectory(),
616
cmLocalGenerator::HOME_OUTPUT);
617
commands.insert(commands.end(),
618
compileCommands.begin(), compileCommands.end());
585
this->AppendProgress(commands);
587
if(!this->NoRuleMessages)
589
std::string buildEcho = "Building ";
591
buildEcho += " object ";
592
buildEcho += relativeObj;
593
this->LocalGenerator->AppendEcho
594
(commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild);
620
597
std::string targetOutPathPDB;
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)
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);
633
609
targetOutPathPDB =
634
this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::FULL,
610
this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
635
611
cmLocalGenerator::SHELL);
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();
632
// Construct the compile rules.
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);
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)
658
646
this->LocalGenerator->ExpandRuleVariables(*i, vars);
649
// Change the command working directory to the local build tree.
650
this->LocalGenerator->CreateCDCommand
652
this->Makefile->GetStartOutputDirectory(),
653
cmLocalGenerator::HOME_OUTPUT);
654
commands.insert(commands.end(),
655
compileCommands.begin(), compileCommands.end());
662
658
// Write the rule.
663
659
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
722
718
std::vector<std::string> preprocessCommands;
723
719
cmSystemTools::ExpandListArgument(preprocessRule, preprocessCommands);
721
std::string shellObjI =
722
this->Convert(objI.c_str(),
723
cmLocalGenerator::NONE,
724
cmLocalGenerator::SHELL).c_str();
725
vars.PreprocessedSource = shellObjI.c_str();
727
// Expand placeholders in the commands.
728
for(std::vector<std::string>::iterator i = preprocessCommands.begin();
729
i != preprocessCommands.end(); ++i)
731
this->LocalGenerator->ExpandRuleVariables(*i, vars);
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());
732
std::string shellObjI =
733
this->Convert(objI.c_str(),
734
cmLocalGenerator::NONE,
735
cmLocalGenerator::SHELL).c_str();
736
vars.PreprocessedSource = shellObjI.c_str();
738
// Expand placeholders in the commands.
739
for(std::vector<std::string>::iterator i = commands.begin();
740
i != commands.end(); ++i)
742
this->LocalGenerator->ExpandRuleVariables(*i, vars);
778
775
std::vector<std::string> assemblyCommands;
779
776
cmSystemTools::ExpandListArgument(assemblyRule, assemblyCommands);
778
std::string shellObjS =
779
this->Convert(objS.c_str(),
780
cmLocalGenerator::NONE,
781
cmLocalGenerator::SHELL).c_str();
782
vars.AssemblySource = shellObjS.c_str();
784
// Expand placeholders in the commands.
785
for(std::vector<std::string>::iterator i = assemblyCommands.begin();
786
i != assemblyCommands.end(); ++i)
788
this->LocalGenerator->ExpandRuleVariables(*i, vars);
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());
788
std::string shellObjS =
789
this->Convert(objS.c_str(),
790
cmLocalGenerator::NONE,
791
cmLocalGenerator::SHELL).c_str();
792
vars.AssemblySource = shellObjS.c_str();
794
// Expand placeholders in the commands.
795
for(std::vector<std::string>::iterator i = commands.begin();
796
i != commands.end(); ++i)
798
this->LocalGenerator->ExpandRuleVariables(*i, vars);
1102
1100
if(!comment.empty())
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
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)
1106
this->LocalGenerator
1107
->AppendEcho(commands, comment.c_str(),
1108
cmLocalUnixMakefileGenerator3::EchoGenerate);
1121
// Below we need to skip over the echo and progress commands.
1122
unsigned int skip = static_cast<unsigned int>(commands.size());
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,
1127
1118
// Collect the dependencies.
1128
1119
std::vector<std::string> depends;
1216
1205
//----------------------------------------------------------------------------
1207
cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands)
1209
this->NumberOfProgressActions++;
1210
if(this->NoRuleMessages)
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());
1225
//----------------------------------------------------------------------------
1218
1227
cmMakefileTargetGenerator
1219
1228
::WriteObjectsVariable(std::string& variableName,
1220
1229
std::string& variableNameExternal)
1521
void cmMakefileTargetGenerator::WriteProgressVariables(unsigned long total,
1522
unsigned long ¤t)
1524
cmGeneratedFileStream *progressFileStream =
1525
new cmGeneratedFileStream(this->ProgressFileNameFull.c_str());
1526
if(!progressFileStream)
1533
for (i = 1; i <= this->NumberOfProgressActions; ++i)
1536
<< "CMAKE_PROGRESS_" << i << " = ";
1540
*progressFileStream << num;
1541
this->LocalGenerator->ProgressFiles[this->Target->GetName()]
1544
else if (((i+current)*100)/total > ((i-1+current)*100)/total)
1546
num = ((i+current)*100)/total;
1547
*progressFileStream << num;
1548
this->LocalGenerator->ProgressFiles[this->Target->GetName()]
1551
*progressFileStream << "\n";
1553
*progressFileStream << "\n";
1554
current += this->NumberOfProgressActions;
1555
delete progressFileStream;
1558
1530
//----------------------------------------------------------------------------
1560
1532
cmMakefileTargetGenerator
1737
//----------------------------------------------------------------------------
1738
void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
1740
if(this->ModuleDefinitionFile.empty())
1745
// TODO: Create a per-language flag variable.
1746
const char* defFileFlag =
1747
this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
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());
1761
//----------------------------------------------------------------------------
1762
const char* cmMakefileTargetGenerator::GetFeature(const char* feature)
1764
return this->Target->GetFeature(feature, this->ConfigName);
1767
//----------------------------------------------------------------------------
1768
bool cmMakefileTargetGenerator::GetFeatureAsBool(const char* feature)
1770
return cmSystemTools::IsOn(this->GetFeature(feature));
1773
//----------------------------------------------------------------------------
1774
void cmMakefileTargetGenerator::AddFeatureFlags(
1775
std::string& flags, const char* lang
1778
// Add language-specific flags.
1779
this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
1781
if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
1783
this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");