diff --git a/Source/cmLocalUnixMakefileGenerator2.cxx b/Source/cmLocalUnixMakefileGenerator2.cxx index d222b4b9c..fda2e0adf 100644 --- a/Source/cmLocalUnixMakefileGenerator2.cxx +++ b/Source/cmLocalUnixMakefileGenerator2.cxx @@ -46,6 +46,10 @@ // TODO: Add "help" target. // TODO: Identify remaining relative path violations. // TODO: Need test for separate executable/library output path. +// TODO: Add registered files for cleaning: +// $(GENERATED_QT_FILES) $(GENERATED_FLTK_FILES) +// What about cleaning custom command outputs? + //---------------------------------------------------------------------------- cmLocalUnixMakefileGenerator2::cmLocalUnixMakefileGenerator2() @@ -91,7 +95,6 @@ void cmLocalUnixMakefileGenerator2::Generate(bool fromTheTop) const cmTargets& targets = m_Makefile->GetTargets(); for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t) { - // TODO: Dispatch generation of each target type. if((t->second.GetType() == cmTarget::EXECUTABLE) || (t->second.GetType() == cmTarget::STATIC_LIBRARY) || (t->second.GetType() == cmTarget::SHARED_LIBRARY) || @@ -153,19 +156,16 @@ void cmLocalUnixMakefileGenerator2::GenerateMakefile() this->WriteAllRules(makefileStream); // Write dependency generation rules. - this->WritePassRules(makefileStream, "depend", - "Build dependencies for this directory.", - m_DependTargets); + this->WritePassRules(makefileStream, "depend"); + this->WriteLocalRule(makefileStream, "depend", 0); // Write main build rules. - this->WritePassRules(makefileStream, "build", - "Build targets in this directory.", - m_BuildTargets); + this->WritePassRules(makefileStream, "build"); + this->WriteLocalRule(makefileStream, "build", 0); // Write clean rules. - this->WritePassRules(makefileStream, "clean", - "Clean targets in this directory.", - m_CleanTargets); + this->WritePassRules(makefileStream, "clean"); + this->WriteLocalCleanRule(makefileStream); // Write include statements to get rules for this directory. this->WriteRuleFileIncludes(makefileStream); @@ -762,7 +762,7 @@ cmLocalUnixMakefileGenerator2 // Add this to the list of build rules in this directory. if(target.IsInAll()) { - m_BuildTargets.push_back(target.GetName()); + this->WriteLocalRule(ruleFileStream, "build", target.GetName()); } } @@ -1168,10 +1168,7 @@ cmLocalUnixMakefileGenerator2 //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator2 -::WritePassRules(std::ostream& makefileStream, - const char* pass, - const char* comment, - const std::vector& depends) +::WritePassRules(std::ostream& makefileStream, const char* pass) { // Write section header. this->WriteDivider(makefileStream); @@ -1183,17 +1180,6 @@ cmLocalUnixMakefileGenerator2 std::string passLocal = pass; passLocal += ".local"; this->WriteDriverRules(makefileStream, pass, passLocal.c_str()); - - // If there are no dependencies, use empty commands. - std::vector commands; - if(depends.empty()) - { - commands = m_EmptyCommands; - } - - // Write the rule. - this->WriteMakeRule(makefileStream, comment, 0, passLocal.c_str(), - depends, commands); } //---------------------------------------------------------------------------- @@ -1392,6 +1378,36 @@ cmLocalUnixMakefileGenerator2 tgt.c_str(), depends, commands); } +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator2 +::WriteLocalRule(std::ostream& ruleFileStream, const char* pass, + const char* dependency) +{ + std::string localTarget = pass; + localTarget += ".local"; + if(dependency) + { + std::string comment = "Include this target in the \""; + comment += pass; + comment += "\" pass for this directory."; + std::vector depends; + std::vector no_commands; + depends.push_back(dependency); + this->WriteMakeRule(ruleFileStream, comment.c_str(), 0, + localTarget.c_str(), depends, no_commands); + } + else + { + std::vector no_depends; + std::vector commands = m_EmptyCommands; + this->WriteMakeRule(ruleFileStream, + "Local rule is empty by default. " + "Targets may add dependencies.", 0, + localTarget.c_str(), no_depends, commands); + } +} + //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator2 @@ -1970,10 +1986,10 @@ cmLocalUnixMakefileGenerator2 this->WriteMakeRule(ruleFileStream, 0, depEcho.c_str(), depTarget.c_str(), depends, no_commands); - // Add this to the list of depend rules in this directory. + // Add this to the list of depends rules in this directory. if(target.IsInAll()) { - m_DependTargets.push_back(depTarget); + this->WriteLocalRule(ruleFileStream, "depend", depTarget.c_str()); } } @@ -1987,8 +2003,6 @@ cmLocalUnixMakefileGenerator2 std::vector no_depends; std::vector commands; - // TODO: Add registered files for cleaning. - // Construct the clean target name. std::string cleanTarget = target.GetName(); cleanTarget += ".clean"; @@ -2010,7 +2024,7 @@ cmLocalUnixMakefileGenerator2 // Add this to the list of clean rules in this directory. if(target.IsInAll()) { - m_CleanTargets.push_back(cleanTarget); + this->WriteLocalRule(ruleFileStream, "clean", cleanTarget.c_str()); } } @@ -2023,6 +2037,7 @@ cmLocalUnixMakefileGenerator2 // Create the driving make target. std::string targetRequires = target.GetName(); targetRequires += ".requires"; + std::string comment = "Directory-level driver rulue for this target."; if(provides_requires.empty()) { // No provides-requires mode objects in this target. Anything @@ -2030,7 +2045,7 @@ cmLocalUnixMakefileGenerator2 std::vector no_commands; std::vector depends; depends.push_back(target.GetName()); - this->WriteMakeRule(ruleFileStream, 0, 0, + this->WriteMakeRule(ruleFileStream, comment.c_str(), 0, targetRequires.c_str(), depends, no_commands); } else @@ -2056,9 +2071,10 @@ cmLocalUnixMakefileGenerator2 depends.push_back(*pr); } + // Write the requires rule for this target. std::vector commands; commands.push_back(this->GetRecursiveMakeCall(targetProvides.c_str())); - this->WriteMakeRule(ruleFileStream, 0, 0, + this->WriteMakeRule(ruleFileStream, comment.c_str(), 0, targetRequires.c_str(), depends, commands); } } @@ -2066,7 +2082,47 @@ cmLocalUnixMakefileGenerator2 // Add this to the list of build rules in this directory. if(target.IsInAll()) { - m_BuildTargets.push_back(targetRequires); + this->WriteLocalRule(ruleFileStream, "build", targetRequires.c_str()); + } +} + +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator2 +::WriteLocalCleanRule(std::ostream& makefileStream) +{ + // Collect a list of extra files to clean in this directory. + std::vector files; + + // Look for files registered for cleaning in this directory. + if(const char* additional_clean_files = + m_Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) + { + cmSystemTools::ExpandListArgument(additional_clean_files, files); + } + + // Write the local clean rule for this directory. + if(files.empty()) + { + // No extra files to clean. Write an empty rule. + this->WriteLocalRule(makefileStream, "clean", 0); + } + else + { + // Have extra files to clean. Write the action to remove them. + std::string remove = "$(CMAKE_COMMAND) -E remove -f"; + for(std::vector::iterator i = files.begin(); + i != files.end(); ++i) + { + remove += " "; + remove += this->ConvertToRelativeOutputPath(i->c_str()); + } + std::vector no_depends; + std::vector commands; + commands.push_back(remove); + this->WriteMakeRule(makefileStream, + "Clean extra files in this directory.", 0, + "clean.local", no_depends, commands); } } diff --git a/Source/cmLocalUnixMakefileGenerator2.h b/Source/cmLocalUnixMakefileGenerator2.h index 2fb3a12d8..7cf9a166c 100644 --- a/Source/cmLocalUnixMakefileGenerator2.h +++ b/Source/cmLocalUnixMakefileGenerator2.h @@ -90,9 +90,7 @@ protected: void WriteSpecialTargetsBottom(std::ostream& makefileStream); void WriteRuleFileIncludes(std::ostream& makefileStream); void WriteAllRules(std::ostream& makefileStream); - void WritePassRules(std::ostream& makefileStream, - const char* pass, const char* comment, - const std::vector& depends); + void WritePassRules(std::ostream& makefileStream, const char* pass); void WriteDriverRules(std::ostream& makefileStream, const char* pass, const char* local1, const char* local2=0); void WriteSubdirRules(std::ostream& makefileStream, const char* pass); @@ -100,6 +98,8 @@ protected: const char* subdir, std::string& last); void WriteSubdirDriverRule(std::ostream& makefileStream, const char* pass, const char* order, const std::string& last); + void WriteLocalRule(std::ostream& ruleFileStream, const char* pass, + const char* dependency); void WriteConvenienceRules(std::ostream& ruleFileStream, const cmTarget& target, const char* targetOutPath); @@ -154,6 +154,7 @@ protected: void WriteTargetRequiresRule(std::ostream& ruleFileStream, const cmTarget& target, const std::vector& provides_requires); + void WriteLocalCleanRule(std::ostream& makefileStream); void WriteCMakeArgument(std::ostream& os, const char* s); std::string GetTargetDirectory(const cmTarget& target); std::string GetSubdirTargetName(const char* pass, const char* subdir); @@ -211,12 +212,6 @@ private: // Set of custom rule files that have been generated. std::set m_CustomRuleFiles; - // List of target-level rules for each pass. These are populated by - // target rule file writing methods. - std::vector m_DependTargets; - std::vector m_BuildTargets; - std::vector m_CleanTargets; - // The prefix required of a path to be converted to a relative path. // No sequence of ../.. will ever go past this path. std::string m_RelativePathTop;