1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator3
4 Module: $RCSfile: cmGlobalUnixMakefileGenerator3.cxx,v $
6 Date: $Date: 2009-02-06 16:18:56 $
7 Version: $Revision: 1.132 $
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 =========================================================================*/
18 #include "cmGlobalUnixMakefileGenerator3.h"
19 #include "cmLocalUnixMakefileGenerator3.h"
20 #include "cmMakefile.h"
22 #include "cmGeneratedFileStream.h"
23 #include "cmSourceFile.h"
26 cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
28 // This type of makefile always requires unix style paths
29 this->ForceUnixPaths
= true;
30 this->FindMakeProgramFile
= "CMakeUnixFindMake.cmake";
31 this->ToolSupportsColor
= true;
32 this->ForceVerboseMakefiles
= false;
35 this->UseLinkScript
= false;
37 this->UseLinkScript
= true;
41 void cmGlobalUnixMakefileGenerator3
42 ::EnableLanguage(std::vector
<std::string
>const& languages
,
46 this->cmGlobalGenerator::EnableLanguage(languages
, mf
, optional
);
48 for(std::vector
<std::string
>::const_iterator l
= languages
.begin();
49 l
!= languages
.end(); ++l
)
55 const char* lang
= l
->c_str();
56 std::string langComp
= "CMAKE_";
58 langComp
+= "_COMPILER";
60 if(!mf
->GetDefinition(langComp
.c_str()))
64 cmSystemTools::Error(langComp
.c_str(),
65 " not set, after EnableLanguage");
69 const char* name
= mf
->GetRequiredDefinition(langComp
.c_str());
70 if(!cmSystemTools::FileIsFullPath(name
))
72 path
= cmSystemTools::FindProgram(name
);
78 if((path
.size() == 0 || !cmSystemTools::FileExists(path
.c_str()))
81 std::string message
= "your ";
83 message
+= " compiler: \"";
85 message
+= "\" was not found. Please set ";
87 message
+= " to a valid compiler path or name.";
88 cmSystemTools::Error(message
.c_str());
91 std::string doc
= lang
;
93 const char* cname
= this->GetCMakeInstance()->
94 GetCacheManager()->GetCacheValue(langComp
.c_str());
95 std::string changeVars
;
96 if(cname
&& (path
!= cname
) && (optional
==false))
99 this->GetCMakeInstance()->GetProperty(
100 "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
106 changeVars
+= langComp
;
109 this->GetCMakeInstance()->SetProperty(
110 "__CMAKE_DELETE_CACHE_CHANGE_VARS_",
113 mf
->AddCacheDefinition(langComp
.c_str(), path
.c_str(),
114 doc
.c_str(), cmCacheManager::FILEPATH
);
118 ///! Create a local generator appropriate to this Global Generator
119 cmLocalGenerator
*cmGlobalUnixMakefileGenerator3::CreateLocalGenerator()
121 cmLocalGenerator
* lg
= new cmLocalUnixMakefileGenerator3
;
122 lg
->SetGlobalGenerator(this);
126 //----------------------------------------------------------------------------
127 void cmGlobalUnixMakefileGenerator3
128 ::GetDocumentation(cmDocumentationEntry
& entry
) const
130 entry
.Name
= this->GetName();
131 entry
.Brief
= "Generates standard UNIX makefiles.";
133 "A hierarchy of UNIX makefiles is generated into the build tree. Any "
134 "standard UNIX-style make program can build the project through the "
135 "default make target. A \"make install\" target is also provided.";
138 //----------------------------------------------------------------------------
139 void cmGlobalUnixMakefileGenerator3::Generate()
141 // first do superclass method
142 this->cmGlobalGenerator::Generate();
144 // initialize progress
146 unsigned long total
= 0;
147 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
149 cmLocalUnixMakefileGenerator3
*lg
=
150 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[i
]);
151 total
+= lg
->GetNumberOfProgressActions();
154 // write each target's progress.make this loop is done twice. Bascially the
155 // Generate pass counts all the actions, the first loop below determines
156 // how many actions have progress updates for each target and writes to
157 // corrrect variable values for everything except the all targets. The
158 // second loop actually writes out correct values for the all targets as
159 // well. This is because the all targets require more information that is
160 // computed in the first loop.
161 unsigned long current
= 0;
162 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
164 cmLocalUnixMakefileGenerator3
*lg
=
165 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[i
]);
166 lg
->WriteProgressVariables(total
,current
);
168 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
170 cmLocalUnixMakefileGenerator3
*lg
=
171 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[i
]);
172 lg
->WriteAllProgressVariable();
175 // write the main makefile
176 this->WriteMainMakefile2();
177 this->WriteMainCMakefile();
180 void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
182 // Open the output file. This should not be copy-if-different
183 // because the check-build-system step compares the makefile time to
184 // see if the build system must be regenerated.
185 std::string makefileName
=
186 this->GetCMakeInstance()->GetHomeOutputDirectory();
187 makefileName
+= cmake::GetCMakeFilesDirectory();
188 makefileName
+= "/Makefile2";
189 cmGeneratedFileStream
makefileStream(makefileName
.c_str());
195 // get a local generator for some useful methods
196 cmLocalUnixMakefileGenerator3
*lg
=
197 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[0]);
199 // Write the do not edit header.
200 lg
->WriteDisclaimer(makefileStream
);
202 // Write the main entry point target. This must be the VERY first
203 // target so that make with no arguments will run it.
204 // Just depend on the all target to drive the build.
205 std::vector
<std::string
> depends
;
206 std::vector
<std::string
> no_commands
;
207 depends
.push_back("all");
210 lg
->WriteMakeRule(makefileStream
,
211 "Default target executed when no arguments are "
219 // The all and preinstall rules might never have any dependencies
221 if(this->EmptyRuleHackDepends
!= "")
223 depends
.push_back(this->EmptyRuleHackDepends
);
226 // Write and empty all:
227 lg
->WriteMakeRule(makefileStream
,
228 "The main recursive all target", "all",
229 depends
, no_commands
, true);
231 // Write an empty preinstall:
232 lg
->WriteMakeRule(makefileStream
,
233 "The main recursive preinstall target", "preinstall",
234 depends
, no_commands
, true);
236 // Write out the "special" stuff
237 lg
->WriteSpecialTargetsTop(makefileStream
);
239 // write the target convenience rules
241 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
244 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[i
]);
245 this->WriteConvenienceRules2(makefileStream
,lg
);
248 lg
= static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[0]);
249 lg
->WriteSpecialTargetsBottom(makefileStream
);
253 //----------------------------------------------------------------------------
254 void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
256 // Open the output file. This should not be copy-if-different
257 // because the check-build-system step compares the makefile time to
258 // see if the build system must be regenerated.
259 std::string cmakefileName
=
260 this->GetCMakeInstance()->GetHomeOutputDirectory();
261 cmakefileName
+= cmake::GetCMakeFilesDirectory();
262 cmakefileName
+= "/Makefile.cmake";
263 cmGeneratedFileStream
cmakefileStream(cmakefileName
.c_str());
269 std::string makefileName
=
270 this->GetCMakeInstance()->GetHomeOutputDirectory();
271 makefileName
+= "/Makefile";
273 // get a local generator for some useful methods
274 cmLocalUnixMakefileGenerator3
*lg
=
275 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[0]);
277 // Write the do not edit header.
278 lg
->WriteDisclaimer(cmakefileStream
);
280 // Save the generator name
282 << "# The generator used is:\n"
283 << "SET(CMAKE_DEPENDS_GENERATOR \"" << this->GetName() << "\")\n\n";
285 // for each cmMakefile get its list of dependencies
286 std::vector
<std::string
> lfiles
;
287 for (unsigned int i
= 0; i
< this->LocalGenerators
.size(); ++i
)
290 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[i
]);
292 // Get the list of files contributing to this generation step.
293 lfiles
.insert(lfiles
.end(),lg
->GetMakefile()->GetListFiles().begin(),
294 lg
->GetMakefile()->GetListFiles().end());
296 // Sort the list and remove duplicates.
297 std::sort(lfiles
.begin(), lfiles
.end(), std::less
<std::string
>());
298 std::vector
<std::string
>::iterator new_end
=
299 std::unique(lfiles
.begin(),lfiles
.end());
300 lfiles
.erase(new_end
, lfiles
.end());
302 // reset lg to the first makefile
303 lg
= static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[0]);
305 // Build the path to the cache file.
306 std::string cache
= this->GetCMakeInstance()->GetHomeOutputDirectory();
307 cache
+= "/CMakeCache.txt";
309 // Save the list to the cmake file.
311 << "# The top level Makefile was generated from the following files:\n"
312 << "SET(CMAKE_MAKEFILE_DEPENDS\n"
314 << lg
->Convert(cache
.c_str(),
315 cmLocalGenerator::START_OUTPUT
).c_str() << "\"\n";
316 for(std::vector
<std::string
>::const_iterator i
= lfiles
.begin();
317 i
!= lfiles
.end(); ++i
)
321 << lg
->Convert(i
->c_str(), cmLocalGenerator::START_OUTPUT
).c_str()
327 // Build the path to the cache check file.
328 std::string check
= this->GetCMakeInstance()->GetHomeOutputDirectory();
329 check
+= cmake::GetCMakeFilesDirectory();
330 check
+= "/cmake.check_cache";
332 // Set the corresponding makefile in the cmake file.
334 << "# The corresponding makefile is:\n"
335 << "SET(CMAKE_MAKEFILE_OUTPUTS\n"
337 << lg
->Convert(makefileName
.c_str(),
338 cmLocalGenerator::START_OUTPUT
).c_str() << "\"\n"
340 << lg
->Convert(check
.c_str(),
341 cmLocalGenerator::START_OUTPUT
).c_str() << "\"\n";
343 // add in all the directory information files
345 for (unsigned int i
= 0; i
< this->LocalGenerators
.size(); ++i
)
348 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[i
]);
349 tmpStr
= lg
->GetMakefile()->GetStartOutputDirectory();
350 tmpStr
+= cmake::GetCMakeFilesDirectory();
351 tmpStr
+= "/CMakeDirectoryInformation.cmake";
352 cmakefileStream
<< " \"" <<
353 lg
->Convert(tmpStr
.c_str(),cmLocalGenerator::HOME_OUTPUT
).c_str()
356 cmakefileStream
<< " )\n\n";
358 // CMake must rerun if a byproduct is missing.
361 << "# Byproducts of CMake generate step:\n"
362 << "SET(CMAKE_MAKEFILE_PRODUCTS\n";
363 const std::vector
<std::string
>& outfiles
=
364 lg
->GetMakefile()->GetOutputFiles();
365 for(std::vector
<std::string
>::const_iterator k
= outfiles
.begin();
366 k
!= outfiles
.end(); ++k
)
368 cmakefileStream
<< " \"" <<
369 lg
->Convert(k
->c_str(),cmLocalGenerator::HOME_OUTPUT
).c_str()
372 cmakefileStream
<< " )\n\n";
375 this->WriteMainCMakefileLanguageRules(cmakefileStream
,
376 this->LocalGenerators
);
379 void cmGlobalUnixMakefileGenerator3
380 ::WriteMainCMakefileLanguageRules(cmGeneratedFileStream
& cmakefileStream
,
381 std::vector
<cmLocalGenerator
*> &lGenerators
384 cmLocalUnixMakefileGenerator3
*lg
;
386 // now list all the target info files
388 << "# Dependency information for all targets:\n";
390 << "SET(CMAKE_DEPEND_INFO_FILES\n";
391 for (unsigned int i
= 0; i
< lGenerators
.size(); ++i
)
393 lg
= static_cast<cmLocalUnixMakefileGenerator3
*>(lGenerators
[i
]);
394 // for all of out targets
395 for (cmTargets::iterator l
= lg
->GetMakefile()->GetTargets().begin();
396 l
!= lg
->GetMakefile()->GetTargets().end(); l
++)
398 if((l
->second
.GetType() == cmTarget::EXECUTABLE
) ||
399 (l
->second
.GetType() == cmTarget::STATIC_LIBRARY
) ||
400 (l
->second
.GetType() == cmTarget::SHARED_LIBRARY
) ||
401 (l
->second
.GetType() == cmTarget::MODULE_LIBRARY
) ||
402 (l
->second
.GetType() == cmTarget::UTILITY
))
404 std::string tname
= lg
->GetRelativeTargetDirectory(l
->second
);
405 tname
+= "/DependInfo.cmake";
406 cmSystemTools::ConvertToUnixSlashes(tname
);
407 cmakefileStream
<< " \"" << tname
.c_str() << "\"\n";
411 cmakefileStream
<< " )\n";
414 //----------------------------------------------------------------------------
416 cmGlobalUnixMakefileGenerator3
417 ::WriteDirectoryRule2(std::ostream
& ruleFileStream
,
418 cmLocalUnixMakefileGenerator3
* lg
,
419 const char* pass
, bool check_all
,
422 // Get the relative path to the subdirectory from the top.
423 std::string makeTarget
= lg
->GetMakefile()->GetStartOutputDirectory();
427 // The directory-level rule should depend on the target-level rules
428 // for all targets in the directory.
429 std::vector
<std::string
> depends
;
430 for(cmTargets::iterator l
= lg
->GetMakefile()->GetTargets().begin();
431 l
!= lg
->GetMakefile()->GetTargets().end(); ++l
)
433 if((l
->second
.GetType() == cmTarget::EXECUTABLE
) ||
434 (l
->second
.GetType() == cmTarget::STATIC_LIBRARY
) ||
435 (l
->second
.GetType() == cmTarget::SHARED_LIBRARY
) ||
436 (l
->second
.GetType() == cmTarget::MODULE_LIBRARY
) ||
437 (l
->second
.GetType() == cmTarget::UTILITY
))
439 // Add this to the list of depends rules in this directory.
440 if((!check_all
|| !l
->second
.GetPropertyAsBool("EXCLUDE_FROM_ALL")) &&
441 (!check_relink
|| l
->second
.NeedRelinkBeforeInstall()))
443 std::string tname
= lg
->GetRelativeTargetDirectory(l
->second
);
446 depends
.push_back(tname
);
451 // The directory-level rule should depend on the directory-level
452 // rules of the subdirectories.
453 for(std::vector
<cmLocalGenerator
*>::iterator sdi
=
454 lg
->GetChildren().begin(); sdi
!= lg
->GetChildren().end(); ++sdi
)
456 cmLocalUnixMakefileGenerator3
* slg
=
457 static_cast<cmLocalUnixMakefileGenerator3
*>(*sdi
);
458 std::string subdir
= slg
->GetMakefile()->GetStartOutputDirectory();
461 depends
.push_back(subdir
);
464 // Work-around for makes that drop rules that have no dependencies
466 if(depends
.empty() && this->EmptyRuleHackDepends
!= "")
468 depends
.push_back(this->EmptyRuleHackDepends
);
472 std::string doc
= "Convenience name for \"";
474 doc
+= "\" pass in the directory.";
475 std::vector
<std::string
> no_commands
;
476 lg
->WriteMakeRule(ruleFileStream
, doc
.c_str(),
477 makeTarget
.c_str(), depends
, no_commands
, true);
480 //----------------------------------------------------------------------------
482 cmGlobalUnixMakefileGenerator3
483 ::WriteDirectoryRules2(std::ostream
& ruleFileStream
,
484 cmLocalUnixMakefileGenerator3
* lg
)
486 // Only subdirectories need these rules.
492 // Begin the directory-level rules section.
493 std::string dir
= lg
->GetMakefile()->GetStartOutputDirectory();
494 dir
= lg
->Convert(dir
.c_str(), cmLocalGenerator::HOME_OUTPUT
,
495 cmLocalGenerator::MAKEFILE
);
496 lg
->WriteDivider(ruleFileStream
);
498 << "# Directory level rules for directory "
501 // Write directory-level rules for "all".
502 this->WriteDirectoryRule2(ruleFileStream
, lg
, "all", true, false);
504 // Write directory-level rules for "clean".
505 this->WriteDirectoryRule2(ruleFileStream
, lg
, "clean", false, false);
507 // Write directory-level rules for "preinstall".
508 this->WriteDirectoryRule2(ruleFileStream
, lg
, "preinstall", true, true);
512 std::string cmGlobalUnixMakefileGenerator3
513 ::GenerateBuildCommand(const char* makeProgram
, const char *projectName
,
514 const char* additionalOptions
, const char *targetName
,
515 const char* config
, bool ignoreErrors
, bool fast
)
517 // Project name and config are not used yet.
521 std::string makeCommand
=
522 cmSystemTools::ConvertToUnixOutputPath(makeProgram
);
524 // Since we have full control over the invocation of nmake, let us
526 if ( strcmp(this->GetName(), "NMake Makefiles") == 0 )
528 makeCommand
+= " /NOLOGO ";
532 makeCommand
+= " -i";
534 if ( additionalOptions
)
537 makeCommand
+= additionalOptions
;
539 if ( targetName
&& strlen(targetName
))
541 cmLocalUnixMakefileGenerator3
*lg
;
542 if (this->LocalGenerators
.size())
544 lg
= static_cast<cmLocalUnixMakefileGenerator3
*>
545 (this->LocalGenerators
[0]);
549 lg
= static_cast<cmLocalUnixMakefileGenerator3
*>
550 (this->CreateLocalGenerator());
551 // set the Start directories
552 lg
->GetMakefile()->SetStartDirectory
553 (this->CMakeInstance
->GetStartDirectory());
554 lg
->GetMakefile()->SetStartOutputDirectory
555 (this->CMakeInstance
->GetStartOutputDirectory());
556 lg
->GetMakefile()->MakeStartDirectoriesCurrent();
559 makeCommand
+= " \"";
560 std::string tname
= targetName
;
565 tname
= lg
->Convert(tname
.c_str(),cmLocalGenerator::HOME_OUTPUT
,
566 cmLocalGenerator::MAKEFILE
);
567 makeCommand
+= tname
.c_str();
569 if (!this->LocalGenerators
.size())
577 //----------------------------------------------------------------------------
579 cmGlobalUnixMakefileGenerator3
580 ::WriteConvenienceRules(std::ostream
& ruleFileStream
,
581 std::set
<cmStdString
> &emitted
)
583 std::vector
<std::string
> depends
;
584 std::vector
<std::string
> commands
;
586 depends
.push_back("cmake_check_build_system");
588 // write the target convenience rules
590 cmLocalUnixMakefileGenerator3
*lg
;
591 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
593 lg
= static_cast<cmLocalUnixMakefileGenerator3
*>
594 (this->LocalGenerators
[i
]);
595 // for each target Generate the rule files for each target.
596 cmTargets
& targets
= lg
->GetMakefile()->GetTargets();
597 for(cmTargets::iterator t
= targets
.begin(); t
!= targets
.end(); ++t
)
599 // Don't emit the same rule twice (e.g. two targets with the same
601 if(t
->second
.GetName() &&
602 strlen(t
->second
.GetName()) &&
603 emitted
.insert(t
->second
.GetName()).second
&&
604 // Handle user targets here. Global targets are handled in
605 // the local generator on a per-directory basis.
606 ((t
->second
.GetType() == cmTarget::EXECUTABLE
) ||
607 (t
->second
.GetType() == cmTarget::STATIC_LIBRARY
) ||
608 (t
->second
.GetType() == cmTarget::SHARED_LIBRARY
) ||
609 (t
->second
.GetType() == cmTarget::MODULE_LIBRARY
) ||
610 (t
->second
.GetType() == cmTarget::UTILITY
)))
612 // Add a rule to build the target by name.
613 lg
->WriteDivider(ruleFileStream
);
615 << "# Target rules for targets named "
616 << t
->second
.GetName() << "\n\n";
620 std::string tmp
= cmake::GetCMakeFilesDirectoryPostSlash();
622 commands
.push_back(lg
->GetRecursiveMakeCall
623 (tmp
.c_str(),t
->second
.GetName()));
625 depends
.push_back("cmake_check_build_system");
626 lg
->WriteMakeRule(ruleFileStream
,
627 "Build rule for target.",
628 t
->second
.GetName(), depends
, commands
,
631 // Add a fast rule to build the target
632 std::string localName
= lg
->GetRelativeTargetDirectory(t
->second
);
633 std::string makefileName
;
634 makefileName
= localName
;
635 makefileName
+= "/build.make";
638 std::string makeTargetName
= localName
;
639 makeTargetName
+= "/build";
640 localName
= t
->second
.GetName();
641 localName
+= "/fast";
642 commands
.push_back(lg
->GetRecursiveMakeCall
643 (makefileName
.c_str(), makeTargetName
.c_str()));
644 lg
->WriteMakeRule(ruleFileStream
, "fast build rule for target.",
645 localName
.c_str(), depends
, commands
, true);
647 // Add a local name for the rule to relink the target before
649 if(t
->second
.NeedRelinkBeforeInstall())
651 makeTargetName
= lg
->GetRelativeTargetDirectory(t
->second
);
652 makeTargetName
+= "/preinstall";
653 localName
= t
->second
.GetName();
654 localName
+= "/preinstall";
657 commands
.push_back(lg
->GetRecursiveMakeCall
658 (makefileName
.c_str(), makeTargetName
.c_str()));
659 lg
->WriteMakeRule(ruleFileStream
,
660 "Manual pre-install relink rule for target.",
661 localName
.c_str(), depends
, commands
, true);
669 //----------------------------------------------------------------------------
671 cmGlobalUnixMakefileGenerator3
672 ::WriteConvenienceRules2(std::ostream
& ruleFileStream
,
673 cmLocalUnixMakefileGenerator3
*lg
)
675 std::vector
<std::string
> depends
;
676 std::vector
<std::string
> commands
;
677 std::string localName
;
678 std::string makeTargetName
;
681 // write the directory level rules for this local gen
682 this->WriteDirectoryRules2(ruleFileStream
,lg
);
684 depends
.push_back("cmake_check_build_system");
686 // for each target Generate the rule files for each target.
687 cmTargets
& targets
= lg
->GetMakefile()->GetTargets();
688 for(cmTargets::iterator t
= targets
.begin(); t
!= targets
.end(); ++t
)
690 if (t
->second
.GetName()
691 && strlen(t
->second
.GetName())
692 && ((t
->second
.GetType() == cmTarget::EXECUTABLE
)
693 || (t
->second
.GetType() == cmTarget::STATIC_LIBRARY
)
694 || (t
->second
.GetType() == cmTarget::SHARED_LIBRARY
)
695 || (t
->second
.GetType() == cmTarget::MODULE_LIBRARY
)
696 || (t
->second
.GetType() == cmTarget::UTILITY
)))
698 std::string makefileName
;
699 // Add a rule to build the target by name.
700 localName
= lg
->GetRelativeTargetDirectory(t
->second
);
701 makefileName
= localName
;
702 makefileName
+= "/build.make";
704 bool needRequiresStep
= this->NeedRequiresStep(t
->second
);
706 lg
->WriteDivider(ruleFileStream
);
708 << "# Target rules for target "
709 << localName
<< "\n\n";
712 makeTargetName
= localName
;
713 makeTargetName
+= "/depend";
714 commands
.push_back(lg
->GetRecursiveMakeCall
715 (makefileName
.c_str(),makeTargetName
.c_str()));
717 // add requires if we need it for this generator
718 if (needRequiresStep
)
720 makeTargetName
= localName
;
721 makeTargetName
+= "/requires";
722 commands
.push_back(lg
->GetRecursiveMakeCall
723 (makefileName
.c_str(),makeTargetName
.c_str()));
725 makeTargetName
= localName
;
726 makeTargetName
+= "/build";
727 commands
.push_back(lg
->GetRecursiveMakeCall
728 (makefileName
.c_str(),makeTargetName
.c_str()));
734 std::string progressDir
=
735 lg
->GetMakefile()->GetHomeOutputDirectory();
736 progressDir
+= cmake::GetCMakeFilesDirectory();
738 cmOStringStream progCmd
;
739 progCmd
<< "$(CMAKE_COMMAND) -E cmake_progress_report ";
741 progCmd
<< lg
->Convert(progressDir
.c_str(),
742 cmLocalGenerator::FULL
,
743 cmLocalGenerator::SHELL
);
745 std::vector
<int> &progFiles
= lg
->ProgressFiles
[t
->first
];
746 for (std::vector
<int>::iterator i
= progFiles
.begin();
747 i
!= progFiles
.end(); ++i
)
749 progCmd
<< " " << *i
;
751 commands
.push_back(progCmd
.str());
753 progressDir
= "Built target ";
754 progressDir
+= t
->first
;
755 lg
->AppendEcho(commands
,progressDir
.c_str());
757 this->AppendGlobalTargetDepends(depends
,t
->second
);
758 lg
->WriteMakeRule(ruleFileStream
, "All Build rule for target.",
759 localName
.c_str(), depends
, commands
, true);
761 // add the all/all dependency
762 if(!this->IsExcluded(this->LocalGenerators
[0], t
->second
))
765 depends
.push_back(localName
);
767 lg
->WriteMakeRule(ruleFileStream
, "Include target in all.",
768 "all", depends
, commands
, true);
773 progressDir
= lg
->GetMakefile()->GetHomeOutputDirectory();
774 progressDir
+= cmake::GetCMakeFilesDirectory();
777 // TODO: Convert the total progress count to a make variable.
778 cmOStringStream progCmd
;
779 progCmd
<< "$(CMAKE_COMMAND) -E cmake_progress_start ";
781 progCmd
<< lg
->Convert(progressDir
.c_str(),
782 cmLocalGenerator::FULL
,
783 cmLocalGenerator::SHELL
);
785 std::set
<cmTarget
*> emitted
;
787 << this->GetTargetTotalNumberOfActions(t
->second
,
789 commands
.push_back(progCmd
.str());
791 std::string tmp
= cmake::GetCMakeFilesDirectoryPostSlash();
793 commands
.push_back(lg
->GetRecursiveMakeCall
794 (tmp
.c_str(),localName
.c_str()));
796 cmOStringStream progCmd
;
797 progCmd
<< "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
798 progCmd
<< lg
->Convert(progressDir
.c_str(),
799 cmLocalGenerator::FULL
,
800 cmLocalGenerator::SHELL
);
802 commands
.push_back(progCmd
.str());
805 depends
.push_back("cmake_check_build_system");
806 localName
= lg
->GetRelativeTargetDirectory(t
->second
);
807 localName
+= "/rule";
808 lg
->WriteMakeRule(ruleFileStream
,
809 "Build rule for subdir invocation for target.",
810 localName
.c_str(), depends
, commands
, true);
812 // Add a target with the canonical name (no prefix, suffix or path).
815 depends
.push_back(localName
);
816 lg
->WriteMakeRule(ruleFileStream
, "Convenience name for target.",
817 t
->second
.GetName(), depends
, commands
, true);
819 // Add rules to prepare the target for installation.
820 if(t
->second
.NeedRelinkBeforeInstall())
822 localName
= lg
->GetRelativeTargetDirectory(t
->second
);
823 localName
+= "/preinstall";
826 commands
.push_back(lg
->GetRecursiveMakeCall
827 (makefileName
.c_str(), localName
.c_str()));
828 lg
->WriteMakeRule(ruleFileStream
,
829 "Pre-install relink rule for target.",
830 localName
.c_str(), depends
, commands
, true);
832 if(!this->IsExcluded(this->LocalGenerators
[0], t
->second
))
835 depends
.push_back(localName
);
837 lg
->WriteMakeRule(ruleFileStream
, "Prepare target for install.",
838 "preinstall", depends
, commands
, true);
842 // add the clean rule
843 localName
= lg
->GetRelativeTargetDirectory(t
->second
);
844 makeTargetName
= localName
;
845 makeTargetName
+= "/clean";
848 commands
.push_back(lg
->GetRecursiveMakeCall
849 (makefileName
.c_str(), makeTargetName
.c_str()));
850 lg
->WriteMakeRule(ruleFileStream
, "clean rule for target.",
851 makeTargetName
.c_str(), depends
, commands
, true);
853 depends
.push_back(makeTargetName
);
854 lg
->WriteMakeRule(ruleFileStream
, "clean rule for target.",
855 "clean", depends
, commands
, true);
860 //----------------------------------------------------------------------------
861 int cmGlobalUnixMakefileGenerator3
862 ::GetTargetTotalNumberOfActions(cmTarget
&target
,
863 std::set
<cmTarget
*> &emitted
)
865 // do not double count
868 if(emitted
.insert(&target
).second
)
870 cmLocalUnixMakefileGenerator3
*lg
=
871 static_cast<cmLocalUnixMakefileGenerator3
*>
872 (target
.GetMakefile()->GetLocalGenerator());
873 result
= static_cast<int>(lg
->ProgressFiles
[target
.GetName()].size());
875 TargetDependSet
& depends
= this->GetTargetDirectDepends(target
);
877 TargetDependSet::iterator i
;
878 for (i
= depends
.begin(); i
!= depends
.end(); ++i
)
880 result
+= this->GetTargetTotalNumberOfActions(**i
, emitted
);
887 unsigned long cmGlobalUnixMakefileGenerator3
888 ::GetNumberOfProgressActionsInAll(cmLocalUnixMakefileGenerator3
*lg
)
890 unsigned long result
= 0;
891 std::set
<cmTarget
*> emitted
;
892 std::set
<cmTarget
*>& targets
= this->LocalGeneratorToTargetMap
[lg
];
893 for(std::set
<cmTarget
*>::iterator t
= targets
.begin();
894 t
!= targets
.end(); ++t
)
896 result
+= this->GetTargetTotalNumberOfActions(**t
,emitted
);
902 //----------------------------------------------------------------------------
904 cmGlobalUnixMakefileGenerator3
905 ::AppendGlobalTargetDepends(std::vector
<std::string
>& depends
,
908 TargetDependSet
const& depends_set
= this->GetTargetDirectDepends(target
);
909 for(TargetDependSet::const_iterator i
= depends_set
.begin();
910 i
!= depends_set
.end(); ++i
)
912 // Create the target-level dependency.
913 cmTarget
const* dep
= *i
;
914 cmLocalUnixMakefileGenerator3
* lg3
=
915 static_cast<cmLocalUnixMakefileGenerator3
*>
916 (dep
->GetMakefile()->GetLocalGenerator());
917 std::string tgtName
= lg3
->GetRelativeTargetDirectory(*dep
);
919 depends
.push_back(tgtName
);
923 //----------------------------------------------------------------------------
924 void cmGlobalUnixMakefileGenerator3::WriteHelpRule
925 (std::ostream
& ruleFileStream
, cmLocalUnixMakefileGenerator3
*lg
)
927 // add the help target
929 std::vector
<std::string
> no_depends
;
930 std::vector
<std::string
> commands
;
931 lg
->AppendEcho(commands
,"The following are some of the valid targets "
932 "for this Makefile:");
933 lg
->AppendEcho(commands
,"... all (the default if no target is provided)");
934 lg
->AppendEcho(commands
,"... clean");
935 lg
->AppendEcho(commands
,"... depend");
937 // Keep track of targets already listed.
938 std::set
<cmStdString
> emittedTargets
;
940 // for each local generator
942 cmLocalUnixMakefileGenerator3
*lg2
;
943 for (i
= 0; i
< this->LocalGenerators
.size(); ++i
)
946 static_cast<cmLocalUnixMakefileGenerator3
*>(this->LocalGenerators
[i
]);
947 // for the passed in makefile or if this is the top Makefile wripte out
949 if (lg2
== lg
|| !lg
->GetParent())
951 // for each target Generate the rule files for each target.
952 cmTargets
& targets
= lg2
->GetMakefile()->GetTargets();
953 for(cmTargets::iterator t
= targets
.begin(); t
!= targets
.end(); ++t
)
955 if((t
->second
.GetType() == cmTarget::EXECUTABLE
) ||
956 (t
->second
.GetType() == cmTarget::STATIC_LIBRARY
) ||
957 (t
->second
.GetType() == cmTarget::SHARED_LIBRARY
) ||
958 (t
->second
.GetType() == cmTarget::MODULE_LIBRARY
) ||
959 (t
->second
.GetType() == cmTarget::GLOBAL_TARGET
) ||
960 (t
->second
.GetType() == cmTarget::UTILITY
))
962 if(emittedTargets
.insert(t
->second
.GetName()).second
)
965 path
+= t
->second
.GetName();
966 lg
->AppendEcho(commands
,path
.c_str());
972 std::vector
<cmStdString
> const& localHelp
= lg
->GetLocalHelp();
973 for(std::vector
<cmStdString
>::const_iterator o
= localHelp
.begin();
974 o
!= localHelp
.end(); ++o
)
978 lg
->AppendEcho(commands
, path
.c_str());
980 lg
->WriteMakeRule(ruleFileStream
, "Help Target",
982 no_depends
, commands
, true);
983 ruleFileStream
<< "\n\n";
987 bool cmGlobalUnixMakefileGenerator3
988 ::NeedRequiresStep(cmTarget
const& target
)
990 std::set
<cmStdString
> languages
;
991 target
.GetLanguages(languages
);
992 for(std::set
<cmStdString
>::const_iterator l
= languages
.begin();
993 l
!= languages
.end(); ++l
)
995 std::string var
= "CMAKE_NEEDS_REQUIRES_STEP_";
998 if(target
.GetMakefile()->GetDefinition(var
.c_str()))