Imported Upstream version 2.8.11.2
[platform/upstream/cmake.git] / Source / cmMakefileTargetGenerator.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 "cmMakefileTargetGenerator.h"
13
14 #include "cmGeneratorTarget.h"
15 #include "cmGeneratedFileStream.h"
16 #include "cmGlobalGenerator.h"
17 #include "cmGlobalUnixMakefileGenerator3.h"
18 #include "cmLocalUnixMakefileGenerator3.h"
19 #include "cmMakefile.h"
20 #include "cmSourceFile.h"
21 #include "cmTarget.h"
22 #include "cmake.h"
23 #include "cmComputeLinkInformation.h"
24
25 #include "cmMakefileExecutableTargetGenerator.h"
26 #include "cmMakefileLibraryTargetGenerator.h"
27 #include "cmMakefileUtilityTargetGenerator.h"
28
29
30 cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
31   : OSXBundleGenerator(0)
32   , MacOSXContentGenerator(0)
33 {
34   this->BuildFileStream = 0;
35   this->InfoFileStream = 0;
36   this->FlagFileStream = 0;
37   this->CustomCommandDriver = OnBuild;
38   this->FortranModuleDirectoryComputed = false;
39   this->Target = target;
40   this->Makefile = this->Target->GetMakefile();
41   this->LocalGenerator =
42     static_cast<cmLocalUnixMakefileGenerator3*>(
43       this->Makefile->GetLocalGenerator());
44   this->ConfigName = this->LocalGenerator->ConfigurationName.c_str();
45   this->GlobalGenerator =
46     static_cast<cmGlobalUnixMakefileGenerator3*>(
47       this->LocalGenerator->GetGlobalGenerator());
48   this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target);
49   cmake* cm = this->GlobalGenerator->GetCMakeInstance();
50   this->NoRuleMessages = false;
51   if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES"))
52     {
53     this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
54     }
55   MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
56 }
57
58 cmMakefileTargetGenerator::~cmMakefileTargetGenerator()
59 {
60   delete MacOSXContentGenerator;
61 }
62
63 cmMakefileTargetGenerator *
64 cmMakefileTargetGenerator::New(cmTarget *tgt)
65 {
66   cmMakefileTargetGenerator *result = 0;
67
68   switch (tgt->GetType())
69     {
70     case cmTarget::EXECUTABLE:
71       result = new cmMakefileExecutableTargetGenerator(tgt);
72       break;
73     case cmTarget::STATIC_LIBRARY:
74     case cmTarget::SHARED_LIBRARY:
75     case cmTarget::MODULE_LIBRARY:
76     case cmTarget::OBJECT_LIBRARY:
77       result = new cmMakefileLibraryTargetGenerator(tgt);
78       break;
79     case cmTarget::UTILITY:
80       result = new cmMakefileUtilityTargetGenerator(tgt);
81       break;
82     default:
83       return result;
84       // break; /* unreachable */
85     }
86   return result;
87 }
88
89 //----------------------------------------------------------------------------
90 void cmMakefileTargetGenerator::CreateRuleFile()
91 {
92   // Create a directory for this target.
93   this->TargetBuildDirectory =
94     this->LocalGenerator->GetTargetDirectory(*this->Target);
95   this->TargetBuildDirectoryFull =
96     this->LocalGenerator->ConvertToFullPath(this->TargetBuildDirectory);
97   cmSystemTools::MakeDirectory(this->TargetBuildDirectoryFull.c_str());
98
99   // Construct the rule file name.
100   this->BuildFileName = this->TargetBuildDirectory;
101   this->BuildFileName += "/build.make";
102   this->BuildFileNameFull = this->TargetBuildDirectoryFull;
103   this->BuildFileNameFull += "/build.make";
104
105   // Construct the rule file name.
106   this->ProgressFileNameFull = this->TargetBuildDirectoryFull;
107   this->ProgressFileNameFull += "/progress.make";
108
109   // reset the progress count
110   this->NumberOfProgressActions = 0;
111
112   // Open the rule file.  This should be copy-if-different because the
113   // rules may depend on this file itself.
114   this->BuildFileStream =
115     new cmGeneratedFileStream(this->BuildFileNameFull.c_str());
116   this->BuildFileStream->SetCopyIfDifferent(true);
117   if(!this->BuildFileStream)
118     {
119     return;
120     }
121   this->LocalGenerator->WriteDisclaimer(*this->BuildFileStream);
122   this->LocalGenerator->WriteSpecialTargetsTop(*this->BuildFileStream);
123 }
124
125 //----------------------------------------------------------------------------
126 void cmMakefileTargetGenerator::WriteTargetBuildRules()
127 {
128   // write the custom commands for this target
129   // Look for files registered for cleaning in this directory.
130   if(const char* additional_clean_files =
131      this->Makefile->GetProperty
132      ("ADDITIONAL_MAKE_CLEAN_FILES"))
133     {
134     cmSystemTools::ExpandListArgument(additional_clean_files,
135                                       this->CleanFiles);
136     }
137
138   // add custom commands to the clean rules?
139   const char* clean_no_custom =
140     this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
141   bool clean = cmSystemTools::IsOff(clean_no_custom);
142
143   // First generate the object rule files.  Save a list of all object
144   // files for this target.
145   for(std::vector<cmSourceFile*>::const_iterator
146         si = this->GeneratorTarget->CustomCommands.begin();
147       si != this->GeneratorTarget->CustomCommands.end(); ++si)
148     {
149     cmCustomCommand const* cc = (*si)->GetCustomCommand();
150     this->GenerateCustomRuleFile(*cc);
151     if (clean)
152       {
153       const std::vector<std::string>& outputs = cc->GetOutputs();
154       for(std::vector<std::string>::const_iterator o = outputs.begin();
155           o != outputs.end(); ++o)
156         {
157         this->CleanFiles.push_back
158           (this->Convert(o->c_str(),
159                          cmLocalGenerator::START_OUTPUT,
160                          cmLocalGenerator::UNCHANGED));
161         }
162       }
163     }
164   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
165     this->GeneratorTarget->HeaderSources,
166     this->MacOSXContentGenerator);
167   this->OSXBundleGenerator->GenerateMacOSXContentStatements(
168     this->GeneratorTarget->ExtraSources,
169     this->MacOSXContentGenerator);
170   for(std::vector<cmSourceFile*>::const_iterator
171         si = this->GeneratorTarget->ExternalObjects.begin();
172       si != this->GeneratorTarget->ExternalObjects.end(); ++si)
173     {
174     this->ExternalObjects.push_back((*si)->GetFullPath());
175     }
176   for(std::vector<cmSourceFile*>::const_iterator
177         si = this->GeneratorTarget->ObjectSources.begin();
178       si != this->GeneratorTarget->ObjectSources.end(); ++si)
179     {
180     // Generate this object file's rule file.
181     this->WriteObjectRuleFiles(**si);
182     }
183
184   // Add object library contents as external objects.
185   this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
186 }
187
188 //----------------------------------------------------------------------------
189 void cmMakefileTargetGenerator::WriteCommonCodeRules()
190 {
191   const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")?
192                       "$(CMAKE_BINARY_DIR)/" : "");
193
194   // Include the dependencies for the target.
195   std::string dependFileNameFull = this->TargetBuildDirectoryFull;
196   dependFileNameFull += "/depend.make";
197   *this->BuildFileStream
198     << "# Include any dependencies generated for this target.\n"
199     << this->LocalGenerator->IncludeDirective << " " << root
200     << this->Convert(dependFileNameFull.c_str(),
201                      cmLocalGenerator::HOME_OUTPUT,
202                      cmLocalGenerator::MAKEFILE)
203     << "\n\n";
204
205   if(!this->NoRuleMessages)
206     {
207     // Include the progress variables for the target.
208     *this->BuildFileStream
209       << "# Include the progress variables for this target.\n"
210       << this->LocalGenerator->IncludeDirective << " " << root
211       << this->Convert(this->ProgressFileNameFull.c_str(),
212                        cmLocalGenerator::HOME_OUTPUT,
213                        cmLocalGenerator::MAKEFILE)
214       << "\n\n";
215     }
216
217   // make sure the depend file exists
218   if (!cmSystemTools::FileExists(dependFileNameFull.c_str()))
219     {
220     // Write an empty dependency file.
221     cmGeneratedFileStream depFileStream(dependFileNameFull.c_str());
222     depFileStream
223       << "# Empty dependencies file for " << this->Target->GetName() << ".\n"
224       << "# This may be replaced when dependencies are built." << std::endl;
225     }
226
227   // Open the flags file.  This should be copy-if-different because the
228   // rules may depend on this file itself.
229   this->FlagFileNameFull = this->TargetBuildDirectoryFull;
230   this->FlagFileNameFull += "/flags.make";
231   this->FlagFileStream =
232     new cmGeneratedFileStream(this->FlagFileNameFull.c_str());
233   this->FlagFileStream->SetCopyIfDifferent(true);
234   if(!this->FlagFileStream)
235     {
236     return;
237     }
238   this->LocalGenerator->WriteDisclaimer(*this->FlagFileStream);
239
240   // Include the flags for the target.
241   *this->BuildFileStream
242     << "# Include the compile flags for this target's objects.\n"
243     << this->LocalGenerator->IncludeDirective << " " << root
244     << this->Convert(this->FlagFileNameFull.c_str(),
245                                      cmLocalGenerator::HOME_OUTPUT,
246                                      cmLocalGenerator::MAKEFILE)
247     << "\n\n";
248 }
249
250 //----------------------------------------------------------------------------
251 std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
252 {
253   ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
254   if (i == this->FlagsByLanguage.end())
255     {
256     std::string flags;
257     const char *lang = l.c_str();
258
259     // Add language feature flags.
260     this->AddFeatureFlags(flags, lang);
261
262     this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
263                                                lang, this->ConfigName);
264
265     // Fortran-specific flags computed for this target.
266     if(l == "Fortran")
267       {
268       this->AddFortranFlags(flags);
269       }
270
271     this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
272                                           lang, this->ConfigName);
273
274     // Add include directory flags.
275     this->AddIncludeFlags(flags, lang);
276
277     // Append old-style preprocessor definition flags.
278     this->LocalGenerator->
279       AppendFlags(flags, this->Makefile->GetDefineFlags());
280
281     // Add include directory flags.
282     this->LocalGenerator->
283       AppendFlags(flags,this->GetFrameworkFlags().c_str());
284
285     ByLanguageMap::value_type entry(l, flags);
286     i = this->FlagsByLanguage.insert(entry).first;
287     }
288   return i->second;
289 }
290
291 std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
292 {
293   ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
294   if (i == this->DefinesByLanguage.end())
295     {
296     std::set<std::string> defines;
297     const char *lang = l.c_str();
298     // Add the export symbol definition for shared library objects.
299     if(const char* exportMacro = this->Target->GetExportMacro())
300       {
301       this->LocalGenerator->AppendDefines(defines, exportMacro);
302       }
303
304     // Add preprocessor definitions for this target and configuration.
305     this->LocalGenerator->AppendDefines
306       (defines, this->Target->GetCompileDefinitions(
307                             this->LocalGenerator->ConfigurationName.c_str()));
308
309     std::string definesString;
310     this->LocalGenerator->JoinDefines(defines, definesString, lang);
311
312     ByLanguageMap::value_type entry(l, definesString);
313     i = this->DefinesByLanguage.insert(entry).first;
314     }
315   return i->second;
316 }
317
318 void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
319 {
320   // write language flags for target
321   std::set<cmStdString> languages;
322   this->Target->GetLanguages(languages);
323     // put the compiler in the rules.make file so that if it changes
324   // things rebuild
325   for(std::set<cmStdString>::const_iterator l = languages.begin();
326       l != languages.end(); ++l)
327     {
328     cmStdString compiler = "CMAKE_";
329     compiler += *l;
330     compiler += "_COMPILER";
331     *this->FlagFileStream << "# compile " << l->c_str() << " with " <<
332       this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
333     }
334
335   for(std::set<cmStdString>::const_iterator l = languages.begin();
336       l != languages.end(); ++l)
337     {
338     *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n";
339     *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) <<
340       "\n\n";
341     }
342
343   // Add target-specific flags.
344   if(this->Target->GetProperty("COMPILE_FLAGS"))
345     {
346     std::string flags;
347     this->LocalGenerator->AppendFlags
348       (flags, this->Target->GetProperty("COMPILE_FLAGS"));
349     *this->FlagFileStream << "# TARGET_FLAGS = " << flags << "\n\n";
350     }
351 }
352
353
354 //----------------------------------------------------------------------------
355 void
356 cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
357   (cmSourceFile& source, const char* pkgloc)
358 {
359   // Skip OS X content when not building a Framework or Bundle.
360   if(this->Generator->MacContentDirectory.empty())
361     {
362     return;
363     }
364
365   std::string macdir =
366     this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
367
368   // Get the input file location.
369   std::string input = source.GetFullPath();
370
371   // Get the output file location.
372   std::string output = macdir;
373   output += "/";
374   output += cmSystemTools::GetFilenameName(input);
375   this->Generator->CleanFiles.push_back(
376     this->Generator->Convert(output.c_str(),
377                              cmLocalGenerator::START_OUTPUT));
378   output = this->Generator->Convert(output.c_str(),
379                                     cmLocalGenerator::HOME_OUTPUT);
380
381   // Create a rule to copy the content into the bundle.
382   std::vector<std::string> depends;
383   std::vector<std::string> commands;
384   depends.push_back(input);
385   std::string copyEcho = "Copying OS X content ";
386   copyEcho += output;
387   this->Generator->LocalGenerator->AppendEcho(
388     commands, copyEcho.c_str(),
389     cmLocalUnixMakefileGenerator3::EchoBuild);
390   std::string copyCommand = "$(CMAKE_COMMAND) -E copy ";
391   copyCommand += this->Generator->Convert(input.c_str(),
392                                           cmLocalGenerator::NONE,
393                                           cmLocalGenerator::SHELL);
394   copyCommand += " ";
395   copyCommand += this->Generator->Convert(output.c_str(),
396                                           cmLocalGenerator::NONE,
397                                           cmLocalGenerator::SHELL);
398   commands.push_back(copyCommand);
399   this->Generator->LocalGenerator->WriteMakeRule(
400     *this->Generator->BuildFileStream, 0,
401     output.c_str(),
402     depends, commands, false);
403   this->Generator->ExtraFiles.insert(output);
404 }
405
406 //----------------------------------------------------------------------------
407 void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
408 {
409   // Identify the language of the source file.
410   const char* lang = this->LocalGenerator->GetSourceFileLanguage(source);
411   if(!lang)
412     {
413     // don't know anything about this file so skip it
414     return;
415     }
416
417   // Get the full path name of the object file.
418   std::string const& objectName = this->GeneratorTarget->Objects[&source];
419   std::string obj = this->LocalGenerator->GetTargetDirectory(*this->Target);
420   obj += "/";
421   obj += objectName;
422
423   // Avoid generating duplicate rules.
424   if(this->ObjectFiles.find(obj) == this->ObjectFiles.end())
425     {
426     this->ObjectFiles.insert(obj);
427     }
428   else
429     {
430     cmOStringStream err;
431     err << "Warning: Source file \""
432         << source.GetFullPath()
433         << "\" is listed multiple times for target \""
434         << this->Target->GetName()
435         << "\".";
436     cmSystemTools::Message(err.str().c_str(), "Warning");
437     return;
438     }
439
440   // Create the directory containing the object file.  This may be a
441   // subdirectory under the target's directory.
442   std::string dir = cmSystemTools::GetFilenamePath(obj.c_str());
443   cmSystemTools::MakeDirectory
444     (this->LocalGenerator->ConvertToFullPath(dir).c_str());
445
446   // Save this in the target's list of object files.
447   this->Objects.push_back(obj);
448   this->CleanFiles.push_back(obj);
449
450   // TODO: Remove
451   //std::string relativeObj
452   //= this->LocalGenerator->GetHomeRelativeOutputPath();
453   //relativeObj += obj;
454
455   // we compute some depends when writing the depend.make that we will also
456   // use in the build.make, same with depMakeFile
457   std::vector<std::string> depends;
458   std::string depMakeFile;
459
460   // generate the build rule file
461   this->WriteObjectBuildFile(obj, lang, source, depends);
462
463   // The object file should be checked for dependency integrity.
464   std::string objFullPath = this->Makefile->GetCurrentOutputDirectory();
465   objFullPath += "/";
466   objFullPath += obj;
467   objFullPath =
468     this->Convert(objFullPath.c_str(), cmLocalGenerator::FULL);
469   std::string srcFullPath =
470     this->Convert(source.GetFullPath().c_str(), cmLocalGenerator::FULL);
471   this->LocalGenerator->
472     AddImplicitDepends(*this->Target, lang,
473                        objFullPath.c_str(),
474                        srcFullPath.c_str());
475 }
476
477 //----------------------------------------------------------------------------
478 void
479 cmMakefileTargetGenerator
480 ::AppendFortranFormatFlags(std::string& flags, cmSourceFile& source)
481 {
482   const char* srcfmt = source.GetProperty("Fortran_FORMAT");
483   cmLocalGenerator::FortranFormat format =
484     this->LocalGenerator->GetFortranFormat(srcfmt);
485   if(format == cmLocalGenerator::FortranFormatNone)
486     {
487     const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT");
488     format = this->LocalGenerator->GetFortranFormat(tgtfmt);
489     }
490   const char* var = 0;
491   switch (format)
492     {
493     case cmLocalGenerator::FortranFormatFixed:
494       var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break;
495     case cmLocalGenerator::FortranFormatFree:
496       var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break;
497     default: break;
498     }
499   if(var)
500     {
501     this->LocalGenerator->AppendFlags(
502       flags, this->Makefile->GetDefinition(var));
503     }
504 }
505
506 //----------------------------------------------------------------------------
507 void
508 cmMakefileTargetGenerator
509 ::WriteObjectBuildFile(std::string &obj,
510                        const char *lang,
511                        cmSourceFile& source,
512                        std::vector<std::string>& depends)
513 {
514   this->LocalGenerator->AppendRuleDepend(depends,
515                                          this->FlagFileNameFull.c_str());
516   this->LocalGenerator->AppendRuleDepends(depends,
517                                           this->FlagFileDepends[lang]);
518
519   // generate the depend scanning rule
520   this->WriteObjectDependRules(source, depends);
521
522   std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath();
523   relativeObj += obj;
524   // Write the build rule.
525
526   // Build the set of compiler flags.
527   std::string flags;
528
529   // Add language-specific flags.
530   std::string langFlags = "$(";
531   langFlags += lang;
532   langFlags += "_FLAGS)";
533   this->LocalGenerator->AppendFlags(flags, langFlags.c_str());
534
535   // Add target-specific flags.
536   if(this->Target->GetProperty("COMPILE_FLAGS"))
537     {
538     std::string langIncludeExpr = "CMAKE_";
539     langIncludeExpr += lang;
540     langIncludeExpr += "_FLAG_REGEX";
541     const char* regex = this->Makefile->
542       GetDefinition(langIncludeExpr.c_str());
543     if(regex)
544       {
545       cmsys::RegularExpression r(regex);
546       std::vector<std::string> args;
547       cmSystemTools::ParseWindowsCommandLine(
548         this->Target->GetProperty("COMPILE_FLAGS"),
549         args);
550       for(std::vector<std::string>::iterator i = args.begin();
551           i != args.end(); ++i)
552         {
553         if(r.find(i->c_str()))
554           {
555           this->LocalGenerator->AppendFlags
556             (flags, i->c_str());
557           }
558         }
559       }
560     else
561       {
562       this->LocalGenerator->AppendFlags
563         (flags, this->Target->GetProperty("COMPILE_FLAGS"));
564       }
565     }
566
567   // Add Fortran format flags.
568   if(strcmp(lang, "Fortran") == 0)
569     {
570     this->AppendFortranFormatFlags(flags, source);
571     }
572
573   // Add flags from source file properties.
574   if (source.GetProperty("COMPILE_FLAGS"))
575     {
576     this->LocalGenerator->AppendFlags
577       (flags, source.GetProperty("COMPILE_FLAGS"));
578     *this->FlagFileStream << "# Custom flags: "
579                           << relativeObj << "_FLAGS = "
580                           << source.GetProperty("COMPILE_FLAGS")
581                           << "\n"
582                           << "\n";
583     }
584
585   // Add language-specific defines.
586   std::set<std::string> defines;
587
588   // Add source-sepcific preprocessor definitions.
589   if(const char* compile_defs = source.GetProperty("COMPILE_DEFINITIONS"))
590     {
591     this->LocalGenerator->AppendDefines(defines, compile_defs);
592     *this->FlagFileStream << "# Custom defines: "
593                           << relativeObj << "_DEFINES = "
594                           << compile_defs << "\n"
595                           << "\n";
596     }
597   std::string configUpper =
598     cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
599   std::string defPropName = "COMPILE_DEFINITIONS_";
600   defPropName += configUpper;
601   if(const char* config_compile_defs =
602      source.GetProperty(defPropName.c_str()))
603     {
604     this->LocalGenerator->AppendDefines(defines, config_compile_defs);
605     *this->FlagFileStream
606       << "# Custom defines: "
607       << relativeObj << "_DEFINES_" << configUpper
608       << " = " << config_compile_defs << "\n"
609       << "\n";
610     }
611
612   // Get the output paths for source and object files.
613   std::string sourceFile = source.GetFullPath();
614   if(this->LocalGenerator->UseRelativePaths)
615     {
616     sourceFile = this->Convert(sourceFile.c_str(),
617                                cmLocalGenerator::START_OUTPUT);
618     }
619   sourceFile = this->Convert(sourceFile.c_str(),
620                              cmLocalGenerator::NONE,
621                              cmLocalGenerator::SHELL);
622
623   // Construct the build message.
624   std::vector<std::string> no_commands;
625   std::vector<std::string> commands;
626
627   // add in a progress call if needed
628   this->AppendProgress(commands);
629
630   if(!this->NoRuleMessages)
631     {
632     std::string buildEcho = "Building ";
633     buildEcho += lang;
634     buildEcho += " object ";
635     buildEcho += relativeObj;
636     this->LocalGenerator->AppendEcho
637       (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild);
638     }
639
640   std::string targetOutPathReal;
641   std::string targetOutPathPDB;
642   {
643   std::string targetFullPathReal;
644   std::string targetFullPathPDB;
645   if(this->Target->GetType() == cmTarget::EXECUTABLE ||
646      this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
647      this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
648      this->Target->GetType() == cmTarget::MODULE_LIBRARY)
649     {
650     targetFullPathReal =
651       this->Target->GetFullPath(this->ConfigName, false, true);
652     targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName);
653     targetFullPathPDB += "/";
654     targetFullPathPDB += this->Target->GetPDBName(this->ConfigName);
655     }
656   targetOutPathReal = this->Convert(targetFullPathReal.c_str(),
657                                     cmLocalGenerator::START_OUTPUT,
658                                     cmLocalGenerator::SHELL);
659   targetOutPathPDB =
660     this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
661                   cmLocalGenerator::SHELL);
662   }
663   cmLocalGenerator::RuleVariables vars;
664   vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
665   vars.CMTarget = this->Target;
666   vars.Language = lang;
667   vars.Target = targetOutPathReal.c_str();
668   vars.TargetPDB = targetOutPathPDB.c_str();
669   vars.Source = sourceFile.c_str();
670   std::string shellObj =
671     this->Convert(obj.c_str(),
672                   cmLocalGenerator::NONE,
673                   cmLocalGenerator::SHELL).c_str();
674   vars.Object = shellObj.c_str();
675   std::string objectDir = cmSystemTools::GetFilenamePath(obj);
676   objectDir = this->Convert(objectDir.c_str(),
677                             cmLocalGenerator::START_OUTPUT,
678                             cmLocalGenerator::SHELL);
679   vars.ObjectDir = objectDir.c_str();
680   vars.Flags = flags.c_str();
681
682   std::string definesString = "$(";
683   definesString += lang;
684   definesString += "_DEFINES)";
685
686   this->LocalGenerator->JoinDefines(defines, definesString, lang);
687
688   vars.Defines = definesString.c_str();
689
690   bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
691                            (strcmp(lang, "CXX") == 0));
692
693   // Construct the compile rules.
694   {
695   std::string compileRuleVar = "CMAKE_";
696   compileRuleVar += lang;
697   compileRuleVar += "_COMPILE_OBJECT";
698   std::string compileRule =
699     this->Makefile->GetRequiredDefinition(compileRuleVar.c_str());
700   std::vector<std::string> compileCommands;
701   cmSystemTools::ExpandListArgument(compileRule, compileCommands);
702
703   if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
704       lang_is_c_or_cxx && compileCommands.size() == 1)
705     {
706     std::string compileCommand = compileCommands[0];
707     this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
708     std::string workingDirectory =
709       this->LocalGenerator->Convert(
710         this->Makefile->GetStartOutputDirectory(), cmLocalGenerator::FULL);
711     compileCommand.replace(compileCommand.find(langFlags),
712                            langFlags.size(), this->GetFlags(lang));
713     std::string langDefines = std::string("$(") + lang + "_DEFINES)";
714     compileCommand.replace(compileCommand.find(langDefines),
715                            langDefines.size(), this->GetDefines(lang));
716     this->GlobalGenerator->AddCXXCompileCommand(
717       source.GetFullPath(), workingDirectory, compileCommand);
718     }
719
720   // Expand placeholders in the commands.
721   for(std::vector<std::string>::iterator i = compileCommands.begin();
722       i != compileCommands.end(); ++i)
723     {
724     this->LocalGenerator->ExpandRuleVariables(*i, vars);
725     }
726
727   // Change the command working directory to the local build tree.
728   this->LocalGenerator->CreateCDCommand
729     (compileCommands,
730      this->Makefile->GetStartOutputDirectory(),
731      cmLocalGenerator::HOME_OUTPUT);
732   commands.insert(commands.end(),
733                   compileCommands.begin(), compileCommands.end());
734   }
735
736   // Write the rule.
737   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
738                                       relativeObj.c_str(),
739                                       depends, commands, false);
740
741   // Check for extra outputs created by the compilation.
742   if(const char* extra_outputs_str =
743      source.GetProperty("OBJECT_OUTPUTS"))
744     {
745     std::vector<std::string> extra_outputs;
746     cmSystemTools::ExpandListArgument(extra_outputs_str, extra_outputs);
747     for(std::vector<std::string>::const_iterator eoi = extra_outputs.begin();
748         eoi != extra_outputs.end(); ++eoi)
749       {
750       // Register this as an extra output for the object file rule.
751       // This will cause the object file to be rebuilt if the extra
752       // output is missing.
753       this->GenerateExtraOutput(eoi->c_str(), relativeObj.c_str(), false);
754
755       // Register this as an extra file to clean.
756       this->CleanFiles.push_back(eoi->c_str());
757       }
758     }
759
760   bool do_preprocess_rules = lang_is_c_or_cxx &&
761     this->LocalGenerator->GetCreatePreprocessedSourceRules();
762   bool do_assembly_rules = lang_is_c_or_cxx &&
763     this->LocalGenerator->GetCreateAssemblySourceRules();
764   if(do_preprocess_rules || do_assembly_rules)
765     {
766     std::vector<std::string> force_depends;
767     force_depends.push_back("cmake_force");
768     std::string::size_type dot_pos = relativeObj.rfind(".");
769     std::string relativeObjBase = relativeObj.substr(0, dot_pos);
770     dot_pos = obj.rfind(".");
771     std::string objBase = obj.substr(0, dot_pos);
772
773     if(do_preprocess_rules)
774       {
775       commands.clear();
776       std::string relativeObjI = relativeObjBase + ".i";
777       std::string objI = objBase + ".i";
778
779       std::string preprocessEcho = "Preprocessing ";
780       preprocessEcho += lang;
781       preprocessEcho += " source to ";
782       preprocessEcho += objI;
783       this->LocalGenerator->AppendEcho(
784         commands, preprocessEcho.c_str(),
785         cmLocalUnixMakefileGenerator3::EchoBuild
786         );
787
788       std::string preprocessRuleVar = "CMAKE_";
789       preprocessRuleVar += lang;
790       preprocessRuleVar += "_CREATE_PREPROCESSED_SOURCE";
791       if(const char* preprocessRule =
792          this->Makefile->GetDefinition(preprocessRuleVar.c_str()))
793         {
794         std::vector<std::string> preprocessCommands;
795         cmSystemTools::ExpandListArgument(preprocessRule, preprocessCommands);
796
797         std::string shellObjI =
798           this->Convert(objI.c_str(),
799                         cmLocalGenerator::NONE,
800                         cmLocalGenerator::SHELL).c_str();
801         vars.PreprocessedSource = shellObjI.c_str();
802
803         // Expand placeholders in the commands.
804         for(std::vector<std::string>::iterator i = preprocessCommands.begin();
805             i != preprocessCommands.end(); ++i)
806           {
807           this->LocalGenerator->ExpandRuleVariables(*i, vars);
808           }
809
810         this->LocalGenerator->CreateCDCommand
811           (preprocessCommands,
812            this->Makefile->GetStartOutputDirectory(),
813            cmLocalGenerator::HOME_OUTPUT);
814         commands.insert(commands.end(),
815                         preprocessCommands.begin(),
816                         preprocessCommands.end());
817         }
818       else
819         {
820         std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
821         cmd += preprocessRuleVar;
822         commands.push_back(cmd);
823         }
824
825       this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
826                                           relativeObjI.c_str(),
827                                           force_depends, commands, false);
828       }
829
830     if(do_assembly_rules)
831       {
832       commands.clear();
833       std::string relativeObjS = relativeObjBase + ".s";
834       std::string objS = objBase + ".s";
835
836       std::string assemblyEcho = "Compiling ";
837       assemblyEcho += lang;
838       assemblyEcho += " source to assembly ";
839       assemblyEcho += objS;
840       this->LocalGenerator->AppendEcho(
841         commands, assemblyEcho.c_str(),
842         cmLocalUnixMakefileGenerator3::EchoBuild
843         );
844
845       std::string assemblyRuleVar = "CMAKE_";
846       assemblyRuleVar += lang;
847       assemblyRuleVar += "_CREATE_ASSEMBLY_SOURCE";
848       if(const char* assemblyRule =
849          this->Makefile->GetDefinition(assemblyRuleVar.c_str()))
850         {
851         std::vector<std::string> assemblyCommands;
852         cmSystemTools::ExpandListArgument(assemblyRule, assemblyCommands);
853
854         std::string shellObjS =
855           this->Convert(objS.c_str(),
856                         cmLocalGenerator::NONE,
857                         cmLocalGenerator::SHELL).c_str();
858         vars.AssemblySource = shellObjS.c_str();
859
860         // Expand placeholders in the commands.
861         for(std::vector<std::string>::iterator i = assemblyCommands.begin();
862             i != assemblyCommands.end(); ++i)
863           {
864           this->LocalGenerator->ExpandRuleVariables(*i, vars);
865           }
866
867         this->LocalGenerator->CreateCDCommand
868           (assemblyCommands,
869            this->Makefile->GetStartOutputDirectory(),
870            cmLocalGenerator::HOME_OUTPUT);
871         commands.insert(commands.end(),
872                         assemblyCommands.begin(),
873                         assemblyCommands.end());
874         }
875       else
876         {
877         std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
878         cmd += assemblyRuleVar;
879         commands.push_back(cmd);
880         }
881
882       this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
883                                           relativeObjS.c_str(),
884                                           force_depends, commands, false);
885       }
886     }
887
888   // If the language needs provides-requires mode, create the
889   // corresponding targets.
890   std::string objectRequires = relativeObj;
891   objectRequires += ".requires";
892   std::vector<std::string> p_depends;
893   // always provide an empty requires target
894   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
895                                       objectRequires.c_str(), p_depends,
896                                       no_commands, true);
897
898   // write a build rule to recursively build what this obj provides
899   std::string objectProvides = relativeObj;
900   objectProvides += ".provides";
901   std::string temp = relativeObj;
902   temp += ".provides.build";
903   std::vector<std::string> r_commands;
904   std::string tgtMakefileName =
905     this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
906   tgtMakefileName += "/build.make";
907   r_commands.push_back
908     (this->LocalGenerator->GetRecursiveMakeCall(tgtMakefileName.c_str(),
909                                                 temp.c_str()));
910
911   p_depends.clear();
912   p_depends.push_back(objectRequires);
913   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
914                                       objectProvides.c_str(), p_depends,
915                                       r_commands, true);
916
917   // write the provides.build rule dependency on the obj file
918   p_depends.clear();
919   p_depends.push_back(relativeObj);
920   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
921                                       temp.c_str(), p_depends, no_commands,
922                                       false);
923 }
924
925 //----------------------------------------------------------------------------
926 void cmMakefileTargetGenerator::WriteTargetRequiresRules()
927 {
928   std::vector<std::string> depends;
929   std::vector<std::string> no_commands;
930
931   // Construct the name of the dependency generation target.
932   std::string depTarget =
933     this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
934   depTarget += "/requires";
935
936   // This target drives dependency generation for all object files.
937   std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
938   std::string objTarget;
939   for(std::vector<std::string>::const_iterator obj = this->Objects.begin();
940       obj != this->Objects.end(); ++obj)
941     {
942     objTarget = relPath;
943     objTarget += *obj;
944     objTarget += ".requires";
945     depends.push_back(objTarget);
946     }
947
948   // Write the rule.
949   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
950                                       depTarget.c_str(),
951                                       depends, no_commands, true);
952 }
953
954 //----------------------------------------------------------------------------
955 void cmMakefileTargetGenerator::WriteTargetCleanRules()
956 {
957   std::vector<std::string> depends;
958   std::vector<std::string> commands;
959
960   // Construct the clean target name.
961   std::string cleanTarget =
962     this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
963   cleanTarget += "/clean";
964
965   // Construct the clean command.
966   this->LocalGenerator->AppendCleanCommand(commands, this->CleanFiles,
967                                            *this->Target);
968   this->LocalGenerator->CreateCDCommand
969     (commands,
970      this->Makefile->GetStartOutputDirectory(),
971      cmLocalGenerator::HOME_OUTPUT);
972
973   // Write the rule.
974   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
975                                       cleanTarget.c_str(),
976                                       depends, commands, true);
977 }
978
979
980 //----------------------------------------------------------------------------
981 void cmMakefileTargetGenerator::WriteTargetDependRules()
982 {
983   // must write the targets depend info file
984   std::string dir = this->LocalGenerator->GetTargetDirectory(*this->Target);
985   this->InfoFileNameFull = dir;
986   this->InfoFileNameFull += "/DependInfo.cmake";
987   this->InfoFileNameFull =
988     this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
989   this->InfoFileStream =
990     new cmGeneratedFileStream(this->InfoFileNameFull.c_str());
991   this->InfoFileStream->SetCopyIfDifferent(true);
992   if(!*this->InfoFileStream)
993     {
994     return;
995     }
996   this->LocalGenerator->
997     WriteDependLanguageInfo(*this->InfoFileStream,*this->Target);
998
999   // Store multiple output pairs in the depend info file.
1000   if(!this->MultipleOutputPairs.empty())
1001     {
1002     *this->InfoFileStream
1003       << "\n"
1004       << "# Pairs of files generated by the same build rule.\n"
1005       << "SET(CMAKE_MULTIPLE_OUTPUT_PAIRS\n";
1006     for(MultipleOutputPairsType::const_iterator pi =
1007           this->MultipleOutputPairs.begin();
1008         pi != this->MultipleOutputPairs.end(); ++pi)
1009       {
1010       *this->InfoFileStream
1011         << "  " << this->LocalGenerator->EscapeForCMake(pi->first.c_str())
1012         << " "  << this->LocalGenerator->EscapeForCMake(pi->second.c_str())
1013         << "\n";
1014       }
1015     *this->InfoFileStream << "  )\n\n";
1016     }
1017
1018   // Store list of targets linked directly or transitively.
1019   {
1020   *this->InfoFileStream
1021     << "\n"
1022     << "# Targets to which this target links.\n"
1023     << "SET(CMAKE_TARGET_LINKED_INFO_FILES\n";
1024   std::set<cmTarget const*> emitted;
1025   const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
1026   if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
1027     {
1028     cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
1029     for(cmComputeLinkInformation::ItemVector::const_iterator
1030           i = items.begin(); i != items.end(); ++i)
1031       {
1032       cmTarget const* linkee = i->Target;
1033       if(linkee && !linkee->IsImported() && emitted.insert(linkee).second)
1034         {
1035         cmMakefile* mf = linkee->GetMakefile();
1036         cmLocalGenerator* lg = mf->GetLocalGenerator();
1037         std::string di = mf->GetStartOutputDirectory();
1038         di += "/";
1039         di += lg->GetTargetDirectory(*linkee);
1040         di += "/DependInfo.cmake";
1041         *this->InfoFileStream << "  \"" << di << "\"\n";
1042         }
1043       }
1044     }
1045   *this->InfoFileStream
1046     << "  )\n";
1047   }
1048
1049   // Check for a target-specific module output directory.
1050   if(const char* mdir = this->GetFortranModuleDirectory())
1051     {
1052     *this->InfoFileStream
1053       << "\n"
1054       << "# Fortran module output directory.\n"
1055       << "SET(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n";
1056     }
1057
1058   // Target-specific include directories:
1059   *this->InfoFileStream
1060     << "\n"
1061     << "# The include file search paths:\n";
1062   *this->InfoFileStream
1063     << "SET(CMAKE_C_TARGET_INCLUDE_PATH\n";
1064   std::vector<std::string> includes;
1065
1066   const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
1067   this->LocalGenerator->GetIncludeDirectories(includes,
1068                                               this->GeneratorTarget,
1069                                               "C", config);
1070   for(std::vector<std::string>::iterator i = includes.begin();
1071       i != includes.end(); ++i)
1072     {
1073     *this->InfoFileStream
1074       << "  \""
1075       << this->LocalGenerator->Convert(i->c_str(),
1076                                        cmLocalGenerator::HOME_OUTPUT)
1077       << "\"\n";
1078     }
1079   *this->InfoFileStream
1080     << "  )\n";
1081   *this->InfoFileStream
1082     << "SET(CMAKE_CXX_TARGET_INCLUDE_PATH "
1083     << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
1084   *this->InfoFileStream
1085     << "SET(CMAKE_Fortran_TARGET_INCLUDE_PATH "
1086     << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
1087   *this->InfoFileStream
1088     << "SET(CMAKE_ASM_TARGET_INCLUDE_PATH "
1089     << "${CMAKE_C_TARGET_INCLUDE_PATH})\n";
1090
1091   // and now write the rule to use it
1092   std::vector<std::string> depends;
1093   std::vector<std::string> commands;
1094
1095   // Construct the name of the dependency generation target.
1096   std::string depTarget =
1097     this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
1098   depTarget += "/depend";
1099
1100   // Add a command to call CMake to scan dependencies.  CMake will
1101   // touch the corresponding depends file after scanning dependencies.
1102   cmOStringStream depCmd;
1103   // TODO: Account for source file properties and directory-level
1104   // definitions when scanning for dependencies.
1105 #if !defined(_WIN32) || defined(__CYGWIN__)
1106   // This platform supports symlinks, so cmSystemTools will translate
1107   // paths.  Make sure PWD is set to the original name of the home
1108   // output directory to help cmSystemTools to create the same
1109   // translation table for the dependency scanning process.
1110   depCmd << "cd "
1111          << (this->LocalGenerator->Convert(
1112                this->Makefile->GetHomeOutputDirectory(),
1113                cmLocalGenerator::FULL, cmLocalGenerator::SHELL))
1114          << " && ";
1115 #endif
1116   // Generate a call this signature:
1117   //
1118   //   cmake -E cmake_depends <generator>
1119   //                          <home-src-dir> <start-src-dir>
1120   //                          <home-out-dir> <start-out-dir>
1121   //                          <dep-info> --color=$(COLOR)
1122   //
1123   // This gives the dependency scanner enough information to recreate
1124   // the state of our local generator sufficiently for its needs.
1125   depCmd << "$(CMAKE_COMMAND) -E cmake_depends \""
1126          << this->GlobalGenerator->GetName() << "\" "
1127          << this->Convert(this->Makefile->GetHomeDirectory(),
1128                           cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
1129          << " "
1130          << this->Convert(this->Makefile->GetStartDirectory(),
1131                           cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
1132          << " "
1133          << this->Convert(this->Makefile->GetHomeOutputDirectory(),
1134                           cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
1135          << " "
1136          << this->Convert(this->Makefile->GetStartOutputDirectory(),
1137                           cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
1138          << " "
1139          << this->Convert(this->InfoFileNameFull.c_str(),
1140                           cmLocalGenerator::FULL, cmLocalGenerator::SHELL);
1141   if(this->LocalGenerator->GetColorMakefile())
1142     {
1143     depCmd << " --color=$(COLOR)";
1144     }
1145   commands.push_back(depCmd.str());
1146
1147   // Make sure all custom command outputs in this target are built.
1148   if(this->CustomCommandDriver == OnDepends)
1149     {
1150     this->DriveCustomCommands(depends);
1151     }
1152
1153   // Write the rule.
1154   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
1155                                       depTarget.c_str(),
1156                                       depends, commands, true);
1157 }
1158
1159 //----------------------------------------------------------------------------
1160 void
1161 cmMakefileTargetGenerator
1162 ::DriveCustomCommands(std::vector<std::string>& depends)
1163 {
1164   // Depend on all custom command outputs.
1165   const std::vector<cmSourceFile*>& sources =
1166     this->Target->GetSourceFiles();
1167   for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
1168       source != sources.end(); ++source)
1169     {
1170     if(cmCustomCommand* cc = (*source)->GetCustomCommand())
1171       {
1172       const std::vector<std::string>& outputs = cc->GetOutputs();
1173       for(std::vector<std::string>::const_iterator o = outputs.begin();
1174           o != outputs.end(); ++o)
1175         {
1176         depends.push_back(*o);
1177         }
1178       }
1179     }
1180 }
1181
1182 //----------------------------------------------------------------------------
1183 void cmMakefileTargetGenerator
1184 ::WriteObjectDependRules(cmSourceFile& source,
1185                          std::vector<std::string>& depends)
1186 {
1187   // Create the list of dependencies known at cmake time.  These are
1188   // shared between the object file and dependency scanning rule.
1189   depends.push_back(source.GetFullPath());
1190   if(const char* objectDeps = source.GetProperty("OBJECT_DEPENDS"))
1191     {
1192     std::vector<std::string> deps;
1193     cmSystemTools::ExpandListArgument(objectDeps, deps);
1194     for(std::vector<std::string>::iterator i = deps.begin();
1195         i != deps.end(); ++i)
1196       {
1197       depends.push_back(i->c_str());
1198       }
1199     }
1200 }
1201
1202 //----------------------------------------------------------------------------
1203 void cmMakefileTargetGenerator
1204 ::GenerateCustomRuleFile(const cmCustomCommand& cc)
1205 {
1206   // Collect the commands.
1207   std::vector<std::string> commands;
1208   std::string comment = this->LocalGenerator->ConstructComment(cc);
1209   if(!comment.empty())
1210     {
1211     // add in a progress call if needed
1212     this->AppendProgress(commands);
1213     if(!this->NoRuleMessages)
1214       {
1215       this->LocalGenerator
1216         ->AppendEcho(commands, comment.c_str(),
1217                      cmLocalUnixMakefileGenerator3::EchoGenerate);
1218       }
1219     }
1220
1221   // Now append the actual user-specified commands.
1222   cmOStringStream content;
1223   this->LocalGenerator->AppendCustomCommand(commands, cc, this->Target, false,
1224                                             cmLocalGenerator::HOME_OUTPUT,
1225                                             &content);
1226
1227   // Collect the dependencies.
1228   std::vector<std::string> depends;
1229   this->LocalGenerator->AppendCustomDepend(depends, cc);
1230
1231   // Check whether we need to bother checking for a symbolic output.
1232   bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
1233
1234   // Write the rule.
1235   const std::vector<std::string>& outputs = cc.GetOutputs();
1236   std::vector<std::string>::const_iterator o = outputs.begin();
1237   {
1238   bool symbolic = false;
1239   if(need_symbolic)
1240     {
1241     if(cmSourceFile* sf = this->Makefile->GetSource(o->c_str()))
1242       {
1243       symbolic = sf->GetPropertyAsBool("SYMBOLIC");
1244       }
1245     }
1246   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
1247                                       o->c_str(), depends, commands,
1248                                       symbolic);
1249
1250   // If the rule has changed make sure the output is rebuilt.
1251   if(!symbolic)
1252     {
1253     this->GlobalGenerator->AddRuleHash(cc.GetOutputs(), content.str());
1254     }
1255   }
1256
1257   // Write rules to drive building any outputs beyond the first.
1258   const char* in = o->c_str();
1259   for(++o; o != outputs.end(); ++o)
1260     {
1261     bool symbolic = false;
1262     if(need_symbolic)
1263       {
1264       if(cmSourceFile* sf = this->Makefile->GetSource(o->c_str()))
1265         {
1266         symbolic = sf->GetPropertyAsBool("SYMBOLIC");
1267         }
1268       }
1269     this->GenerateExtraOutput(o->c_str(), in, symbolic);
1270     }
1271
1272   // Setup implicit dependency scanning.
1273   for(cmCustomCommand::ImplicitDependsList::const_iterator
1274         idi = cc.GetImplicitDepends().begin();
1275       idi != cc.GetImplicitDepends().end(); ++idi)
1276     {
1277     std::string objFullPath =
1278       this->Convert(outputs[0].c_str(), cmLocalGenerator::FULL);
1279     std::string srcFullPath =
1280       this->Convert(idi->second.c_str(), cmLocalGenerator::FULL);
1281     this->LocalGenerator->
1282       AddImplicitDepends(*this->Target, idi->first.c_str(),
1283                          objFullPath.c_str(),
1284                          srcFullPath.c_str());
1285     }
1286 }
1287
1288 //----------------------------------------------------------------------------
1289 void
1290 cmMakefileTargetGenerator
1291 ::GenerateExtraOutput(const char* out, const char* in, bool symbolic)
1292 {
1293   // Add a rule to build the primary output if the extra output needs
1294   // to be created.
1295   std::vector<std::string> commands;
1296   std::vector<std::string> depends;
1297   std::string emptyCommand = this->GlobalGenerator->GetEmptyRuleHackCommand();
1298   if(!emptyCommand.empty())
1299     {
1300     commands.push_back(emptyCommand);
1301     }
1302   depends.push_back(in);
1303   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
1304                                       out, depends, commands,
1305                                       symbolic);
1306
1307   // Register the extra output as paired with the first output so that
1308   // the check-build-system step will remove the primary output if any
1309   // extra outputs are missing.  This forces the rule to regenerate
1310   // all outputs.
1311   this->AddMultipleOutputPair(out, in);
1312 }
1313
1314 //----------------------------------------------------------------------------
1315 void
1316 cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands)
1317 {
1318   this->NumberOfProgressActions++;
1319   if(this->NoRuleMessages)
1320     {
1321     return;
1322     }
1323   std::string progressDir = this->Makefile->GetHomeOutputDirectory();
1324   progressDir += cmake::GetCMakeFilesDirectory();
1325   cmOStringStream progCmd;
1326   progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
1327   progCmd << this->LocalGenerator->Convert(progressDir.c_str(),
1328                                            cmLocalGenerator::FULL,
1329                                            cmLocalGenerator::SHELL);
1330   progCmd << " $(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")";
1331   commands.push_back(progCmd.str());
1332 }
1333
1334 //----------------------------------------------------------------------------
1335 void
1336 cmMakefileTargetGenerator
1337 ::WriteObjectsVariable(std::string& variableName,
1338                        std::string& variableNameExternal)
1339 {
1340   // Write a make variable assignment that lists all objects for the
1341   // target.
1342   variableName =
1343     this->LocalGenerator->CreateMakeVariable(this->Target->GetName(),
1344                                              "_OBJECTS");
1345   *this->BuildFileStream
1346     << "# Object files for target " << this->Target->GetName() << "\n"
1347     << variableName.c_str() << " =";
1348   std::string object;
1349   const char* objName =
1350     this->Makefile->GetDefinition("CMAKE_NO_QUOTED_OBJECTS");
1351   const char* lineContinue =
1352     this->Makefile->GetDefinition("CMAKE_MAKE_LINE_CONTINUE");
1353   if(!lineContinue)
1354     {
1355     lineContinue = "\\";
1356     }
1357   for(std::vector<std::string>::const_iterator i = this->Objects.begin();
1358       i != this->Objects.end(); ++i)
1359     {
1360     *this->BuildFileStream << " " << lineContinue << "\n";
1361     if(objName)
1362       {
1363       *this->BuildFileStream <<
1364         this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT,
1365                       cmLocalGenerator::MAKEFILE);
1366       }
1367     else
1368       {
1369       *this->BuildFileStream  <<
1370         this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
1371       }
1372     }
1373   *this->BuildFileStream << "\n";
1374
1375   // Write a make variable assignment that lists all external objects
1376   // for the target.
1377   variableNameExternal =
1378     this->LocalGenerator->CreateMakeVariable(this->Target->GetName(),
1379                                              "_EXTERNAL_OBJECTS");
1380   *this->BuildFileStream
1381     << "\n"
1382     << "# External object files for target "
1383     << this->Target->GetName() << "\n"
1384     << variableNameExternal.c_str() << " =";
1385   for(std::vector<std::string>::const_iterator i =
1386         this->ExternalObjects.begin();
1387       i != this->ExternalObjects.end(); ++i)
1388     {
1389     object = this->Convert(i->c_str(),cmLocalGenerator::START_OUTPUT);
1390     *this->BuildFileStream
1391       << " " << lineContinue << "\n"
1392       << this->Makefile->GetSafeDefinition("CMAKE_OBJECT_NAME");
1393     if(objName)
1394       {
1395       *this->BuildFileStream  <<
1396         this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT,
1397                       cmLocalGenerator::MAKEFILE);
1398       }
1399     else
1400       {
1401       *this->BuildFileStream  <<
1402         this->LocalGenerator->ConvertToQuotedOutputPath(i->c_str());
1403       }
1404     }
1405   *this->BuildFileStream << "\n" << "\n";
1406 }
1407
1408 //----------------------------------------------------------------------------
1409 void
1410 cmMakefileTargetGenerator
1411 ::WriteObjectsString(std::string& buildObjs)
1412 {
1413   std::vector<std::string> objStrings;
1414   this->WriteObjectsStrings(objStrings);
1415   buildObjs = objStrings[0];
1416 }
1417
1418 //----------------------------------------------------------------------------
1419 class cmMakefileTargetGeneratorObjectStrings
1420 {
1421 public:
1422   cmMakefileTargetGeneratorObjectStrings(std::vector<std::string>& strings,
1423                                          cmLocalUnixMakefileGenerator3* lg,
1424                                          std::string::size_type limit):
1425     Strings(strings), LocalGenerator(lg), LengthLimit(limit)
1426     {
1427     this->Space = "";
1428     }
1429   void Feed(std::string const& obj)
1430     {
1431     // Construct the name of the next object.
1432     this->NextObject =
1433       this->LocalGenerator->Convert(obj.c_str(),
1434                                     cmLocalGenerator::START_OUTPUT,
1435                                     cmLocalGenerator::RESPONSE);
1436
1437     // Roll over to next string if the limit will be exceeded.
1438     if(this->LengthLimit != std::string::npos &&
1439        (this->CurrentString.length() + 1 + this->NextObject.length()
1440         > this->LengthLimit))
1441       {
1442       this->Strings.push_back(this->CurrentString);
1443       this->CurrentString = "";
1444       this->Space = "";
1445       }
1446
1447     // Separate from previous object.
1448     this->CurrentString += this->Space;
1449     this->Space = " ";
1450
1451     // Append this object.
1452     this->CurrentString += this->NextObject;
1453     }
1454   void Done()
1455     {
1456     this->Strings.push_back(this->CurrentString);
1457     }
1458 private:
1459   std::vector<std::string>& Strings;
1460   cmLocalUnixMakefileGenerator3* LocalGenerator;
1461   std::string::size_type LengthLimit;
1462   std::string CurrentString;
1463   std::string NextObject;
1464   const char* Space;
1465 };
1466
1467 //----------------------------------------------------------------------------
1468 void
1469 cmMakefileTargetGenerator
1470 ::WriteObjectsStrings(std::vector<std::string>& objStrings,
1471                       std::string::size_type limit)
1472 {
1473   cmMakefileTargetGeneratorObjectStrings
1474     helper(objStrings, this->LocalGenerator, limit);
1475   for(std::vector<std::string>::const_iterator i = this->Objects.begin();
1476       i != this->Objects.end(); ++i)
1477     {
1478     helper.Feed(*i);
1479     }
1480   for(std::vector<std::string>::const_iterator i =
1481         this->ExternalObjects.begin();
1482       i != this->ExternalObjects.end(); ++i)
1483     {
1484     helper.Feed(*i);
1485     }
1486   helper.Done();
1487 }
1488
1489 //----------------------------------------------------------------------------
1490 void cmMakefileTargetGenerator::WriteTargetDriverRule(const char* main_output,
1491                                                       bool relink)
1492 {
1493   // Compute the name of the driver target.
1494   std::string dir =
1495     this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
1496   std::string buildTargetRuleName = dir;
1497   buildTargetRuleName += relink?"/preinstall":"/build";
1498   buildTargetRuleName = this->Convert(buildTargetRuleName.c_str(),
1499                                       cmLocalGenerator::HOME_OUTPUT,
1500                                       cmLocalGenerator::UNCHANGED);
1501
1502   // Build the list of target outputs to drive.
1503   std::vector<std::string> depends;
1504   if(main_output)
1505     {
1506     depends.push_back(main_output);
1507     }
1508
1509   const char* comment = 0;
1510   if(relink)
1511     {
1512     // Setup the comment for the preinstall driver.
1513     comment = "Rule to relink during preinstall.";
1514     }
1515   else
1516     {
1517     // Setup the comment for the main build driver.
1518     comment = "Rule to build all files generated by this target.";
1519
1520     // Make sure all custom command outputs in this target are built.
1521     if(this->CustomCommandDriver == OnBuild)
1522       {
1523       this->DriveCustomCommands(depends);
1524       }
1525
1526     // Make sure the extra files are built.
1527     for(std::set<cmStdString>::const_iterator i = this->ExtraFiles.begin();
1528         i != this->ExtraFiles.end(); ++i)
1529       {
1530       depends.push_back(*i);
1531       }
1532     }
1533
1534   // Write the driver rule.
1535   std::vector<std::string> no_commands;
1536   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, comment,
1537                                       buildTargetRuleName.c_str(),
1538                                       depends, no_commands, true);
1539 }
1540
1541 //----------------------------------------------------------------------------
1542 std::string cmMakefileTargetGenerator::GetFrameworkFlags()
1543 {
1544  if(!this->Makefile->IsOn("APPLE"))
1545    {
1546    return std::string();
1547    }
1548
1549  std::set<cmStdString> emitted;
1550 #ifdef __APPLE__  /* don't insert this when crosscompiling e.g. to iphone */
1551   emitted.insert("/System/Library/Frameworks");
1552 #endif
1553   std::vector<std::string> includes;
1554
1555   const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
1556   this->LocalGenerator->GetIncludeDirectories(includes,
1557                                               this->GeneratorTarget,
1558                                               "C", config);
1559   // check all include directories for frameworks as this
1560   // will already have added a -F for the framework
1561   for(std::vector<std::string>::iterator i = includes.begin();
1562       i != includes.end(); ++i)
1563     {
1564     if(this->Target->NameResolvesToFramework(i->c_str()))
1565       {
1566       std::string frameworkDir = *i;
1567       frameworkDir += "/../";
1568       frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
1569       emitted.insert(frameworkDir);
1570       }
1571     }
1572
1573   std::string flags;
1574   const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
1575   if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
1576     {
1577     std::vector<std::string> const& frameworks = cli->GetFrameworkPaths();
1578     for(std::vector<std::string>::const_iterator i = frameworks.begin();
1579         i != frameworks.end(); ++i)
1580       {
1581       if(emitted.insert(*i).second)
1582         {
1583         flags += "-F";
1584         flags += this->Convert(i->c_str(),
1585                                cmLocalGenerator::START_OUTPUT,
1586                                cmLocalGenerator::SHELL, true);
1587         flags += " ";
1588         }
1589       }
1590     }
1591   return flags;
1592 }
1593
1594 //----------------------------------------------------------------------------
1595 void cmMakefileTargetGenerator
1596 ::AppendTargetDepends(std::vector<std::string>& depends)
1597 {
1598   // Static libraries never depend on anything for linking.
1599   if(this->Target->GetType() == cmTarget::STATIC_LIBRARY)
1600     {
1601     return;
1602     }
1603
1604   // Loop over all library dependencies.
1605   const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
1606   if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg))
1607     {
1608     std::vector<std::string> const& libDeps = cli->GetDepends();
1609     for(std::vector<std::string>::const_iterator j = libDeps.begin();
1610         j != libDeps.end(); ++j)
1611       {
1612       depends.push_back(*j);
1613       }
1614     }
1615 }
1616
1617 //----------------------------------------------------------------------------
1618 void cmMakefileTargetGenerator
1619 ::AppendObjectDepends(std::vector<std::string>& depends)
1620 {
1621   // Add dependencies on the compiled object files.
1622   std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
1623   std::string objTarget;
1624   for(std::vector<std::string>::const_iterator obj = this->Objects.begin();
1625       obj != this->Objects.end(); ++obj)
1626     {
1627     objTarget = relPath;
1628     objTarget += *obj;
1629     depends.push_back(objTarget);
1630     }
1631
1632   // Add dependencies on the external object files.
1633   for(std::vector<std::string>::const_iterator obj
1634         = this->ExternalObjects.begin();
1635       obj != this->ExternalObjects.end(); ++obj)
1636     {
1637     depends.push_back(*obj);
1638     }
1639
1640   // Add a dependency on the rule file itself.
1641   this->LocalGenerator->AppendRuleDepend(depends,
1642                                          this->BuildFileNameFull.c_str());
1643 }
1644
1645 //----------------------------------------------------------------------------
1646 void cmMakefileTargetGenerator
1647 ::AppendLinkDepends(std::vector<std::string>& depends)
1648 {
1649   this->AppendObjectDepends(depends);
1650
1651   // Add dependencies on targets that must be built first.
1652   this->AppendTargetDepends(depends);
1653
1654   // Add a dependency on the link definitions file, if any.
1655   if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
1656     {
1657     depends.push_back(this->GeneratorTarget->ModuleDefinitionFile);
1658     }
1659
1660   // Add user-specified dependencies.
1661   if(const char* linkDepends =
1662      this->Target->GetProperty("LINK_DEPENDS"))
1663     {
1664     cmSystemTools::ExpandListArgument(linkDepends, depends);
1665     }
1666 }
1667
1668 //----------------------------------------------------------------------------
1669 std::string cmMakefileTargetGenerator::GetLinkRule(const char* linkRuleVar)
1670 {
1671   std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
1672   if(this->Target->HasImplibGNUtoMS())
1673     {
1674     std::string ruleVar = "CMAKE_";
1675     ruleVar += this->Target->GetLinkerLanguage(this->ConfigName);
1676     ruleVar += "_GNUtoMS_RULE";
1677     if(const char* rule = this->Makefile->GetDefinition(ruleVar.c_str()))
1678       {
1679       linkRule += rule;
1680       }
1681     }
1682   return linkRule;
1683 }
1684
1685 //----------------------------------------------------------------------------
1686 void cmMakefileTargetGenerator
1687 ::CloseFileStreams()
1688 {
1689   delete this->BuildFileStream;
1690   delete this->InfoFileStream;
1691   delete this->FlagFileStream;
1692 }
1693
1694 void cmMakefileTargetGenerator::RemoveForbiddenFlags(const char* flagVar,
1695                                                      const char* linkLang,
1696                                                      std::string& linkFlags)
1697 {
1698   // check for language flags that are not allowed at link time, and
1699   // remove them, -w on darwin for gcc -w -dynamiclib sends -w to libtool
1700   // which fails, there may be more]
1701
1702   std::string removeFlags = "CMAKE_";
1703   removeFlags += linkLang;
1704   removeFlags += flagVar;
1705   std::string removeflags =
1706     this->Makefile->GetSafeDefinition(removeFlags.c_str());
1707   std::vector<std::string> removeList;
1708   cmSystemTools::ExpandListArgument(removeflags, removeList);
1709   for(std::vector<std::string>::iterator i = removeList.begin();
1710       i != removeList.end(); ++i)
1711     {
1712     cmSystemTools::ReplaceString(linkFlags, i->c_str(), "");
1713     }
1714 }
1715
1716 //----------------------------------------------------------------------------
1717 void
1718 cmMakefileTargetGenerator
1719 ::AddMultipleOutputPair(const char* depender, const char* dependee)
1720 {
1721   MultipleOutputPairsType::value_type p(depender, dependee);
1722   this->MultipleOutputPairs.insert(p);
1723 }
1724
1725 //----------------------------------------------------------------------------
1726 void
1727 cmMakefileTargetGenerator
1728 ::CreateLinkScript(const char* name,
1729                    std::vector<std::string> const& link_commands,
1730                    std::vector<std::string>& makefile_commands,
1731                    std::vector<std::string>& makefile_depends)
1732 {
1733   // Create the link script file.
1734   std::string linkScriptName = this->TargetBuildDirectoryFull;
1735   linkScriptName += "/";
1736   linkScriptName += name;
1737   cmGeneratedFileStream linkScriptStream(linkScriptName.c_str());
1738   linkScriptStream.SetCopyIfDifferent(true);
1739   for(std::vector<std::string>::const_iterator cmd = link_commands.begin();
1740       cmd != link_commands.end(); ++cmd)
1741     {
1742     // Do not write out empty commands or commands beginning in the
1743     // shell no-op ":".
1744     if(!cmd->empty() && (*cmd)[0] != ':')
1745       {
1746       linkScriptStream << *cmd << "\n";
1747       }
1748     }
1749
1750   // Create the makefile command to invoke the link script.
1751   std::string link_command = "$(CMAKE_COMMAND) -E cmake_link_script ";
1752   link_command += this->Convert(linkScriptName.c_str(),
1753                                 cmLocalGenerator::START_OUTPUT,
1754                                 cmLocalGenerator::SHELL);
1755   link_command += " --verbose=$(VERBOSE)";
1756   makefile_commands.push_back(link_command);
1757   makefile_depends.push_back(linkScriptName);
1758 }
1759
1760 //----------------------------------------------------------------------------
1761 std::string
1762 cmMakefileTargetGenerator
1763 ::CreateResponseFile(const char* name, std::string const& options,
1764                      std::vector<std::string>& makefile_depends)
1765 {
1766   // Create the response file.
1767   std::string responseFileNameFull = this->TargetBuildDirectoryFull;
1768   responseFileNameFull += "/";
1769   responseFileNameFull += name;
1770   cmGeneratedFileStream responseStream(responseFileNameFull.c_str());
1771   responseStream.SetCopyIfDifferent(true);
1772   responseStream << options << "\n";
1773
1774   // Add a dependency so the target will rebuild when the set of
1775   // objects changes.
1776   makefile_depends.push_back(responseFileNameFull);
1777
1778   // Construct the name to be used on the command line.
1779   std::string responseFileName = this->TargetBuildDirectory;
1780   responseFileName += "/";
1781   responseFileName += name;
1782   return responseFileName;
1783 }
1784
1785 //----------------------------------------------------------------------------
1786 void
1787 cmMakefileTargetGenerator
1788 ::CreateObjectLists(bool useLinkScript, bool useArchiveRules,
1789                     bool useResponseFile, std::string& buildObjs,
1790                     std::vector<std::string>& makefile_depends)
1791 {
1792   std::string variableName;
1793   std::string variableNameExternal;
1794   this->WriteObjectsVariable(variableName, variableNameExternal);
1795   if(useResponseFile)
1796     {
1797     // MSVC response files cannot exceed 128K.
1798     std::string::size_type const responseFileLimit = 131000;
1799
1800     // Construct the individual object list strings.
1801     std::vector<std::string> object_strings;
1802     this->WriteObjectsStrings(object_strings, responseFileLimit);
1803
1804     // Lookup the response file reference flag.
1805     std::string responseFlagVar = "CMAKE_";
1806     responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
1807     responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
1808     const char* responseFlag =
1809       this->Makefile->GetDefinition(responseFlagVar.c_str());
1810     if(!responseFlag)
1811       {
1812       responseFlag = "@";
1813       }
1814
1815     // Write a response file for each string.
1816     const char* sep = "";
1817     for(unsigned int i = 0; i < object_strings.size(); ++i)
1818       {
1819       // Number the response files.
1820       char rsp[32];
1821       sprintf(rsp, "objects%u.rsp", i+1);
1822
1823       // Create this response file.
1824       std::string objects_rsp =
1825         this->CreateResponseFile(rsp, object_strings[i], makefile_depends);
1826
1827       // Separate from previous response file references.
1828       buildObjs += sep;
1829       sep = " ";
1830
1831       // Reference the response file.
1832       buildObjs += responseFlag;
1833       buildObjs += this->Convert(objects_rsp.c_str(),
1834                                  cmLocalGenerator::NONE,
1835                                  cmLocalGenerator::SHELL);
1836       }
1837     }
1838   else if(useLinkScript)
1839     {
1840     if(!useArchiveRules)
1841       {
1842       this->WriteObjectsString(buildObjs);
1843       }
1844     }
1845   else
1846     {
1847     buildObjs = "$(";
1848     buildObjs += variableName;
1849     buildObjs += ") $(";
1850     buildObjs += variableNameExternal;
1851     buildObjs += ")";
1852     }
1853 }
1854
1855 //----------------------------------------------------------------------------
1856 void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
1857                                                 const char* lang)
1858 {
1859   std::string responseVar = "CMAKE_";
1860   responseVar += lang;
1861   responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES";
1862   bool useResponseFile = this->Makefile->IsOn(responseVar.c_str());
1863
1864
1865   std::vector<std::string> includes;
1866   const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
1867   this->LocalGenerator->GetIncludeDirectories(includes,
1868                                               this->GeneratorTarget,
1869                                               lang, config);
1870
1871   std::string includeFlags =
1872     this->LocalGenerator->GetIncludeFlags(includes, lang, useResponseFile);
1873   if(includeFlags.empty())
1874     {
1875     return;
1876     }
1877
1878   if(useResponseFile)
1879     {
1880     std::string name = "includes_";
1881     name += lang;
1882     name += ".rsp";
1883     std::string arg = "@" +
1884       this->CreateResponseFile(name.c_str(), includeFlags,
1885                                this->FlagFileDepends[lang]);
1886     this->LocalGenerator->AppendFlags(flags, arg.c_str());
1887     }
1888   else
1889     {
1890     this->LocalGenerator->AppendFlags(flags, includeFlags.c_str());
1891     }
1892 }
1893
1894 //----------------------------------------------------------------------------
1895 const char* cmMakefileTargetGenerator::GetFortranModuleDirectory()
1896 {
1897   // Compute the module directory.
1898   if(!this->FortranModuleDirectoryComputed)
1899     {
1900     const char* target_mod_dir =
1901       this->Target->GetProperty("Fortran_MODULE_DIRECTORY");
1902     const char* moddir_flag =
1903       this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
1904     if(target_mod_dir && moddir_flag)
1905       {
1906       // Compute the full path to the module directory.
1907       if(cmSystemTools::FileIsFullPath(target_mod_dir))
1908         {
1909         // Already a full path.
1910         this->FortranModuleDirectory = target_mod_dir;
1911         }
1912       else
1913         {
1914         // Interpret relative to the current output directory.
1915         this->FortranModuleDirectory =
1916           this->Makefile->GetCurrentOutputDirectory();
1917         this->FortranModuleDirectory += "/";
1918         this->FortranModuleDirectory += target_mod_dir;
1919         }
1920
1921       // Make sure the module output directory exists.
1922       cmSystemTools::MakeDirectory(this->FortranModuleDirectory.c_str());
1923       }
1924     this->FortranModuleDirectoryComputed = true;
1925     }
1926
1927   // Return the computed directory.
1928   if(this->FortranModuleDirectory.empty())
1929     {
1930     return 0;
1931     }
1932   else
1933     {
1934     return this->FortranModuleDirectory.c_str();
1935     }
1936 }
1937
1938 //----------------------------------------------------------------------------
1939 void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
1940 {
1941   // Enable module output if necessary.
1942   if(const char* modout_flag =
1943      this->Makefile->GetDefinition("CMAKE_Fortran_MODOUT_FLAG"))
1944     {
1945     this->LocalGenerator->AppendFlags(flags, modout_flag);
1946     }
1947
1948   // Add a module output directory flag if necessary.
1949   const char* mod_dir = this->GetFortranModuleDirectory();
1950   if(!mod_dir)
1951     {
1952     mod_dir = this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
1953     }
1954   if(mod_dir)
1955     {
1956     const char* moddir_flag =
1957       this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
1958     std::string modflag = moddir_flag;
1959     modflag += this->Convert(mod_dir,
1960                              cmLocalGenerator::START_OUTPUT,
1961                              cmLocalGenerator::SHELL);
1962     this->LocalGenerator->AppendFlags(flags, modflag.c_str());
1963     }
1964
1965   // If there is a separate module path flag then duplicate the
1966   // include path with it.  This compiler does not search the include
1967   // path for modules.
1968   if(const char* modpath_flag =
1969      this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
1970     {
1971     std::vector<std::string> includes;
1972     const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
1973     this->LocalGenerator->GetIncludeDirectories(includes,
1974                                                 this->GeneratorTarget,
1975                                                 "C", config);
1976     for(std::vector<std::string>::const_iterator idi = includes.begin();
1977         idi != includes.end(); ++idi)
1978       {
1979       std::string flg = modpath_flag;
1980       flg += this->Convert(idi->c_str(),
1981                            cmLocalGenerator::NONE,
1982                            cmLocalGenerator::SHELL);
1983       this->LocalGenerator->AppendFlags(flags, flg.c_str());
1984       }
1985     }
1986 }
1987
1988 //----------------------------------------------------------------------------
1989 void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
1990 {
1991   if(this->GeneratorTarget->ModuleDefinitionFile.empty())
1992     {
1993     return;
1994     }
1995
1996   // TODO: Create a per-language flag variable.
1997   const char* defFileFlag =
1998     this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
1999   if(!defFileFlag)
2000     {
2001     return;
2002     }
2003
2004   // Append the flag and value.  Use ConvertToLinkReference to help
2005   // vs6's "cl -link" pass it to the linker.
2006   std::string flag = defFileFlag;
2007   flag += (this->LocalGenerator->ConvertToLinkReference(
2008              this->GeneratorTarget->ModuleDefinitionFile.c_str()));
2009   this->LocalGenerator->AppendFlags(flags, flag.c_str());
2010 }
2011
2012 //----------------------------------------------------------------------------
2013 const char* cmMakefileTargetGenerator::GetFeature(const char* feature)
2014 {
2015   return this->Target->GetFeature(feature, this->ConfigName);
2016 }
2017
2018 //----------------------------------------------------------------------------
2019 bool cmMakefileTargetGenerator::GetFeatureAsBool(const char* feature)
2020 {
2021   return cmSystemTools::IsOn(this->GetFeature(feature));
2022 }
2023
2024 //----------------------------------------------------------------------------
2025 void cmMakefileTargetGenerator::AddFeatureFlags(
2026   std::string& flags, const char* lang
2027   )
2028 {
2029   // Add language-specific flags.
2030   this->LocalGenerator->AddLanguageFlags(flags, lang, this->ConfigName);
2031
2032   if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
2033     {
2034     this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
2035     }
2036 }