diff options
-rw-r--r-- | Source/cmGlobalUnixMakefileGenerator3.cxx | 325 | ||||
-rw-r--r-- | Source/cmGlobalUnixMakefileGenerator3.h | 14 | ||||
-rw-r--r-- | Source/cmLocalUnixMakefileGenerator3.cxx | 718 | ||||
-rw-r--r-- | Source/cmLocalUnixMakefileGenerator3.h | 236 |
4 files changed, 650 insertions, 643 deletions
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 492e8c9..bca095d 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -91,21 +91,92 @@ void cmGlobalUnixMakefileGenerator3::GetDocumentation(cmDocumentationEntry& entr } //---------------------------------------------------------------------------- +void cmGlobalUnixMakefileGenerator3::Generate() +{ + // first do superclass method + this->cmGlobalGenerator::Generate(); + + // write the main makefile + this->WriteMainMakefile(); + this->WriteMainCMakefile(); + + // now write the support Makefiles + this->WriteDependMakefile(); + this->WriteBuildMakefile(); + this->WriteCleanMakefile(); +} + +void cmGlobalUnixMakefileGenerator3::WriteMainMakefile() +{ + // Open the output file. This should not be copy-if-different + // because the check-build-system step compares the makefile time to + // see if the build system must be regenerated. + std::string makefileName = + this->GetCMakeInstance()->GetHomeOutputDirectory(); + makefileName += "/Makefile"; + cmGeneratedFileStream makefileStream(makefileName.c_str()); + if(!makefileStream) + { + return; + } + + // get a local generator for some useful methods + cmLocalUnixMakefileGenerator3 *lg = + static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]); + + // Write the do not edit header. + lg->WriteDisclaimer(makefileStream); + + // Write the main entry point target. This must be the VERY first + // target so that make with no arguments will run it. + // Just depend on the all target to drive the build. + std::vector<std::string> depends; + std::vector<std::string> no_commands; + depends.push_back("all"); + + // Write the rule. + lg->WriteMakeRule(makefileStream, + "Default target executed when no arguments are " + "given to make.", + "default_target", + depends, + no_commands); + + lg->WriteMakeVariables(makefileStream); + + lg->WriteSpecialTargetsTop(makefileStream); + + this->WriteAllRules(lg,makefileStream); + + // write the target convenience rules + unsigned int i; + for (i = 0; i < m_LocalGenerators.size(); ++i) + { + lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]); + this->WriteConvenienceRules(makefileStream,lg); + } +} + + +//---------------------------------------------------------------------------- void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() { // Open the output file. This should not be copy-if-different // because the check-build-system step compares the makefile time to // see if the build system must be regenerated. - std::string cmakefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); + std::string cmakefileName = + this->GetCMakeInstance()->GetHomeOutputDirectory(); cmakefileName += "/Makefile.cmake"; - std::string makefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); - makefileName += "/Makefile"; cmGeneratedFileStream cmakefileStream(cmakefileName.c_str()); if(!cmakefileStream) { return; } - + + std::string makefileName = + this->GetCMakeInstance()->GetHomeOutputDirectory(); + makefileName += "/Makefile"; + // get a local generator for some useful methods cmLocalUnixMakefileGenerator3 *lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]); @@ -174,12 +245,20 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() << " \"" << this->ConvertToHomeRelativePath(tmpStr.c_str()).c_str() << "\"\n"; } cmakefileStream << " )\n\n"; + + this->WriteMainCMakefileLanguageRules(cmakefileStream); +} +void cmGlobalUnixMakefileGenerator3 +::WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream) +{ + cmLocalUnixMakefileGenerator3 *lg; + // now write all the language stuff // Set the set of files to check for dependency integrity. // loop over all of the local generators to collect this std::set<cmStdString> checkSetLangs; - for (i = 0; i < m_LocalGenerators.size(); ++i) + for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i) { lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]); std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& checkSet = @@ -211,7 +290,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() cmakefileStream << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n"; // now for each local gen get the checkset - for (i = 0; i < m_LocalGenerators.size(); ++i) + for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i) { lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]); // get the check set for this local gen and language @@ -228,90 +307,6 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile() } cmakefileStream << " )\n"; } - -} - -void cmGlobalUnixMakefileGenerator3::WriteMainMakefile() -{ - // Open the output file. This should not be copy-if-different - // because the check-build-system step compares the makefile time to - // see if the build system must be regenerated. - std::string makefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); - makefileName += "/Makefile"; - cmGeneratedFileStream makefileStream(makefileName.c_str()); - if(!makefileStream) - { - return; - } - - // get a local generator for some useful methods - cmLocalUnixMakefileGenerator3 *lg = - static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]); - - // Write the do not edit header. - lg->WriteDisclaimer(makefileStream); - - // Write the main entry point target. This must be the VERY first - // target so that make with no arguments will run it. - // Just depend on the all target to drive the build. - std::vector<std::string> depends; - std::vector<std::string> no_commands; - depends.push_back("all"); - - // Write the rule. - lg->WriteMakeRule(makefileStream, - "Default target executed when no arguments are " - "given to make.", - "default_target", - depends, - no_commands); - - lg->WriteMakeVariables(makefileStream); - - lg->WriteSpecialTargetsTop(makefileStream); - - lg->WriteAllRules(makefileStream); - - // Write special "cmake_check_build_system" target to run cmake with - // the --check-build-system flag. - // Build command to run CMake to check if anything needs regenerating. - std::string cmakefileName = makefileName; - cmakefileName += ".cmake"; - std::string runRule = this->GetCMakeInstance()->GetCacheDefinition("CMAKE_COMMAND"); - runRule += " -H"; - runRule += this->GetCMakeInstance()->GetHomeDirectory(); - runRule += " -B"; - runRule += this->GetCMakeInstance()->GetHomeOutputDirectory(); - runRule += " --check-build-system "; - runRule += lg->ConvertToRelativeOutputPath(cmakefileName.c_str()); - - std::vector<std::string> no_depends; - std::vector<std::string> commands; - commands.push_back(runRule); - lg->WriteMakeRule(makefileStream, - "Special rule to run CMake to check the build system " - "integrity.\n" - "No rule that depends on this can have " - "commands that come from listfiles\n" - "because they might be regenerated.", - "cmake_check_build_system", - no_depends, - commands); - - // write the target convenience rules - unsigned int i; - for (i = 0; i < m_LocalGenerators.size(); ++i) - { - lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]); - lg->WriteConvenienceRules(makefileStream); - } -} - -void cmGlobalUnixMakefileGenerator3::WriteSupportMakefiles() -{ - this->WriteDependMakefile(); - this->WriteBuildMakefile(); - this->WriteCleanMakefile(); } void cmGlobalUnixMakefileGenerator3::WriteDependMakefile() @@ -455,15 +450,149 @@ void cmGlobalUnixMakefileGenerator3::WriteCleanMakefile() } //---------------------------------------------------------------------------- -void cmGlobalUnixMakefileGenerator3::Generate() +void cmGlobalUnixMakefileGenerator3 +::WriteAllRules(cmLocalUnixMakefileGenerator3 *lg, + std::ostream& makefileStream) { - // first do superclass method - this->cmGlobalGenerator::Generate(); + // Write section header. + lg->WriteDivider(makefileStream); + makefileStream + << "# Rules to build dependencies and targets.\n" + << "\n"; - // write the main makefile - this->WriteMainMakefile(); - this->WriteMainCMakefile(); + std::vector<std::string> depends; + std::vector<std::string> commands; - // now write the support Makefiles - this->WriteSupportMakefiles(); + // Check the build system in this directory. + depends.push_back("cmake_check_build_system"); + + commands.push_back(this->GetRecursiveMakeCall("depend.make",0)); + commands.push_back(this->GetRecursiveMakeCall("build.make",0)); + + // Write the rule. + lg->WriteMakeRule(makefileStream, "The main all target", "all", depends, commands); + + // write the clean + commands.clear(); + commands.push_back(this->GetRecursiveMakeCall("clean.make",0)); + lg->WriteMakeRule(makefileStream, "default clean target", "clean", depends, commands); + + + // Write special "cmake_check_build_system" target to run cmake with + // the --check-build-system flag. + // Build command to run CMake to check if anything needs regenerating. + std::string cmakefileName = this->GetCMakeInstance()->GetHomeOutputDirectory(); + cmakefileName += "/Makefile.cmake"; + std::string runRule = this->GetCMakeInstance()->GetCacheDefinition("CMAKE_COMMAND"); + runRule += " -H"; + runRule += this->GetCMakeInstance()->GetHomeDirectory(); + runRule += " -B"; + runRule += this->GetCMakeInstance()->GetHomeOutputDirectory(); + runRule += " --check-build-system "; + runRule += lg->ConvertToRelativeOutputPath(cmakefileName.c_str()); + + std::vector<std::string> no_depends; + commands.clear(); + commands.push_back(runRule); + lg->WriteMakeRule(makefileStream, + "Special rule to run CMake to check the build system " + "integrity.\n" + "No rule that depends on this can have " + "commands that come from listfiles\n" + "because they might be regenerated.", + "cmake_check_build_system", + no_depends, + commands); } + + +//---------------------------------------------------------------------------- +std::string +cmGlobalUnixMakefileGenerator3 +::GetRecursiveMakeCall(const char *Makefile, const char* tgt) +{ + cmLocalUnixMakefileGenerator3 *lg = + static_cast<cmLocalUnixMakefileGenerator3*>(m_LocalGenerators[0]); + + // Call make on the given file. + std::string cmd; + cmd += "$(MAKE) -f "; + cmd += Makefile; + cmd += " "; + + // Pass down verbosity level. + if(lg->GetMakeSilentFlag().size()) + { + cmd += lg->GetMakeSilentFlag(); + cmd += " "; + } + + // Most unix makes will pass the command line flags to make down to + // sub-invoked makes via an environment variable. However, some + // makes do not support that, so you have to pass the flags + // explicitly. + if(lg->GetPassMakeflags()) + { + cmd += "-$(MAKEFLAGS) "; + } + + // Add the target. + if (tgt && tgt[0] != '\0') + { + cmd += tgt; + } + return cmd; +} + +//---------------------------------------------------------------------------- +void +cmGlobalUnixMakefileGenerator3 +::WriteConvenienceRules(std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3 *lg) +{ + std::vector<std::string> depends; + std::vector<std::string> tgt_depends; + std::vector<std::string> commands; + + depends.push_back("cmake_check_build_system"); + + // for each target + // Generate the rule files for each target. + const cmTargets& targets = lg->GetMakefile()->GetTargets(); + std::string localName; + std::string makeTargetName; + for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t) + { + if((t->second.GetType() == cmTarget::EXECUTABLE) || + (t->second.GetType() == cmTarget::STATIC_LIBRARY) || + (t->second.GetType() == cmTarget::SHARED_LIBRARY) || + (t->second.GetType() == cmTarget::MODULE_LIBRARY)) + { + // Add a rule to build the target by name. + localName = lg->GetRelativeTargetDirectory(t->second); + + commands.clear(); + makeTargetName = localName; + makeTargetName += "/depend"; + commands.push_back(this->GetRecursiveMakeCall("depend.make",makeTargetName.c_str())); + makeTargetName = localName; + makeTargetName += "/build"; + commands.push_back(this->GetRecursiveMakeCall("build.make",makeTargetName.c_str())); + + // Write the rule. + lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", + localName.c_str(), depends, commands); + + // Add a target with the canonical name (no prefix, suffix or path). + if(localName != t->second.GetName()) + { + commands.clear(); + tgt_depends.clear(); + tgt_depends.push_back(localName); + lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", + t->second.GetName(), tgt_depends, commands); + } + } + } +} + + diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 8b9c7ef..5fb62b1 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -19,6 +19,9 @@ #include "cmGlobalGenerator.h" +class cmGeneratedFileStream; +class cmLocalUnixMakefileGenerator3; + /** \class cmGlobalUnixMakefileGenerator3 * \brief Write a Unix makefiles. * @@ -60,8 +63,15 @@ protected: void WriteDependMakefile(); void WriteBuildMakefile(); void WriteCleanMakefile(); - void WriteSupportMakefiles(); - + void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream); + void WriteAllRules(cmLocalUnixMakefileGenerator3 *lg, + std::ostream& makefileStream); + + /** used to create a recursive make call */ + std::string GetRecursiveMakeCall(const char *makefile, const char* tgt); + + void WriteConvenienceRules(std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3 *); + }; #endif diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 88bcb10..43dd5c1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -34,9 +34,6 @@ #include <memory> // auto_ptr #include <queue> -// TODO: Convert makefile name to a runtime switch. -#define CMLUMG_MAKEFILE_NAME "Makefile" - // TODO: Add "help" target. // TODO: Identify remaining relative path violations. // TODO: Need test for separate executable/library output path. @@ -58,16 +55,6 @@ cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() } //---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::SetEmptyCommand(const char* cmd) -{ - m_EmptyCommands.clear(); - if(cmd) - { - m_EmptyCommands.push_back(cmd); - } -} - -//---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::Generate() { // Setup our configuration variables for this directory. @@ -82,20 +69,69 @@ void cmLocalUnixMakefileGenerator3::Generate() (t->second.GetType() == cmTarget::SHARED_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY)) { - this->GenerateTargetRuleFile(t->second); + this->WriteTargetRuleFiles(t->second); } else if(t->second.GetType() == cmTarget::UTILITY) { - this->GenerateUtilityRuleFile(t->second); + this->WriteUtilityRuleFiles(t->second); } } this->WriteCustomCommands(); - // Generate the cmake file with information for this directory. - this->GenerateDirectoryInformationFile(); + // Write the cmake file with information for this directory. + this->WriteDirectoryInformationFile(); +} + + +//---------------------------------------------------------------------------- +void cmLocalUnixMakefileGenerator3::ConfigureOutputPaths() +{ + // Format the library and executable output paths. + if(const char* libOut = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH")) + { + m_LibraryOutputPath = libOut; + this->FormatOutputPath(m_LibraryOutputPath, "LIBRARY"); + } + if(const char* exeOut = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")) + { + m_ExecutableOutputPath = exeOut; + this->FormatOutputPath(m_ExecutableOutputPath, "EXECUTABLE"); + } +} + +//---------------------------------------------------------------------------- +void cmLocalUnixMakefileGenerator3::FormatOutputPath(std::string& path, + const char* name) +{ + if(!path.empty()) + { + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + path = + cmSystemTools::CollapseFullPath(path.c_str(), + m_Makefile->GetStartOutputDirectory()); + + // Add a trailing slash for easy appending later. + if(path.empty() || path[path.size()-1] != '/') + { + path += "/"; + } + + // Make sure the output path exists on disk. + if(!cmSystemTools::MakeDirectory(path.c_str())) + { + cmSystemTools::Error("Error failed to create ", + name, "_OUTPUT_PATH directory:", path.c_str()); + } + + // Add this as a link directory automatically. + m_Makefile->AddLinkDirectory(path.c_str()); + } } + void cmLocalUnixMakefileGenerator3::WriteCustomCommands() { // Generate the rule files for each custom command. @@ -135,7 +171,6 @@ void cmLocalUnixMakefileGenerator3::WriteCustomCommands() << this->ConvertToOutputForExisting(objTarget.c_str()).c_str() << "\n"; } - // now do the clean ruleFileName = "CMakeCustomRules.dir/clean.make"; @@ -182,7 +217,7 @@ void cmLocalUnixMakefileGenerator3::WriteCustomCommands() } //---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::GenerateDirectoryInformationFile() +void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() { std::string infoFileName = m_Makefile->GetStartOutputDirectory(); infoFileName += "/CMakeDirectoryInformation.cmake"; @@ -246,6 +281,29 @@ void cmLocalUnixMakefileGenerator3::GenerateDirectoryInformationFile() << "SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN})\n"; } +//---------------------------------------------------------------------------- +std::string +cmLocalUnixMakefileGenerator3 +::ConvertToFullPath(const std::string& localPath) +{ + std::string dir = m_Makefile->GetStartOutputDirectory(); + dir += "/"; + dir += localPath; + return dir; +} + + +//---------------------------------------------------------------------------- +void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os) +{ + os + << "# CMAKE generated file: DO NOT EDIT!\n" + << "# Generated by \"" << m_GlobalGenerator->GetName() << "\"" + << " Generator, CMake Version " + << cmMakefile::GetMajorVersion() << "." + << cmMakefile::GetMinorVersion() << "\n\n"; +} + std::string cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath() { // Include the rule file for each object. @@ -262,7 +320,7 @@ std::string cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath() //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 -::GenerateTargetRuleFile(const cmTarget& target) +::WriteTargetRuleFiles(const cmTarget& target) { // Create a directory for this target. std::string dir = this->GetTargetDirectory(target); @@ -283,8 +341,7 @@ cmLocalUnixMakefileGenerator3 if(!m_GlobalGenerator->IgnoreFile((*source)->GetSourceExtension().c_str())) { // Generate this object file's rule file. - this->GenerateObjectRuleFile(target, *(*source), objects, - provides_requires); + this->WriteObjectRuleFiles(target, *(*source), objects,provides_requires); } else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT")) { @@ -303,9 +360,6 @@ cmLocalUnixMakefileGenerator3 std::string ruleFileName = dir; ruleFileName += "/build.make"; - // The rule file must be included by the makefile. - m_IncludeRuleFiles.push_back(ruleFileName); - // Open the rule file. This should be copy-if-different because the // rules may depend on this file itself. std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName); @@ -370,13 +424,22 @@ cmLocalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 -::GenerateObjectDependFile(const std::string& obj, const cmSourceFile& source, - std::vector<std::string>& objects, - std::vector<std::string>& provides_requires, - const std::string& depMarkFile, - std::vector<std::string>& depends) +::WriteObjectDependFile(std::string &obj, + const char * lang, + const cmSourceFile& source, + std::vector<std::string>& depends, + std::string& depMakeFile) { - const char* lang = this->GetSourceFileLanguage(source); + // TODO: what the heck is this? + // Generate the build-time dependencies file for this object file. + std::string depMarkFile; + if(!this->GenerateDependsMakeFile(lang, obj.c_str(), + depMakeFile, depMarkFile)) + { + cmSystemTools::Error("No dependency checker available for language \"", + lang, "\"."); + return; + } // Open the rule file for writing. This should be copy-if-different // because the rules may depend on this file itself. @@ -441,68 +504,14 @@ cmLocalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 -::GenerateObjectRuleFile(const cmTarget& target, const cmSourceFile& source, - std::vector<std::string>& objects, - std::vector<std::string>& provides_requires) +::WriteObjectBuildFile(std::string &obj, + const char *lang, + const cmTarget& target, + const cmSourceFile& source, + std::vector<std::string>& depends, + std::string &depMakeFile, + std::vector<std::string>& provides_requires) { - // Identify the language of the source file. - const char* lang = this->GetSourceFileLanguage(source); - if(!lang) - { - // If language is not known, this is an error. - cmSystemTools::Error("Source file \"", source.GetFullPath().c_str(), - "\" has unknown type."); - return; - } - - // Get the full path name of the object file. - std::string obj = this->GetObjectFileName(target, source); - - // Avoid generating duplicate rules. - if(m_ObjectFiles.find(obj) == m_ObjectFiles.end()) - { - m_ObjectFiles.insert(obj); - } - else - { - cmOStringStream err; - err << "Warning: Source file \"" - << source.GetSourceName().c_str() << "." - << source.GetSourceExtension().c_str() - << "\" is listed multiple times for target \"" << target.GetName() - << "\"."; - cmSystemTools::Message(err.str().c_str(), "Warning"); - return; - } - - // Create the directory containing the object file. This may be a - // subdirectory under the target's directory. - std::string dir = cmSystemTools::GetFilenamePath(obj.c_str()); - cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str()); - - // Generate the build-time dependencies file for this object file. - std::string depMakeFile; - std::string depMarkFile; - if(!this->GenerateDependsMakeFile(lang, obj.c_str(), - depMakeFile, depMarkFile)) - { - cmSystemTools::Error("No dependency checker available for language \"", - lang, "\"."); - return; - } - - // Save this in the target's list of object files. - objects.push_back(obj); - std::string relativeObj = this->GetHomeRelativeOutputPath(); - relativeObj += obj; - - // The object file should be checked for dependency integrity. - m_CheckDependFiles[lang].insert(obj); - - // write the .depends.make file - std::vector<std::string> depends; - this->GenerateObjectDependFile(obj,source,objects,provides_requires,depMarkFile,depends); - // Open the rule file for writing. This should be copy-if-different // because the rules may depend on this file itself. std::string ruleFileName = obj; @@ -570,6 +579,8 @@ cmLocalUnixMakefileGenerator3 this->ConvertToRelativeOutputPath(obj.c_str()); // Construct the build message. + std::string relativeObj = this->GetHomeRelativeOutputPath(); + relativeObj += obj; std::vector<std::string> commands; std::string buildEcho = "Building "; buildEcho += lang; @@ -629,6 +640,91 @@ cmLocalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 +::WriteObjectRuleFiles(const cmTarget& target, const cmSourceFile& source, + std::vector<std::string>& objects, + std::vector<std::string>& provides_requires) +{ + // Identify the language of the source file. + const char* lang = this->GetSourceFileLanguage(source); + if(!lang) + { + // If language is not known, this is an error. + cmSystemTools::Error("Source file \"", source.GetFullPath().c_str(), + "\" has unknown type."); + return; + } + + // Get the full path name of the object file. + std::string obj = this->GetObjectFileName(target, source); + + // Avoid generating duplicate rules. + if(m_ObjectFiles.find(obj) == m_ObjectFiles.end()) + { + m_ObjectFiles.insert(obj); + } + else + { + cmOStringStream err; + err << "Warning: Source file \"" + << source.GetSourceName().c_str() << "." + << source.GetSourceExtension().c_str() + << "\" is listed multiple times for target \"" << target.GetName() + << "\"."; + cmSystemTools::Message(err.str().c_str(), "Warning"); + return; + } + + // Create the directory containing the object file. This may be a + // subdirectory under the target's directory. + std::string dir = cmSystemTools::GetFilenamePath(obj.c_str()); + cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str()); + + // Save this in the target's list of object files. + objects.push_back(obj); + std::string relativeObj = this->GetHomeRelativeOutputPath(); + relativeObj += obj; + + // we compute some depends when writing the depend.make that we will also + // use in the build.make, same with depMakeFile + std::vector<std::string> depends; + std::string depMakeFile; + + // generate the depends rule file + this->WriteObjectDependFile(obj, lang, source, depends, depMakeFile); + + // generate the build rule file + this->WriteObjectBuildFile(obj, lang, target, source, depends, depMakeFile, + provides_requires); + + // The object file should be checked for dependency integrity. + m_CheckDependFiles[lang].insert(relativeObj); + + // If the language needs provides-requires mode, create the + // corresponding targets. +/* + if(strcmp(lang, "Fortran") == 0) + { + std::string objectRequires = obj; + std::string objectProvides = obj; + objectRequires += ".requires"; + objectProvides += ".provides"; + + // Add the provides target to build the object file. + std::vector<std::string> no_commands; + std::vector<std::string> p_depends; + p_depends.push_back(obj); + this->WriteMakeRule(ruleFileStream, 0, + objectProvides.c_str(), p_depends, no_commands); + + // Add this to the set of provides-requires objects on the target. + provides_requires.push_back(objectRequires); + } +*/ +} + +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator3 ::GenerateCustomRuleFile(const cmCustomCommand& cc) { // Create a directory for custom rule files. @@ -659,9 +755,6 @@ cmLocalUnixMakefileGenerator3 } m_CustomRuleFiles.insert(ruleFileName); - // This rule should be included by the makefile. - m_IncludeRuleFiles.push_back(ruleFileName); - // what is the relative path to the rule file std::string relRuleFile = this->GetHomeRelativeOutputPath(); relRuleFile += ruleFileName; @@ -707,7 +800,7 @@ cmLocalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 -::GenerateUtilityRuleFile(const cmTarget& target) +::WriteUtilityRuleFiles(const cmTarget& target) { // Create a directory for this target. std::string dir = this->GetTargetDirectory(target); @@ -717,9 +810,6 @@ cmLocalUnixMakefileGenerator3 std::string ruleFileName = dir; ruleFileName += "/build.make"; - // This rule should be included by the makefile. - m_IncludeRuleFiles.push_back(ruleFileName); - // Open the rule file. This should be copy-if-different because the // rules may depend on this file itself. std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName); @@ -785,9 +875,11 @@ cmLocalUnixMakefileGenerator3 depMakeFile = checker->GetMakeFileName(); depMarkFile = checker->GetMarkFileName(); + + // Todo is this required??? // Check the dependencies. checker->Check(); - + return true; } return false; @@ -867,6 +959,88 @@ cmLocalUnixMakefileGenerator3 os << "\n"; } +//---------------------------------------------------------------------------- +void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os) +{ + os + << "#======================================" + << "=======================================\n"; +} + +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator3 +::WriteMakeVariables(std::ostream& makefileStream) +{ + this->WriteDivider(makefileStream); + makefileStream + << "# Set environment variables for the build.\n" + << "\n"; + if(m_WindowsShell) + { + makefileStream + << "!IF \"$(OS)\" == \"Windows_NT\"\n" + << "NULL=\n" + << "!ELSE\n" + << "NULL=nul\n" + << "!ENDIF\n"; + } + else + { + makefileStream + << "# The shell in which to execute make rules.\n" + << "SHELL = /bin/sh\n" + << "\n"; + } + + if(m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) + { + makefileStream + << "# Produce verbose output by default.\n" + << "VERBOSE = 1\n" + << "\n"; + } + + std::string cmakecommand = + this->ConvertToOutputForExisting( + m_Makefile->GetRequiredDefinition("CMAKE_COMMAND")); + makefileStream + << "# The CMake executable.\n" + << "CMAKE_COMMAND = " + << m_GlobalGenerator->ConvertToHomeRelativeOutputPath + (cmakecommand.c_str()).c_str() << "\n" + << "\n"; + makefileStream + << "# The command to remove a file.\n" + << "RM = " + << this->ConvertToRelativeOutputPath(cmakecommand.c_str()).c_str() + << " -E remove -f\n" + << "\n"; + + if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND")) + { + makefileStream + << "# The program to use to edit the cache.\n" + << "CMAKE_EDIT_COMMAND = " + << (this->ConvertToOutputForExisting( + m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))) << "\n" + << "\n"; + } + + makefileStream + << "# The top-level source directory on which CMake was run.\n" + << "CMAKE_SOURCE_DIR = " + << this->ConvertToRelativeOutputPath(m_Makefile->GetHomeDirectory()) + << "\n" + << "\n"; + makefileStream + << "# The top-level build directory on which CMake was run.\n" + << "CMAKE_BINARY_DIR = " + << this->ConvertToRelativeOutputPath(m_Makefile->GetHomeOutputDirectory()) + << "\n" + << "\n"; +} + void cmLocalUnixMakefileGenerator3::WriteTargetIncludes(std::ostream& makefileStream, const char *file, const char *rule) @@ -973,98 +1147,6 @@ cmLocalUnixMakefileGenerator3 } } -//---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os) -{ - os - << "#======================================" - << "=======================================\n"; -} - -//---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os) -{ - os - << "# CMAKE generated file: DO NOT EDIT!\n" - << "# Generated by \"" << m_GlobalGenerator->GetName() << "\"" - << " Generator, CMake Version " - << cmMakefile::GetMajorVersion() << "." - << cmMakefile::GetMinorVersion() << "\n\n"; -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteMakeVariables(std::ostream& makefileStream) -{ - this->WriteDivider(makefileStream); - makefileStream - << "# Set environment variables for the build.\n" - << "\n"; - if(m_WindowsShell) - { - makefileStream - << "!IF \"$(OS)\" == \"Windows_NT\"\n" - << "NULL=\n" - << "!ELSE\n" - << "NULL=nul\n" - << "!ENDIF\n"; - } - else - { - makefileStream - << "# The shell in which to execute make rules.\n" - << "SHELL = /bin/sh\n" - << "\n"; - } - - if(m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) - { - makefileStream - << "# Produce verbose output by default.\n" - << "VERBOSE = 1\n" - << "\n"; - } - - std::string cmakecommand = - this->ConvertToOutputForExisting( - m_Makefile->GetRequiredDefinition("CMAKE_COMMAND")); - makefileStream - << "# The CMake executable.\n" - << "CMAKE_COMMAND = " - << m_GlobalGenerator->ConvertToHomeRelativeOutputPath - (cmakecommand.c_str()).c_str() << "\n" - << "\n"; - makefileStream - << "# The command to remove a file.\n" - << "RM = " - << this->ConvertToRelativeOutputPath(cmakecommand.c_str()).c_str() - << " -E remove -f\n" - << "\n"; - - if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND")) - { - makefileStream - << "# The program to use to edit the cache.\n" - << "CMAKE_EDIT_COMMAND = " - << (this->ConvertToOutputForExisting( - m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))) << "\n" - << "\n"; - } - - makefileStream - << "# The top-level source directory on which CMake was run.\n" - << "CMAKE_SOURCE_DIR = " - << this->ConvertToRelativeOutputPath(m_Makefile->GetHomeDirectory()) - << "\n" - << "\n"; - makefileStream - << "# The top-level build directory on which CMake was run.\n" - << "CMAKE_BINARY_DIR = " - << this->ConvertToRelativeOutputPath(m_Makefile->GetHomeOutputDirectory()) - << "\n" - << "\n"; -} //---------------------------------------------------------------------------- void @@ -1219,7 +1301,7 @@ cmLocalUnixMakefileGenerator3 { // Build command to run CMake to check if anything needs regenerating. std::string cmakefileName = m_Makefile->GetStartOutputDirectory(); - cmakefileName += "/" CMLUMG_MAKEFILE_NAME ".cmake"; + cmakefileName += "/Makefile.cmake"; std::string runRule = "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"; runRule += " --check-build-system "; @@ -1267,86 +1349,7 @@ cmLocalUnixMakefileGenerator3 ".SUFFIXES", depends, no_commands); } -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteAllRules(std::ostream& makefileStream) -{ - // Write section header. - this->WriteDivider(makefileStream); - makefileStream - << "# Rules to build dependencies and targets.\n" - << "\n"; - - std::vector<std::string> depends; - std::vector<std::string> commands; - - // Check the build system in this directory. - depends.push_back("cmake_check_build_system"); - - commands.push_back(this->GetRecursiveMakeCall("depend.make",0)); - commands.push_back(this->GetRecursiveMakeCall("build.make",0)); - - // Write the rule. - this->WriteMakeRule(makefileStream, "The main all target", "all", depends, commands); - - // write the clean - commands.clear(); - commands.push_back(this->GetRecursiveMakeCall("clean.make",0)); - this->WriteMakeRule(makefileStream, "default clean target", "clean", depends, commands); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteConvenienceRules(std::ostream& ruleFileStream) -{ - std::vector<std::string> depends; - std::vector<std::string> tgt_depends; - std::vector<std::string> commands; - - depends.push_back("cmake_check_build_system"); - - // for each target - // Generate the rule files for each target. - const cmTargets& targets = m_Makefile->GetTargets(); - std::string localName; - std::string makeTargetName; - for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t) - { - if((t->second.GetType() == cmTarget::EXECUTABLE) || - (t->second.GetType() == cmTarget::STATIC_LIBRARY) || - (t->second.GetType() == cmTarget::SHARED_LIBRARY) || - (t->second.GetType() == cmTarget::MODULE_LIBRARY)) - { - // Add a rule to build the target by name. - localName = this->GetRelativeTargetDirectory(t->second); - - commands.clear(); - makeTargetName = localName; - makeTargetName += "/depend"; - commands.push_back(this->GetRecursiveMakeCall("depend.make",makeTargetName.c_str())); - makeTargetName = localName; - makeTargetName += "/build"; - commands.push_back(this->GetRecursiveMakeCall("build.make",makeTargetName.c_str())); - - // Write the rule. - this->WriteMakeRule(ruleFileStream, "Convenience name for target.", - localName.c_str(), depends, commands); - - // Add a target with the canonical name (no prefix, suffix or path). - if(localName != t->second.GetName()) - { - commands.clear(); - tgt_depends.clear(); - tgt_depends.push_back(localName); - this->WriteMakeRule(ruleFileStream, "Convenience name for target.", - t->second.GetName(), tgt_depends, commands); - } - } - } -} //---------------------------------------------------------------------------- void @@ -1374,35 +1377,6 @@ cmLocalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 -::WriteRuleFileIncludes(std::ostream& makefileStream) -{ - // Make sure we have some rules to include. - if(m_IncludeRuleFiles.empty()) - { - return; - } - - // Write section header. - this->WriteDivider(makefileStream); - makefileStream - << "# Include rule files for this directory.\n" - << "\n"; - - // Write the include rules. - for(std::vector<std::string>::const_iterator i = m_IncludeRuleFiles.begin(); - i != m_IncludeRuleFiles.end(); ++i) - { - makefileStream - << m_IncludeDirective << " " - << this->ConvertToOutputForExisting(i->c_str()).c_str() - << "\n"; - } - makefileStream << "\n"; -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 ::WriteExecutableRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, @@ -2061,52 +2035,6 @@ cmLocalUnixMakefileGenerator3 cleanTarget.c_str(), no_depends, commands); } -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteTargetRequiresRule(std::ostream& ruleFileStream, const cmTarget& target, - const std::vector<std::string>& provides_requires) -{ - // 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 - // that requires the target can build it directly. - std::vector<std::string> no_commands; - std::vector<std::string> depends; - depends.push_back(target.GetName()); - this->WriteMakeRule(ruleFileStream, comment.c_str(), - targetRequires.c_str(), depends, no_commands); - } - else - { - // There are provides-requires mode objects in this target. Use - // provides-requires mode to build the target itself. - std::string targetProvides = target.GetName(); - targetProvides += ".provides"; - { - std::vector<std::string> no_commands; - std::vector<std::string> depends; - depends.push_back(target.GetName()); - this->WriteMakeRule(ruleFileStream, 0, - targetProvides.c_str(), depends, no_commands); - } - { - // Build list of require-level dependencies. - std::vector<std::string> depends; - for(std::vector<std::string>::const_iterator - pr = provides_requires.begin(); - pr != provides_requires.end(); ++pr) - { - depends.push_back(*pr); - } - - } - } -} //---------------------------------------------------------------------------- void @@ -2241,17 +2169,6 @@ cmLocalUnixMakefileGenerator3 //---------------------------------------------------------------------------- std::string -cmLocalUnixMakefileGenerator3 -::ConvertToFullPath(const std::string& localPath) -{ - std::string dir = m_Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += localPath; - return dir; -} - -//---------------------------------------------------------------------------- -std::string cmLocalUnixMakefileGenerator3::ConvertToRelativeOutputPath(const char* p) { // Convert the path to a relative path. @@ -2320,53 +2237,6 @@ cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p) } //---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::ConfigureOutputPaths() -{ - // Format the library and executable output paths. - if(const char* libOut = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH")) - { - m_LibraryOutputPath = libOut; - this->FormatOutputPath(m_LibraryOutputPath, "LIBRARY"); - } - if(const char* exeOut = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")) - { - m_ExecutableOutputPath = exeOut; - this->FormatOutputPath(m_ExecutableOutputPath, "EXECUTABLE"); - } -} - -//---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::FormatOutputPath(std::string& path, - const char* name) -{ - if(!path.empty()) - { - // Convert the output path to a full path in case it is - // specified as a relative path. Treat a relative path as - // relative to the current output directory for this makefile. - path = - cmSystemTools::CollapseFullPath(path.c_str(), - m_Makefile->GetStartOutputDirectory()); - - // Add a trailing slash for easy appending later. - if(path.empty() || path[path.size()-1] != '/') - { - path += "/"; - } - - // Make sure the output path exists on disk. - if(!cmSystemTools::MakeDirectory(path.c_str())) - { - cmSystemTools::Error("Error failed to create ", - name, "_OUTPUT_PATH directory:", path.c_str()); - } - - // Add this as a link directory automatically. - m_Makefile->AddLinkDirectory(path.c_str()); - } -} - -//---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 ::AppendTargetDepends(std::vector<std::string>& depends, @@ -2840,43 +2710,6 @@ cmLocalUnixMakefileGenerator3 //============================================================================ //---------------------------------------------------------------------------- -std::string -cmLocalUnixMakefileGenerator3 -::GetRecursiveMakeCall(const char *Makefile, const char* tgt) -{ - // Call make on the given file. - std::string cmd; - cmd += "$(MAKE) -f "; - cmd += Makefile; - cmd += " "; - - // Pass down verbosity level. - if(m_MakeSilentFlag.size()) - { - cmd += m_MakeSilentFlag; - cmd += " "; - } - - // Most unix makes will pass the command line flags to make down to - // sub-invoked makes via an environment variable. However, some - // makes do not support that, so you have to pass the flags - // explicitly. - if(m_PassMakeflags) - { - cmd += "-$(MAKEFLAGS) "; - } - - // Add the target. - if (tgt && tgt[0] != '\0') - { - std::string tgt2 = this->ConvertToRelativeOutputPath(tgt); - tgt2 = this->ConvertToMakeTarget(tgt2.c_str()); - cmd += tgt2; - } - return cmd; -} - -//---------------------------------------------------------------------------- cmDepends* cmLocalUnixMakefileGenerator3::GetDependsChecker(const std::string& lang, const char* dir, @@ -3039,3 +2872,4 @@ void cmLocalUnixMakefileGenerator3::CheckDependencies(cmMakefile* mf) } } } + diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 7596c1b..163323a 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -35,16 +35,54 @@ class cmSourceFile; class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator { public: - ///! Set cache only and recurse to false by default. cmLocalUnixMakefileGenerator3(); - virtual ~cmLocalUnixMakefileGenerator3(); - /** Set the command used when there are no dependencies or rules for - a target. This is used to avoid errors on some make - implementations. */ - void SetEmptyCommand(const char* cmd); + /** + * Generate the makefile for this directory. + */ + virtual void Generate(); + + /** creates the common disclainer text at the top of each makefile */ + void WriteDisclaimer(std::ostream& os); + + // this returns the relative path between the HomeOutputDirectory and this + // local generators StartOutputDirectory + std::string GetHomeRelativeOutputPath(); + + // Write out a make rule + void WriteMakeRule(std::ostream& os, + const char* comment, + const char* target, + const std::vector<std::string>& depends, + const std::vector<std::string>& commands); + + // write the main variables used by the makefiles + void WriteMakeVariables(std::ostream& makefileStream); + + // write a comment line #====... in the stream + void WriteDivider(std::ostream& os); + + /** + * If true, then explicitly pass MAKEFLAGS on the make all target for makes + * that do not use environment variables. + * + */ + void SetPassMakeflags(bool s){m_PassMakeflags = s;} + bool GetPassMakeflags() { return m_PassMakeflags; } + + /** + * Set the flag used to keep the make program silent. + */ + void SetMakeSilentFlag(const char* s) { m_MakeSilentFlag = s; } + std::string &GetMakeSilentFlag() { return m_MakeSilentFlag; } + + + + + + /** Set whether the echo command needs its argument quoted. */ void SetEchoNeedsQuote(bool b) { m_EchoNeedsQuote = b; } @@ -63,11 +101,6 @@ public: const char *GetIncludeDirective() { return m_IncludeDirective.c_str(); } /** - * Set the flag used to keep the make program silent. - */ - void SetMakeSilentFlag(const char* s) { m_MakeSilentFlag = s; } - - /** * Set max makefile variable size, default is 0 which means unlimited. */ void SetMakefileVariableSize(int s) { m_MakefileVariableSize = s; } @@ -78,45 +111,29 @@ public: */ void SetIgnoreLibPrefix(bool s) { m_IgnoreLibPrefix = s; } - /** - * If true, then explicitly pass MAKEFLAGS on the make all target for makes - * that do not use environment variables. - * - */ - void SetPassMakeflags(bool s){m_PassMakeflags = s;} - - /** - * Generate the makefile for this directory. - */ - virtual void Generate(); - + + + + /** Called from command-line hook to scan dependencies. */ static bool ScanDependencies(std::vector<std::string> const& args); /** Called from command-line hook to check dependencies. */ static void CheckDependencies(cmMakefile* mf); + + /** write some extra rules suahc as make test etc */ + void WriteSpecialTargetsTop(std::ostream& makefileStream); - void WriteDisclaimer(std::ostream& os); - void WriteMakeRule(std::ostream& os, - const char* comment, - const char* target, - const std::vector<std::string>& depends, - const std::vector<std::string>& commands); - void WriteAllRules(std::ostream& makefileStream); + + + void WriteTargetIncludes(std::ostream& makefileStream,const char *file, const char *rule); - void WriteSpecialTargetsTop(std::ostream& makefileStream); void WriteSpecialTargetsBottom(std::ostream& makefileStream); - void WriteMakeVariables(std::ostream& makefileStream); std::string ConvertToRelativeOutputPath(const char* p); - void WriteConvenienceRules(std::ostream& ruleFileStream); std::string GetRelativeTargetDirectory(const cmTarget& target); void WriteLocalCleanRule(std::ostream& makefileStream); - // this returns the relative path between the HomeOutputDirectory and this - // local generators StartOutputDirectory - std::string GetHomeRelativeOutputPath(); - // List the files for which to check dependency integrity. Each // language has its own list because integrity may be checked // differently. @@ -126,45 +143,69 @@ public: protected: - void GenerateMakefile(); - void GenerateCMakefile(); - void GenerateDirectoryInformationFile(); - void GenerateTargetRuleFile(const cmTarget& target); - void GenerateObjectRuleFile(const cmTarget& target, - const cmSourceFile& source, - std::vector<std::string>& objects, - std::vector<std::string>& provides_requires); - void GenerateObjectDependFile(const std::string& obj, - const cmSourceFile& source, - std::vector<std::string>& objects, - std::vector<std::string>& provides_requires, - const std::string& depMarkFile, - std::vector<std::string>& depends); - void GenerateCustomRuleFile(const cmCustomCommand& cc); - void GenerateUtilityRuleFile(const cmTarget& target); + // these two methods just compute reasonable values for m_LibraryOutputPath and + // m_ExecutableOutputPath + void ConfigureOutputPaths(); + void FormatOutputPath(std::string& path, const char* name); + + // this converts a file name that is relative to the StartOuputDirectory + // into a full path + std::string ConvertToFullPath(const std::string& localPath); + + // this is responsible for writing all of the rules for all this + // directories custom commands (but not utility targets) + void WriteCustomCommands(); + + // this method Writes the Directory informaiton files + void WriteDirectoryInformationFile(); + + // cleanup the name of a potential target + std::string ConvertToMakeTarget(const char* tgt); + + // used in writing out Cmake files such as WriteDirectoryInformation + void WriteCMakeArgument(std::ostream& os, const char* s); + + // write out all the rules for this target + void WriteTargetRuleFiles(const cmTarget& target); + void WriteUtilityRuleFiles(const cmTarget& target); + + // create the rule files for an object + void WriteObjectRuleFiles(const cmTarget& target, + const cmSourceFile& source, + std::vector<std::string>& objects, + std::vector<std::string>& provides_requires); + + // write the build rule for an object + void WriteObjectBuildFile(std::string &obj, + const char *lang, + const cmTarget& target, + const cmSourceFile& source, + std::vector<std::string>& depends, + std::string &depMakeFile, + std::vector<std::string>& provides_requires); + + // write the depend.make file for an object + void WriteObjectDependFile(std::string& obj, + const char *lang, + const cmSourceFile& source, + std::vector<std::string>& depends, + std::string& depMarkFile); + + // this is used only by WriteObjectDependFile bool GenerateDependsMakeFile(const std::string& lang, const char* objFile, std::string& depMakeFile, std::string& depMarkFile); - void WriteDivider(std::ostream& os); - void WriteRuleFileIncludes(std::ostream& makefileStream); - void WriteSubdirRules(std::ostream& makefileStream, const char* pass); - void WriteSubdirRule(std::ostream& makefileStream, const char* pass, - 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 WriteConvenienceRule(std::ostream& ruleFileStream, - const char* realTarget, - const char* helpTarget); - void WriteCustomCommands(); - void WriteExecutableRule(std::ostream& ruleFileStream, - const char* ruleFileName, - const cmTarget& target, - const std::vector<std::string>& objects, - const std::vector<std::string>& external_objects, - const std::vector<std::string>& provides_requires); + + // return the appropriate depends checker + static cmDepends* GetDependsChecker(const std::string& lang, + const char* dir, + const char* objFile); + + + void GenerateCustomRuleFile(const cmCustomCommand& cc); + + // these three make some simple changes and then call WriteLibraryRule void WriteStaticLibraryRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, @@ -183,6 +224,16 @@ protected: const std::vector<std::string>& objects, const std::vector<std::string>& external_objects, const std::vector<std::string>& provides_requires); + + // the main code for writing the Executable target rules + void WriteExecutableRule(std::ostream& ruleFileStream, + const char* ruleFileName, + const cmTarget& target, + const std::vector<std::string>& objects, + const std::vector<std::string>& external_objects, + const std::vector<std::string>& provides_requires); + + // the main method for writing library rules void WriteLibraryRule(std::ostream& ruleFileStream, const char* ruleFileName, const cmTarget& target, @@ -191,6 +242,17 @@ protected: const char* linkRuleVar, const char* extraLinkFlags, const std::vector<std::string>& provides_requires); + + + + + + + void WriteLocalRule(std::ostream& ruleFileStream, const char* pass, + const char* dependency); + void WriteConvenienceRule(std::ostream& ruleFileStream, + const char* realTarget, + const char* helpTarget); void WriteObjectsVariable(std::ostream& ruleFileStream, const cmTarget& target, const std::vector<std::string>& objects, @@ -205,19 +267,13 @@ protected: const std::vector<std::string>& files, const std::vector<std::string>& objects, const std::vector<std::string>& external_objects); - void WriteTargetRequiresRule(std::ostream& ruleFileStream, - const cmTarget& target, - const std::vector<std::string>& provides_requires); - void WriteCMakeArgument(std::ostream& os, const char* s); + std::string GetTargetDirectory(const cmTarget& target); std::string GetSubdirTargetName(const char* pass, const char* subdir); std::string GetObjectFileName(const cmTarget& target, const cmSourceFile& source); const char* GetSourceFileLanguage(const cmSourceFile& source); - std::string ConvertToFullPath(const std::string& localPath); std::string ConvertToQuotedOutputPath(const char* p); - void ConfigureOutputPaths(); - void FormatOutputPath(std::string& path, const char* name); void AppendTargetDepends(std::vector<std::string>& depends, const cmTarget& target); @@ -240,33 +296,14 @@ protected: //========================================================================== bool SamePath(const char* path1, const char* path2); - std::string ConvertToMakeTarget(const char* tgt); std::string& CreateSafeUniqueObjectFileName(const char* sin); std::string CreateMakeVariable(const char* sin, const char* s2in); //========================================================================== - std::string GetRecursiveMakeCall(const char *makefile, const char* tgt); - void WriteJumpAndBuildRules(std::ostream& makefileStream); - - static cmDepends* GetDependsChecker(const std::string& lang, - const char* dir, - const char* objFile); private: - // Map from target name to build directory containing it for - // jump-and-build targets. - struct RemoteTarget - { - std::string m_BuildDirectory; - std::string m_FilePath; - }; - std::map<cmStdString, RemoteTarget> m_JumpAndBuild; - std::map<cmStdString, IntegrityCheckSet> m_CheckDependFiles; - // Command used when a rule has no dependencies or commands. - std::vector<std::string> m_EmptyCommands; - //========================================================================== // Configuration settings. int m_MakefileVariableSize; @@ -283,9 +320,6 @@ private: // Flag for whether echo command needs quotes. bool m_EchoNeedsQuote; - // List of make rule files that need to be included by the makefile. - std::vector<std::string> m_IncludeRuleFiles; - // Set of custom rule files that have been generated. std::set<cmStdString> m_CustomRuleFiles; |