From 141ad7645e4c6d8841f346ecd0fb40383fa3a733 Mon Sep 17 00:00:00 2001 From: Ken Martin Date: Wed, 15 Feb 2006 10:34:11 -0500 Subject: ENH: some reorg of the unix makefile generator --- Source/CMakeLists.txt | 4 + Source/cmGlobalUnixMakefileGenerator3.cxx | 34 +- Source/cmLocalUnixMakefileGenerator3.cxx | 2454 ++++++----------------------- Source/cmLocalUnixMakefileGenerator3.h | 230 ++- Source/cmMakefileTargetGenerator.h | 2 +- bootstrap | 4 + 6 files changed, 622 insertions(+), 2106 deletions(-) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index c5d05f1..eebc4f3 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -125,6 +125,10 @@ SET(SRCS cmMakeDepend.h cmMakefile.cxx cmMakefile.h + cmMakefileTargetGenerator.cxx + cmMakefileExecutableTargetGenerator.cxx + cmMakefileLibraryTargetGenerator.cxx + cmMakefileUtilityTargetGenerator.cxx cmOrderLinkDirectories.cxx cmFileTimeComparison.cxx cmFileTimeComparison.h diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index d76b6be..d87ccca 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -129,6 +129,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() // Write the do not edit header. lg->WriteDisclaimer(makefileStream); + // Write out the "special" stuff lg->WriteSpecialTargetsTop(makefileStream); // Write the main entry point target. This must be the VERY first @@ -390,8 +391,8 @@ cmGlobalUnixMakefileGenerator3 // write the directory rule commands.clear(); commands.push_back - (lg->GetRecursiveMakeCall("CMakeFiles/Makefile2", - makeTargetName.c_str())); + (lg->GetRecursiveMakeCall + ("CMakeFiles/Makefile2",makeTargetName.c_str())); // Write the rule. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.", @@ -520,9 +521,8 @@ cmGlobalUnixMakefileGenerator3 // write the directory rule commands.clear(); - commands.push_back - (lg->GetRecursiveMakeCall("CMakeFiles/Makefile2", - makeTargetName.c_str())); + commands.push_back(lg->GetRecursiveMakeCall + ("CMakeFiles/Makefile2",makeTargetName.c_str())); // Write the rule. lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.", @@ -627,8 +627,8 @@ cmGlobalUnixMakefileGenerator3 // Write the rule. commands.clear(); - commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2", - t->second.GetName())); + commands.push_back(lg->GetRecursiveMakeCall + ("CMakeFiles/Makefile2",t->second.GetName())); depends.clear(); if(sym) { @@ -691,22 +691,22 @@ cmGlobalUnixMakefileGenerator3 { makeTargetName = localName; makeTargetName += "/depend"; - commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(), - makeTargetName.c_str())); + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); // add requires if we need it for this generator if (needRequiresStep) { makeTargetName = localName; makeTargetName += "/requires"; - commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(), - makeTargetName.c_str())); + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); } } makeTargetName = localName; makeTargetName += "/build"; - commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(), - makeTargetName.c_str())); + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(),makeTargetName.c_str())); // Write the rule. localName += "/all"; @@ -732,8 +732,8 @@ cmGlobalUnixMakefileGenerator3 // Write the rule. commands.clear(); - commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2", - localName.c_str())); + commands.push_back(lg->GetRecursiveMakeCall + ("CMakeFiles/Makefile2",localName.c_str())); depends.clear(); if(sym) { @@ -763,8 +763,8 @@ cmGlobalUnixMakefileGenerator3 depends.push_back(sym); } commands.clear(); - commands.push_back(lg->GetRecursiveMakeCall(makefileName.c_str(), - makeTargetName.c_str())); + commands.push_back(lg->GetRecursiveMakeCall + (makefileName.c_str(), makeTargetName.c_str())); lg->WriteMakeRule(ruleFileStream, "clean rule for target.", makeTargetName.c_str(), depends, commands); commands.clear(); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index ebf8060..4c26db3 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -20,6 +20,7 @@ #include "cmGeneratedFileStream.h" #include "cmGlobalUnixMakefileGenerator3.h" #include "cmMakefile.h" +#include "cmMakefileTargetGenerator.h" #include "cmSourceFile.h" #include "cmake.h" @@ -34,10 +35,6 @@ #include // auto_ptr #include -// TODO: Add "help" target. -// TODO: Identify remaining relative path violations. -// TODO: Need test for separate executable/library output path. - //---------------------------------------------------------------------------- cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3() { @@ -82,18 +79,13 @@ void cmLocalUnixMakefileGenerator3::Generate() std::string empty; for(cmTargets::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)) + cmMakefileTargetGenerator *tg = + cmMakefileTargetGenerator::New(this, t->first, &(t->second)); + if (tg) { + this->TargetGenerators.push_back(tg); t->second.TraceVSDependencies(empty, m_Makefile); - this->WriteTargetRuleFiles(t->second); - } - else if(t->second.GetType() == cmTarget::UTILITY) - { - t->second.TraceVSDependencies(empty, m_Makefile); - this->WriteUtilityRuleFiles(t->second); + tg->WriteRuleFiles(); } } @@ -102,6 +94,15 @@ void cmLocalUnixMakefileGenerator3::Generate() // Write the cmake file with information for this directory. this->WriteDirectoryInformationFile(); + + // delete the makefile target generator objects + for (std::vector::iterator mtgIter = + this->TargetGenerators.begin(); + mtgIter != this->TargetGenerators.end(); ++mtgIter) + { + delete *mtgIter; + } + this->TargetGenerators.clear(); } @@ -164,27 +165,129 @@ void cmLocalUnixMakefileGenerator3::FormatOutputPath(std::string& path, } } +//---------------------------------------------------------------------------- +void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() +{ + // generate the includes + std::string ruleFileName = "Makefile"; + + // 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); + cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str()); + if(!ruleFileStream) + { + return; + } + // always write the top makefile + if (m_Parent) + { + ruleFileStream.SetCopyIfDifferent(true); + } + + // write the all rules + this->WriteLocalAllRules(ruleFileStream); + + // only write local targets unless at the top Keep track of targets already + // listed. + std::set emittedTargets; + if (m_Parent) + { + // write our targets, and while doing it collect up the object + // file rules + this->WriteLocalMakefileTargets(ruleFileStream,emittedTargets); + } + else + { + cmGlobalUnixMakefileGenerator3 *gg = + static_cast(m_GlobalGenerator); + gg->WriteConvenienceRules(ruleFileStream,emittedTargets); + } + + std::vector depends; + std::vector commands; + + // now write out the object rules + // for each object file name + for (std::map >::iterator lo = + m_LocalObjectFiles.begin(); + lo != m_LocalObjectFiles.end(); ++lo) + { + commands.clear(); + // for each target using the object file + for (std::vector::iterator to = + lo->second.begin(); to != lo->second.end(); ++to) + { + std::string tgtMakefileName = this->GetRelativeTargetDirectory(**to); + std::string targetName = tgtMakefileName; + tgtMakefileName += "/build.make"; + targetName += "/"; + targetName += lo->first.c_str(); + commands.push_back(this->GetRecursiveMakeCall + (tgtMakefileName.c_str(),targetName.c_str())); + this->CreateCDCommand(commands, + m_Makefile->GetHomeOutputDirectory(), + m_Makefile->GetStartOutputDirectory()); + } + this->WriteMakeRule(ruleFileStream, + "target for object file", + lo->first.c_str(), depends, commands); + } + + // add a help target as long as there isn;t a real target named help + if(emittedTargets.insert("help").second) + { + cmGlobalUnixMakefileGenerator3 *gg = + static_cast(m_GlobalGenerator); + gg->WriteHelpRule(ruleFileStream,this); + } + + this->WriteSpecialTargetsBottom(ruleFileStream); +} void cmLocalUnixMakefileGenerator3 -::WriteCustomCommands(std::ostream& ruleFileStream, - std::vector& cleanFiles) +::WriteLocalMakefileTargets(std::ostream& ruleFileStream, + std::set &emitted) { - // add custom commands to the clean rules? - const char* clean_no_custom = m_Makefile->GetProperty("CLEAN_NO_CUSTOM"); - bool clean = cmSystemTools::IsOff(clean_no_custom); - - // Generate the rule files for each custom command. - const std::vector &classes = m_Makefile->GetSourceFiles(); - for(std::vector::const_iterator i = classes.begin(); - i != classes.end(); i++) + std::vector depends; + std::vector commands; + + // for each target we just provide a rule to cd up to the top and do a make + // on the target + cmTargets& targets = m_Makefile->GetTargets(); + std::string localName; + for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) { - if(cmCustomCommand* cc = (*i)->GetCustomCommand()) + if((t->second.GetType() == cmTarget::EXECUTABLE) || + (t->second.GetType() == cmTarget::STATIC_LIBRARY) || + (t->second.GetType() == cmTarget::SHARED_LIBRARY) || + (t->second.GetType() == cmTarget::MODULE_LIBRARY) || + (t->second.GetType() == cmTarget::UTILITY)) { - this->GenerateCustomRuleFile(*cc,ruleFileStream); - if (clean) + emitted.insert(t->second.GetName()); + + // for subdirs add a rule to build this specific target by name. + localName = this->GetRelativeTargetDirectory(t->second); + localName += "/rule"; + commands.clear(); + depends.clear(); + + // Build the target for this pass. + commands.push_back(this->GetRecursiveMakeCall + ("CMakeFiles/Makefile2",localName.c_str())); + this->CreateCDCommand(commands, + m_Makefile->GetHomeOutputDirectory(), + m_Makefile->GetStartOutputDirectory()); + 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()) { - cleanFiles.push_back - (this->Convert(cc->GetOutput(),START_OUTPUT,SHELL)); + commands.clear(); + depends.push_back(localName); + this->WriteMakeRule(ruleFileStream, "Convenience name for target.", + t->second.GetName(), depends, commands); } } } @@ -293,692 +396,91 @@ cmLocalUnixMakefileGenerator3 } -//---------------------------------------------------------------------------- -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"; -} - const std::string &cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath() { return m_HomeRelativeOutputPath; } + //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 -::WriteTargetRuleFiles(cmTarget& target) +::WriteMakeRule(std::ostream& os, + const char* comment, + const char* target, + const std::vector& depends, + const std::vector& commands) { - // Create a directory for this target. - std::string dir = m_Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += this->GetTargetDirectory(target); - cmSystemTools::MakeDirectory(dir.c_str()); - - // Generate the build-time dependencies file for this target. - std::string depBase = dir; - depBase += "/"; - depBase += target.GetName(); - - // Construct the rule file name. - std::string ruleFileName = dir; - ruleFileName += "/build.make"; - - // Open the rule file. This should be copy-if-different because the - // rules may depend on this file itself. - std::string ruleFileNameFull = ruleFileName; - cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str()); - ruleFileStream.SetCopyIfDifferent(true); - if(!ruleFileStream) + // Make sure there is a target. + if(!target || !*target) { + cmSystemTools::Error("No target for WriteMakeRule! called with comment: ", + comment); return; } - this->WriteDisclaimer(ruleFileStream); - this->WriteSpecialTargetsTop(ruleFileStream); - this->WriteMakeVariables(ruleFileStream); - - // Open the flags file. This should be copy-if-different because the - // rules may depend on this file itself. - std::string flagFileName = dir; - flagFileName += "/flags.make"; - std::string flagFileNameFull = flagFileName; - cmGeneratedFileStream flagFileStream(flagFileNameFull.c_str()); - flagFileStream.SetCopyIfDifferent(true); - if(!flagFileStream) + + std::string replace; + + // Write the comment describing the rule in the makefile. + if(comment) { - return; - } - this->WriteDisclaimer(flagFileStream); - - // Include the dependencies for the target. - std::string depPath = dir; - depPath += "/depend.make"; - depPath = this->Convert(depPath.c_str(),HOME_OUTPUT,MAKEFILE); - ruleFileStream - << "# Include any dependencies generated for this target.\n" - << m_IncludeDirective << " " - << depPath - << "\n\n"; - - // Include the flags for the target. - flagFileName = this->Convert(flagFileName.c_str(), HOME_OUTPUT, MAKEFILE); - ruleFileStream - << "# Include the compile flags for this target's objects.\n" - << m_IncludeDirective << " " - << flagFileName - << "\n\n"; - - // make sure the depend file exists - depPath = dir; - depPath += "/depend.make"; - depPath = this->Convert(depPath.c_str(),FULL,UNCHANGED); - if (!cmSystemTools::FileExists(depPath.c_str())) - { - // Write an empty dependency file. - cmGeneratedFileStream depFileStream(depPath.c_str()); - depFileStream - << "# Empty dependencies file for " << target.GetName() << ".\n" - << "# This may be replaced when dependencies are built." << std::endl; - } - - // First generate the object rule files. Save a list of all object - // files for this target. - std::vector objects; - std::vector external_objects; - const std::vector& sources = target.GetSourceFiles(); - for(std::vector::const_iterator source = sources.begin(); - source != sources.end(); ++source) - { - if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") && - !(*source)->GetCustomCommand()) + replace = comment; + std::string::size_type lpos = 0; + std::string::size_type rpos; + while((rpos = replace.find('\n', lpos)) != std::string::npos) { - if(!m_GlobalGenerator->IgnoreFile((*source)->GetSourceExtension().c_str())) - { - // Generate this object file's rule file. - this->WriteObjectRuleFiles(target, *(*source), objects, - ruleFileStream, flagFileStream); - } - else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT")) - { - // This is an external object file. Just add it. - external_objects.push_back((*source)->GetFullPath()); - } - else - { - // We only get here if a source file is not an external object - // and has an extension that is listed as an ignored file type - // for this language. No message or diagnosis should be - // given. - } + os << "# " << replace.substr(lpos, rpos-lpos) << "\n"; + lpos = rpos+1; } + os << "# " << replace.substr(lpos) << "\n"; } - - // write language flags for target - std::map& - checkSet = this->GetIntegrityCheckSet()[target.GetName()]; - for(std::map::const_iterator - l = checkSet.begin(); l != checkSet.end(); ++l) + + // Construct the left hand side of the rule. + replace = target; + std::string tgt = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE); + tgt = this->ConvertToMakeTarget(tgt.c_str()); + const char* space = ""; + if(tgt.size() == 1) { - const char *lang = l->first.c_str(); - std::string flags; - // Add the export symbol definition for shared library objects. - bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) || - (target.GetType() == cmTarget::MODULE_LIBRARY)); - if(shared) - { - flags += "-D"; - if(const char* custom_export_name = target.GetProperty("DEFINE_SYMBOL")) - { - flags += custom_export_name; - } - else - { - std::string in = target.GetName(); - in += "_EXPORTS"; - flags += cmSystemTools::MakeCindentifier(in.c_str()); - } - } - - // Add language-specific flags. - this->AddLanguageFlags(flags, lang); - - // Add shared-library flags if needed. - this->AddSharedFlags(flags, lang, shared); - - // Add include directory flags. - this->AppendFlags(flags, this->GetIncludeFlags(lang)); - // Add include directory flags. - this->AppendFlags(flags, this->GetFrameworkFlags(target).c_str()); + // Add a space before the ":" to avoid drive letter confusion on + // Windows. + space = " "; + } - flagFileStream << lang << "_FLAGS = " << flags - << "\n" - << "\n"; + // Write the rule. + if(depends.empty()) + { + // No dependencies. The commands will always run. + os << tgt.c_str() << space << ":\n"; } - - // write the custom commands for this target - std::vector cleanFiles; - // Look for files registered for cleaning in this directory. - if(const char* additional_clean_files = - m_Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) + else { - cmSystemTools::ExpandListArgument(additional_clean_files, cleanFiles); - } - this->WriteCustomCommands(ruleFileStream,cleanFiles); - - // Include the rule file for each object. - std::string relPath = this->GetHomeRelativeOutputPath(); - std::string objTarget; - - // Write the rule for this target type. - switch(target.GetType()) - { - case cmTarget::STATIC_LIBRARY: - this->WriteStaticLibraryRule(ruleFileStream, ruleFileName.c_str(), - target, objects, external_objects, - cleanFiles); - break; - case cmTarget::SHARED_LIBRARY: - this->WriteSharedLibraryRule(ruleFileStream, ruleFileName.c_str(), - target, objects, external_objects, - cleanFiles); - break; - case cmTarget::MODULE_LIBRARY: - this->WriteModuleLibraryRule(ruleFileStream, ruleFileName.c_str(), - target, objects, external_objects, - cleanFiles); - break; - case cmTarget::EXECUTABLE: - this->WriteExecutableRule(ruleFileStream, ruleFileName.c_str(), - target, objects, external_objects, - cleanFiles); - break; - default: - break; - } - - // Write the requires target. - this->WriteTargetRequiresRule(ruleFileStream, target, objects); - - // Write clean target - this->WriteTargetCleanRule(ruleFileStream, target, cleanFiles); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalUnixMakefileGenerator3 -::GetFrameworkFlags(cmTarget& -#ifdef __APPLE__ - target -#endif - ) -{ -#ifndef __APPLE__ - return std::string(); -#else - std::set emitted; - std::vector includes; - this->GetIncludeDirectories(includes); - std::vector::iterator i; - // check all include directories for frameworks as this - // will already have added a -F for the framework - for(i = includes.begin(); i != includes.end(); ++i) - { - if(cmSystemTools::IsPathToFramework(i->c_str())) + // Split dependencies into multiple rule lines. This allows for + // very long dependency lists even on older make implementations. + for(std::vector::const_iterator dep = depends.begin(); + dep != depends.end(); ++dep) { - std::string frameworkDir = *i; - frameworkDir += "/../"; - frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str()); - emitted.insert(frameworkDir); + replace = *dep; + replace = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE); + replace = this->ConvertToMakeTarget(replace.c_str()); + os << tgt.c_str() << space << ": " << replace.c_str() << "\n"; } } - std::string flags; - std::vector& frameworks = target.GetFrameworks(); - for(i = frameworks.begin(); - i != frameworks.end(); ++i) + // Write the list of commands. + for(std::vector::const_iterator i = commands.begin(); + i != commands.end(); ++i) { - if(emitted.insert(*i).second) - { - flags += "-F"; - flags += this->ConvertToOutputForExisting(i->c_str()); - flags += " "; - } + replace = *i; + os << "\t" << replace.c_str() << "\n"; } - return flags; -#endif + os << "\n"; } //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 -::WriteObjectDependRules(cmSourceFile& source, - std::vector& depends) -{ - // Create the list of dependencies known at cmake time. These are - // shared between the object file and dependency scanning rule. - depends.push_back(source.GetFullPath()); - if(const char* objectDeps = source.GetProperty("OBJECT_DEPENDS")) - { - std::vector deps; - cmSystemTools::ExpandListArgument(objectDeps, deps); - for(std::vector::iterator i = deps.begin(); - i != deps.end(); ++i) - { - depends.push_back(i->c_str()); - } - } -} - - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteObjectBuildFile(std::string &obj, - const char *lang, - cmTarget& target, - cmSourceFile& source, - std::vector& depends, - std::ostream &ruleFileStream, - std::ostream &flagFileStream) -{ - // Open the rule file for writing. This should be copy-if-different - // because the rules may depend on this file itself. - std::string ruleFileName = m_Makefile->GetStartOutputDirectory(); - ruleFileName += "/"; - ruleFileName += this->GetTargetDirectory(target); - ruleFileName += "/build.make"; - std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName); - - std::string flagFileName = this->GetTargetDirectory(target); - flagFileName += "/flags.make"; - std::string flagFileNameFull = this->ConvertToFullPath(flagFileName); - this->AppendRuleDepend(depends, flagFileNameFull.c_str()); - - // generate the depend scanning rule - this->WriteObjectDependRules(source, depends); - - std::string relativeObj = this->GetHomeRelativeOutputPath(); - relativeObj += obj; - if(m_Makefile->GetDefinition("CMAKE_WINDOWS_OBJECT_PATH")) - { - relativeObj = cmSystemTools::ConvertToOutputPath(relativeObj.c_str()); - } - // Write the build rule. - // Build the set of compiler flags. - std::string flags; - if(target.GetProperty("COMPILE_FLAGS")) - { - this->AppendFlags(flags, target.GetProperty("COMPILE_FLAGS")); - } - - // Add flags from source file properties. - if (source.GetProperty("COMPILE_FLAGS")) - { - this->AppendFlags(flags, source.GetProperty("COMPILE_FLAGS")); - flagFileStream << "# Custom flags: " - << relativeObj << "_FLAGS = " - << source.GetProperty("COMPILE_FLAGS") - << "\n" - << "\n"; - } - - // Add language-specific flags. - std::string langFlags = "$("; - langFlags += lang; - langFlags += "_FLAGS)"; - this->AppendFlags(flags, langFlags.c_str()); - - // Get the output paths for source and object files. - std::string sourceFile = source.GetFullPath(); - if(m_UseRelativePaths) - { - sourceFile = this->Convert(sourceFile.c_str(),HOME_OUTPUT); - } - sourceFile = this->Convert(sourceFile.c_str(),NONE,SHELL); - std::string objectFile = this->Convert(obj.c_str(),START_OUTPUT,SHELL); - - // Construct the build message. - std::vector no_commands; - std::vector commands; - std::string buildEcho = "Building "; - buildEcho += lang; - buildEcho += " object "; - buildEcho += relativeObj; - this->AppendEcho(commands, buildEcho.c_str()); - - // Construct the compile rules. - std::string compileRuleVar = "CMAKE_"; - compileRuleVar += lang; - compileRuleVar += "_COMPILE_OBJECT"; - std::string compileRule = - m_Makefile->GetRequiredDefinition(compileRuleVar.c_str()); - cmSystemTools::ExpandListArgument(compileRule, commands); - - // Expand placeholders in the commands. - for(std::vector::iterator i = commands.begin(); - i != commands.end(); ++i) - { - this->ExpandRuleVariables(*i, - lang, - 0, // no objects - 0, // no target - 0, // no link libs - sourceFile.c_str(), - relativeObj.c_str(), - flags.c_str()); - } - - // Make the target dependency scanning rule include cmake-time-known - // dependencies. The others are handled by the check-build-system - // path. - std::string depMark = this->GetRelativeTargetDirectory(target); - depMark += "/depend.make.mark"; - this->WriteMakeRule(ruleFileStream, 0, - depMark.c_str(), depends, no_commands); - - // Write the rule. - this->WriteMakeRule(ruleFileStream, 0, - relativeObj.c_str(), depends, commands); - - // If the language needs provides-requires mode, create the - // corresponding targets. - std::string objectRequires = relativeObj; - objectRequires += ".requires"; - std::vector p_depends; - // always provide an empty requires target - this->WriteMakeRule(ruleFileStream, 0, - objectRequires.c_str(), p_depends, no_commands); - - // write a build rule to recursively build what this obj provides - std::string objectProvides = relativeObj; - objectProvides += ".provides"; - std::string temp = relativeObj; - temp += ".provides.build"; - std::vector r_commands; - std::string tgtMakefileName = this->GetRelativeTargetDirectory(target); - tgtMakefileName += "/build.make"; - r_commands.push_back(this->GetRecursiveMakeCall(tgtMakefileName.c_str(), - temp.c_str())); - p_depends.clear(); - p_depends.push_back(objectRequires); - this->WriteMakeRule(ruleFileStream, 0, - objectProvides.c_str(), p_depends, r_commands); - - // write the provides.build rule dependency on the obj file - p_depends.clear(); - p_depends.push_back(relativeObj); - this->WriteMakeRule(ruleFileStream, 0, - temp.c_str(), p_depends, no_commands); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteObjectRuleFiles(cmTarget& target, cmSourceFile& source, - std::vector& objects, - std::ostream &ruleFileStream, - std::ostream &flagFileStream) -{ - // 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 objNoTargetDir; - std::string obj = this->GetObjectFileName(target, source, &objNoTargetDir); - // 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 depends; - std::string depMakeFile; - - // generate the build rule file - this->WriteObjectBuildFile(obj, lang, target, source, depends, - ruleFileStream, flagFileStream); - - // The object file should be checked for dependency integrity. - m_CheckDependFiles[target.GetName()][lang].insert(&source); - // add this to the list of objects for this local generator - if(cmSystemTools::FileIsFullPath(objNoTargetDir.c_str())) - { - objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir); - } - m_LocalObjectFiles[objNoTargetDir].push_back(&target); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::GenerateCustomRuleFile(const cmCustomCommand& cc, - std::ostream &ruleFileStream) -{ - // Convert the output name to a relative path if possible. - std::string output = this->Convert(cc.GetOutput(),START_OUTPUT); - - // Collect the commands. - std::vector commands; - std::string preEcho = "Generating "; - preEcho += output; - this->AppendEcho(commands, preEcho.c_str()); - this->AppendCustomCommand(commands, cc); - - // Collect the dependencies. - std::vector depends; - this->AppendCustomDepend(depends, cc); - - // Write the rule. - const char* comment = 0; - if(cc.GetComment() && *cc.GetComment()) - { - comment = cc.GetComment(); - } - this->WriteMakeRule(ruleFileStream, comment, - cc.GetOutput(), depends, commands); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteUtilityRuleFiles(cmTarget& target) -{ - // Create a directory for this target. - std::string dir = this->GetTargetDirectory(target); - cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str()); - - // Construct the name of the rule file. - std::string ruleFileName = dir; - ruleFileName += "/build.make"; - - // 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); - cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str()); - ruleFileStream.SetCopyIfDifferent(true); - if(!ruleFileStream) - { - return; - } - this->WriteDisclaimer(ruleFileStream); - this->WriteMakeVariables(ruleFileStream); - ruleFileStream - << "# Utility rule file for " << target.GetName() << ".\n\n"; - - // write the custom commands for this target - std::vector cleanFiles; - if(const char* additional_clean_files = - m_Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) - { - cmSystemTools::ExpandListArgument(additional_clean_files, cleanFiles); - } - this->WriteCustomCommands(ruleFileStream, cleanFiles); - - // Collect the commands and dependencies. - std::vector commands; - std::vector depends; - const char* sym = m_Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE"); - if(sym) - { - depends.push_back(sym); - } - - // Utility targets store their rules in pre- and post-build commands. - this->AppendCustomDepends(depends, target.GetPreBuildCommands()); - this->AppendCustomDepends(depends, target.GetPostBuildCommands()); - this->AppendCustomCommands(commands, target.GetPreBuildCommands()); - this->AppendCustomCommands(commands, target.GetPostBuildCommands()); - - // Add dependencies on targets that must be built first. - this->AppendTargetDepends(depends, target); - - // Add a dependency on the rule file itself. - std::string relPath = this->GetHomeRelativeOutputPath(); - std::string objTarget = relPath; - objTarget += ruleFileName; - this->AppendRuleDepend(depends, objTarget.c_str()); - - // Write the rule. - this->WriteMakeRule(ruleFileStream, 0, - target.GetName(), depends, commands); - - // Write convenience targets. - dir = m_Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += this->GetTargetDirectory(target); - std::string buildTargetRuleName = dir; - buildTargetRuleName += "/build"; - buildTargetRuleName = - this->Convert(buildTargetRuleName.c_str(),HOME_OUTPUT,MAKEFILE); - this->WriteConvenienceRule(ruleFileStream, target.GetName(), - buildTargetRuleName.c_str()); - - // Write clean target - this->WriteTargetCleanRule(ruleFileStream, target, cleanFiles); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteMakeRule(std::ostream& os, - const char* comment, - const char* target, - const std::vector& depends, - const std::vector& commands) -{ - // Make sure there is a target. - if(!target || !*target) - { - cmSystemTools::Error("No target for WriteMakeRule! called with comment: ", - comment); - return; - } - - std::string replace; - - // Write the comment describing the rule in the makefile. - if(comment) - { - replace = comment; - std::string::size_type lpos = 0; - std::string::size_type rpos; - while((rpos = replace.find('\n', lpos)) != std::string::npos) - { - os << "# " << replace.substr(lpos, rpos-lpos) << "\n"; - lpos = rpos+1; - } - os << "# " << replace.substr(lpos) << "\n"; - } - - // Construct the left hand side of the rule. - replace = target; - std::string tgt = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE); - tgt = this->ConvertToMakeTarget(tgt.c_str()); - const char* space = ""; - if(tgt.size() == 1) - { - // Add a space before the ":" to avoid drive letter confusion on - // Windows. - space = " "; - } - - // Write the rule. - if(depends.empty()) - { - // No dependencies. The commands will always run. - os << tgt.c_str() << space << ":\n"; - } - else - { - // Split dependencies into multiple rule lines. This allows for - // very long dependency lists even on older make implementations. - for(std::vector::const_iterator dep = depends.begin(); - dep != depends.end(); ++dep) - { - replace = *dep; - replace = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE); - replace = this->ConvertToMakeTarget(replace.c_str()); - os << tgt.c_str() << space << ": " << replace.c_str() << "\n"; - } - } - - // Write the list of commands. - for(std::vector::const_iterator i = commands.begin(); - i != commands.end(); ++i) - { - replace = *i; - os << "\t" << replace.c_str() << "\n"; - } - os << "\n"; -} - -//---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os) -{ - os - << "#======================================" - << "=======================================\n"; -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteMakeVariables(std::ostream& makefileStream) +::WriteMakeVariables(std::ostream& makefileStream) { this->WriteDivider(makefileStream); makefileStream @@ -1308,1060 +810,74 @@ cmLocalUnixMakefileGenerator3 } } + //---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteTargetRequiresRule(std::ostream& ruleFileStream, cmTarget& target, - const std::vector& objects) +std::string +cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory(cmTarget& target) { - std::vector depends; - std::vector no_commands; + std::string dir = m_Makefile->GetStartOutputDirectory(); + dir += "/"; + dir += this->GetTargetDirectory(target); + dir = cmSystemTools::RelativePath(m_Makefile->GetHomeOutputDirectory(), dir.c_str()); + return this->Convert(dir.c_str(),NONE,MAKEFILE); +} + - // Construct the name of the dependency generation target. - std::string depTarget = this->GetRelativeTargetDirectory(target); - depTarget += "/requires"; - // This target drives dependency generation for all object files. - std::string relPath = this->GetHomeRelativeOutputPath(); - std::string objTarget; - for(std::vector::const_iterator obj = objects.begin(); - obj != objects.end(); ++obj) +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator3 +::AppendRuleDepend(std::vector& depends, + const char* ruleFileName) +{ + // Add a dependency on the rule file itself unless an option to skip + // it is specifically enabled by the user or project. + const char* nodep = m_Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY"); + if(!nodep || cmSystemTools::IsOff(nodep)) { - objTarget = relPath; - objTarget += *obj; - objTarget += ".requires"; - depends.push_back(objTarget); + depends.push_back(ruleFileName); } - - // Write the rule. - this->WriteMakeRule(ruleFileStream, 0, - depTarget.c_str(), depends, no_commands); } //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3 -::WriteExecutableRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::vector& cleanFiles) +::AppendCustomDepends(std::vector& depends, + const std::vector& ccs) { - // Write the dependency generation rule. - this->WriteTargetDependRule(ruleFileStream, target); - - std::vector commands; - - std::string relPath = this->GetHomeRelativeOutputPath(); - std::string objTarget; - - // Build list of dependencies. - std::vector depends; - for(std::vector::const_iterator obj = objects.begin(); - obj != objects.end(); ++obj) + for(std::vector::const_iterator i = ccs.begin(); + i != ccs.end(); ++i) { - objTarget = relPath; - objTarget += *obj; - depends.push_back(objTarget); + this->AppendCustomDepend(depends, *i); } +} - // Add dependencies on targets that must be built first. - this->AppendTargetDepends(depends, target); - - // Add a dependency on the rule file itself. - this->AppendRuleDepend(depends, ruleFileName); - - for(std::vector::const_iterator obj = external_objects.begin(); - obj != external_objects.end(); ++obj) +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator3 +::AppendCustomDepend(std::vector& depends, + const cmCustomCommand& cc) +{ + for(std::vector::const_iterator d = cc.GetDepends().begin(); + d != cc.GetDepends().end(); ++d) { - depends.push_back(*obj); + // Lookup the real name of the dependency in case it is a CMake target. + std::string dep = this->GetRealDependency(d->c_str(), + m_ConfigurationName.c_str()); + depends.push_back(dep); } +} - // from here up is the same for exe or lib - - // Get the name of the executable to generate. - std::string targetName; - std::string targetNameReal; - target.GetExecutableNames(targetName, targetNameReal, - m_ConfigurationName.c_str()); - - // Construct the full path version of the names. - std::string outpath = m_ExecutableOutputPath; - if(outpath.length() == 0) +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator3 +::AppendCustomCommands(std::vector& commands, + const std::vector& ccs) +{ + for(std::vector::const_iterator i = ccs.begin(); + i != ccs.end(); ++i) { - outpath = m_Makefile->GetStartOutputDirectory(); - outpath += "/"; - } -#ifdef __APPLE__ - if(target.GetPropertyAsBool("MACOSX_BUNDLE")) - { - // Make bundle directories - outpath += target.GetName(); - outpath += ".app/Contents/MacOS/"; - std::string f1 = m_Makefile->GetModulesFile("MacOSXBundleInfo.plist.in"); - if ( f1.size() == 0 ) - { - cmSystemTools::Error("could not find Mac OSX bundle template file."); - } - std::string macdir = m_Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH"); - if ( macdir.size() == 0 ) - { - macdir = m_Makefile->GetCurrentOutputDirectory(); - } - if(macdir.size() && macdir[macdir.size()-1] != '/') - { - macdir += "/"; - } - macdir += target.GetName(); - macdir += ".app/Contents/"; - std::string f2 = macdir + "Info.plist"; - macdir += "MacOS"; - cmSystemTools::MakeDirectory(macdir.c_str()); - m_Makefile->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", target.GetName()); - m_Makefile->ConfigureFile(f1.c_str(), f2.c_str(), false, false, false); - } -#endif - std::string targetFullPath = outpath + targetName; - std::string targetFullPathReal = outpath + targetNameReal; - - // Convert to the output path to use in constructing commands. - std::string targetOutPath = - this->Convert(targetFullPath.c_str(),START_OUTPUT,MAKEFILE); - std::string targetOutPathReal = - this->Convert(targetFullPathReal.c_str(),START_OUTPUT,MAKEFILE); - - // Get the language to use for linking this executable. - const char* linkLanguage = - target.GetLinkerLanguage(this->GetGlobalGenerator()); - - // Make sure we have a link language. - if(!linkLanguage) - { - cmSystemTools::Error("Cannot determine link language for target \"", - target.GetName(), "\"."); - return; - } - - // Add the link message. - std::string buildEcho = "Linking "; - buildEcho += linkLanguage; - buildEcho += " executable "; - buildEcho += targetOutPath; - this->AppendEcho(commands, buildEcho.c_str()); - - // Build a list of compiler flags and linker flags. - std::string flags; - std::string linkFlags; - - // Add flags to deal with shared libraries. Any library being - // linked in might be shared, so always use shared flags for an - // executable. - this->AddSharedFlags(linkFlags, linkLanguage, true); - - // Add flags to create an executable. - this->AddConfigVariableFlags(linkFlags, "CMAKE_EXE_LINKER_FLAGS"); - - - if(target.GetPropertyAsBool("WIN32_EXECUTABLE")) - { - this->AppendFlags(linkFlags, - m_Makefile->GetDefinition("CMAKE_CREATE_WIN32_EXE")); - } - else - { - this->AppendFlags(linkFlags, - m_Makefile->GetDefinition("CMAKE_CREATE_CONSOLE_EXE")); - } - - // Add language-specific flags. - this->AddLanguageFlags(flags, linkLanguage); - - // Add target-specific linker flags. - this->AppendFlags(linkFlags, target.GetProperty("LINK_FLAGS")); - - // Construct a list of files associated with this executable that - // may need to be cleaned. - std::vector exeCleanFiles; - { - std::string cleanName; - std::string cleanRealName; - target.GetExecutableCleanNames(cleanName, cleanRealName, - m_ConfigurationName.c_str()); - std::string cleanFullName = outpath + cleanName; - std::string cleanFullRealName = outpath + cleanRealName; - exeCleanFiles.push_back - (this->Convert(cleanFullName.c_str(),START_OUTPUT,MAKEFILE)); - if(cleanRealName != cleanName) - { - exeCleanFiles.push_back - (this->Convert(cleanFullRealName.c_str(),START_OUTPUT,MAKEFILE)); - } - } - - // Add a command to remove any existing files for this executable. - std::vector commands1; - this->AppendCleanCommand(commands1, exeCleanFiles); - this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(), - m_Makefile->GetHomeOutputDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); - commands1.clear(); - // Add the pre-build and pre-link rules. - this->AppendCustomCommands(commands, target.GetPreBuildCommands()); - this->AppendCustomCommands(commands, target.GetPreLinkCommands()); - - // Construct the main link rule. - std::string linkRuleVar = "CMAKE_"; - linkRuleVar += linkLanguage; - linkRuleVar += "_LINK_EXECUTABLE"; - std::string linkRule = - m_Makefile->GetRequiredDefinition(linkRuleVar.c_str()); - cmSystemTools::ExpandListArgument(linkRule, commands1); - this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(), - m_Makefile->GetHomeOutputDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); - - // Add a rule to create necessary symlinks for the library. - if(targetOutPath != targetOutPathReal) - { - std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_executable "; - symlink += targetOutPathReal; - symlink += " "; - symlink += targetOutPath; - commands.push_back(symlink); - } - - // Add the post-build rules. - this->AppendCustomCommands(commands, target.GetPostBuildCommands()); - - // Collect up flags to link in needed libraries. - cmOStringStream linklibs; - this->OutputLinkLibraries(linklibs, target); - - // Construct object file lists that may be needed to expand the - // rule. - std::string variableName; - std::string variableNameExternal; - this->WriteObjectsVariable(ruleFileStream, target, objects, external_objects, - variableName, variableNameExternal); - std::string buildObjs = "$("; - buildObjs += variableName; - buildObjs += ") $("; - buildObjs += variableNameExternal; - buildObjs += ")"; - std::string cleanObjs = "$("; - cleanObjs += variableName; - cleanObjs += ")"; - - // Expand placeholders in the commands. - for(std::vector::iterator i = commands.begin(); - i != commands.end(); ++i) - { - this->ExpandRuleVariables(*i, - linkLanguage, - buildObjs.c_str(), - targetOutPathReal.c_str(), - linklibs.str().c_str(), - 0, - 0, - flags.c_str(), - 0, - 0, - linkFlags.c_str()); - } - - // Write the build rule. - this->WriteMakeRule(ruleFileStream, 0, - targetFullPathReal.c_str(), depends, commands); - - // The symlink name for the target should depend on the real target - // so if the target version changes it rebuilds and recreates the - // symlink. - if(targetFullPath != targetFullPathReal) - { - depends.clear(); - commands.clear(); - depends.push_back(targetFullPathReal.c_str()); - this->WriteMakeRule(ruleFileStream, 0, - targetFullPath.c_str(), depends, commands); - } - - // Write convenience targets. - std::string dir = m_Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += this->GetTargetDirectory(target); - std::string buildTargetRuleName = dir; - buildTargetRuleName += "/build"; - buildTargetRuleName = - this->Convert(buildTargetRuleName.c_str(),HOME_OUTPUT,MAKEFILE); - this->WriteConvenienceRule(ruleFileStream, targetFullPath.c_str(), - buildTargetRuleName.c_str()); - - // Clean all the possible executable names and symlinks and object files. - cleanFiles.insert(cleanFiles.end(),exeCleanFiles.begin(),exeCleanFiles.end()); - cleanFiles.push_back(cleanObjs); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteStaticLibraryRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::vector& cleanFiles) -{ - const char* linkLanguage = - target.GetLinkerLanguage(this->GetGlobalGenerator()); - std::string linkRuleVar = "CMAKE_"; - if (linkLanguage) - { - linkRuleVar += linkLanguage; - } - linkRuleVar += "_CREATE_STATIC_LIBRARY"; - - std::string extraFlags; - this->AppendFlags(extraFlags, target.GetProperty("STATIC_LIBRARY_FLAGS")); - this->WriteLibraryRule(ruleFileStream, ruleFileName, target, - objects, external_objects, - linkRuleVar.c_str(), extraFlags.c_str(),cleanFiles); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteSharedLibraryRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::vector& cleanFiles) -{ - const char* linkLanguage = - target.GetLinkerLanguage(this->GetGlobalGenerator()); - std::string linkRuleVar = "CMAKE_"; - if (linkLanguage) - { - linkRuleVar += linkLanguage; - } - linkRuleVar += "_CREATE_SHARED_LIBRARY"; - - std::string extraFlags; - this->AppendFlags(extraFlags, target.GetProperty("LINK_FLAGS")); - this->AddConfigVariableFlags(extraFlags, "CMAKE_SHARED_LINKER_FLAGS"); - if(m_Makefile->IsOn("WIN32") && !(m_Makefile->IsOn("CYGWIN") || m_Makefile->IsOn("MINGW"))) - { - const std::vector& sources = target.GetSourceFiles(); - for(std::vector::const_iterator i = sources.begin(); - i != sources.end(); ++i) - { - if((*i)->GetSourceExtension() == "def") - { - extraFlags += " "; - extraFlags += m_Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); - extraFlags += - this->Convert((*i)->GetFullPath().c_str(),START_OUTPUT,MAKEFILE); - } - } - } - this->WriteLibraryRule(ruleFileStream, ruleFileName, target, - objects, external_objects, - linkRuleVar.c_str(), extraFlags.c_str(), cleanFiles); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteModuleLibraryRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::vector& cleanFiles) -{ - const char* linkLanguage = - target.GetLinkerLanguage(this->GetGlobalGenerator()); - std::string linkRuleVar = "CMAKE_"; - if (linkLanguage) - { - linkRuleVar += linkLanguage; - } - linkRuleVar += "_CREATE_SHARED_MODULE"; - - std::string extraFlags; - this->AppendFlags(extraFlags, target.GetProperty("LINK_FLAGS")); - this->AddConfigVariableFlags(extraFlags, "CMAKE_MODULE_LINKER_FLAGS"); - // TODO: .def files should be supported here also. - this->WriteLibraryRule(ruleFileStream, ruleFileName, target, - objects, external_objects, - linkRuleVar.c_str(), extraFlags.c_str(), cleanFiles); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteLibraryRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - const char* linkRuleVar, - const char* extraFlags, - std::vector& cleanFiles) -{ - // Write the dependency generation rule. - this->WriteTargetDependRule(ruleFileStream, target); - - // TODO: Merge the methods that call this method to avoid - // code duplication. - std::vector commands; - - std::string relPath = this->GetHomeRelativeOutputPath(); - std::string objTarget; - - // Build list of dependencies. - std::vector depends; - for(std::vector::const_iterator obj = objects.begin(); - obj != objects.end(); ++obj) - { - objTarget = relPath; - objTarget += *obj; - depends.push_back(objTarget); - } - - // Add dependencies on targets that must be built first. - this->AppendTargetDepends(depends, target); - - // Add a dependency on the rule file itself. - this->AppendRuleDepend(depends, ruleFileName); - - for(std::vector::const_iterator obj = external_objects.begin(); - obj != external_objects.end(); ++obj) - { - depends.push_back(*obj); - } - - // from here up is the same for exe or lib - - // Get the language to use for linking this library. - const char* linkLanguage = - target.GetLinkerLanguage(this->GetGlobalGenerator()); - - // Make sure we have a link language. - if(!linkLanguage) - { - cmSystemTools::Error("Cannot determine link language for target \"", - target.GetName(), "\"."); - return; - } - - // Create set of linking flags. - std::string linkFlags; - this->AppendFlags(linkFlags, extraFlags); - - // Construct the name of the library. - std::string targetName; - std::string targetNameSO; - std::string targetNameReal; - target.GetLibraryNames(targetName, targetNameSO, targetNameReal, - m_ConfigurationName.c_str()); - - // Construct the full path version of the names. - std::string outpath = m_LibraryOutputPath; - if(outpath.length() == 0) - { - outpath = m_Makefile->GetStartOutputDirectory(); - outpath += "/"; - } - std::string targetFullPath = outpath + targetName; - std::string targetFullPathSO = outpath + targetNameSO; - std::string targetFullPathReal = outpath + targetNameReal; - - // Construct the output path version of the names for use in command - // arguments. - std::string targetOutPath = - this->Convert(targetFullPath.c_str(),START_OUTPUT,MAKEFILE); - std::string targetOutPathSO = - this->Convert(targetFullPathSO.c_str(),START_OUTPUT,MAKEFILE); - std::string targetOutPathReal = - this->Convert(targetFullPathReal.c_str(),START_OUTPUT,MAKEFILE); - - // Add the link message. - std::string buildEcho = "Linking "; - buildEcho += linkLanguage; - switch(target.GetType()) - { - case cmTarget::STATIC_LIBRARY: - buildEcho += " static library "; break; - case cmTarget::SHARED_LIBRARY: - buildEcho += " shared library "; break; - case cmTarget::MODULE_LIBRARY: - buildEcho += " shared module "; break; - default: - buildEcho += " library "; break; - } - buildEcho += targetOutPath.c_str(); - this->AppendEcho(commands, buildEcho.c_str()); - - // Construct a list of files associated with this library that may - // need to be cleaned. - std::vector libCleanFiles; - { - std::string cleanStaticName; - std::string cleanSharedName; - std::string cleanSharedSOName; - std::string cleanSharedRealName; - target.GetLibraryCleanNames(cleanStaticName, - cleanSharedName, - cleanSharedSOName, - cleanSharedRealName, - m_ConfigurationName.c_str()); - std::string cleanFullStaticName = outpath + cleanStaticName; - std::string cleanFullSharedName = outpath + cleanSharedName; - std::string cleanFullSharedSOName = outpath + cleanSharedSOName; - std::string cleanFullSharedRealName = outpath + cleanSharedRealName; - libCleanFiles.push_back - (this->Convert(cleanFullStaticName.c_str(),START_OUTPUT,MAKEFILE)); - if(cleanSharedRealName != cleanStaticName) - { - libCleanFiles.push_back - (this->Convert(cleanFullSharedRealName.c_str(),START_OUTPUT,MAKEFILE)); - } - if(cleanSharedSOName != cleanStaticName && - cleanSharedSOName != cleanSharedRealName) - { - libCleanFiles.push_back - (this->Convert(cleanFullSharedSOName.c_str(),START_OUTPUT,MAKEFILE)); - } - if(cleanSharedName != cleanStaticName && - cleanSharedName != cleanSharedSOName && - cleanSharedName != cleanSharedRealName) - { - libCleanFiles.push_back - (this->Convert(cleanFullSharedName.c_str(),START_OUTPUT,MAKEFILE)); - } - } - // Add a command to remove any existing files for this library. - std::vector commands1; - this->AppendCleanCommand(commands1, libCleanFiles); - this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(), - m_Makefile->GetHomeOutputDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); - commands1.clear(); - // Add the pre-build and pre-link rules. - this->AppendCustomCommands(commands, target.GetPreBuildCommands()); - this->AppendCustomCommands(commands, target.GetPreLinkCommands()); - - // Construct the main link rule. - std::string linkRule = m_Makefile->GetRequiredDefinition(linkRuleVar); - cmSystemTools::ExpandListArgument(linkRule, commands1); - this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(), - m_Makefile->GetHomeOutputDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); - - // Add a rule to create necessary symlinks for the library. - if(targetOutPath != targetOutPathReal) - { - std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library "; - symlink += targetOutPathReal; - symlink += " "; - symlink += targetOutPathSO; - symlink += " "; - symlink += targetOutPath; - commands1.clear(); - commands1.push_back(symlink); - this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(), - m_Makefile->GetHomeOutputDirectory()); - commands.insert(commands.end(), commands1.begin(), commands1.end()); - } - - // Add the post-build rules. - this->AppendCustomCommands(commands, target.GetPostBuildCommands()); - - // Collect up flags to link in needed libraries. - cmOStringStream linklibs; - this->OutputLinkLibraries(linklibs, target); - - // Construct object file lists that may be needed to expand the - // rule. - std::string variableName; - std::string variableNameExternal; - this->WriteObjectsVariable(ruleFileStream, target, objects, external_objects, - variableName, variableNameExternal); - std::string buildObjs = "$("; - buildObjs += variableName; - buildObjs += ") $("; - buildObjs += variableNameExternal; - buildObjs += ")"; - std::string cleanObjs = "$("; - cleanObjs += variableName; - cleanObjs += ")"; - - // Expand placeholders in the commands. - for(std::vector::iterator i = commands.begin(); - i != commands.end(); ++i) - { - this->ExpandRuleVariables(*i, - linkLanguage, - buildObjs.c_str(), - targetOutPathReal.c_str(), - linklibs.str().c_str(), - 0, 0, 0, buildObjs.c_str(), - targetNameSO.c_str(), - linkFlags.c_str()); - } - - // Write the build rule. - this->WriteMakeRule(ruleFileStream, 0, - targetFullPathReal.c_str(), depends, commands); - - // The symlink names for the target should depend on the real target - // so if the target version changes it rebuilds and recreates the - // symlinks. - if(targetFullPathSO != targetFullPathReal) - { - depends.clear(); - commands.clear(); - depends.push_back(targetFullPathReal.c_str()); - this->WriteMakeRule(ruleFileStream, 0, - targetFullPathSO.c_str(), depends, commands); - } - if(targetFullPath != targetFullPathSO) - { - depends.clear(); - commands.clear(); - depends.push_back(targetFullPathSO.c_str()); - this->WriteMakeRule(ruleFileStream, 0, - targetFullPath.c_str(), depends, commands); - } - - // Write convenience targets. - std::string dir = m_Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += this->GetTargetDirectory(target); - std::string buildTargetRuleName = dir; - buildTargetRuleName += "/build"; - buildTargetRuleName = - this->Convert(buildTargetRuleName.c_str(),HOME_OUTPUT,MAKEFILE); - this->WriteConvenienceRule(ruleFileStream, targetFullPath.c_str(), - buildTargetRuleName.c_str()); - - // Clean all the possible library names and symlinks and object files. - cleanFiles.insert(cleanFiles.end(),libCleanFiles.begin(),libCleanFiles.end()); - cleanFiles.push_back(cleanObjs); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteObjectsVariable(std::ostream& ruleFileStream, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::string& variableName, - std::string& variableNameExternal) -{ - // Write a make variable assignment that lists all objects for the - // target. - variableName = this->CreateMakeVariable(target.GetName(), "_OBJECTS"); - ruleFileStream - << "# Object files for target " << target.GetName() << "\n" - << variableName.c_str() << " ="; - std::string object; - const char* objName = m_Makefile->GetDefinition("CMAKE_NO_QUOTED_OBJECTS"); - const char* lineContinue = m_Makefile->GetDefinition("CMAKE_MAKE_LINE_CONTINUE"); - if(!lineContinue) - { - lineContinue = "\\"; - } - for(std::vector::const_iterator i = objects.begin(); - i != objects.end(); ++i) - { - ruleFileStream - << " " << lineContinue << "\n"; - if(objName) - { - ruleFileStream << this->Convert(i->c_str(), START_OUTPUT, MAKEFILE); - } - else - { - ruleFileStream << this->ConvertToQuotedOutputPath(i->c_str()); - } - } - ruleFileStream - << "\n"; - - // Write a make variable assignment that lists all external objects - // for the target. - variableNameExternal = this->CreateMakeVariable(target.GetName(), - "_EXTERNAL_OBJECTS"); - ruleFileStream - << "\n" - << "# External object files for target " << target.GetName() << "\n" - << variableNameExternal.c_str() << " ="; - for(std::vector::const_iterator i = external_objects.begin(); - i != external_objects.end(); ++i) - { - object = this->Convert(i->c_str(),START_OUTPUT); - ruleFileStream - << " " << lineContinue << "\n" - << m_Makefile->GetSafeDefinition("CMAKE_OBJECT_NAME"); - if(objName) - { - ruleFileStream << this->Convert(i->c_str(), START_OUTPUT, MAKEFILE); - } - else - { - ruleFileStream << this->ConvertToQuotedOutputPath(i->c_str()); - } - } - ruleFileStream - << "\n" - << "\n"; -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteTargetDependRule(std::ostream& ruleFileStream, cmTarget& target) -{ - // must write the targets depend info file - std::string dir = this->GetTargetDirectory(target); - std::string infoFileName = dir; - infoFileName += "/DependInfo.cmake"; - std::string ruleFileNameFull = this->ConvertToFullPath(infoFileName); - cmGeneratedFileStream infoFileStream(ruleFileNameFull.c_str()); - infoFileStream.SetCopyIfDifferent(true); - if(!infoFileStream) - { - return; - } - this->WriteDependLanguageInfo(infoFileStream,target); - - // and now write the rule to use it - std::vector depends; - std::vector commands; - - // Construct the name of the dependency generation target. - std::string depTarget = this->GetRelativeTargetDirectory(target); - depTarget += "/depend"; - - std::string depMark = depTarget; - depMark += ".make.mark"; - depends.push_back(depMark); - - this->WriteMakeRule(ruleFileStream, 0, - depTarget.c_str(), depends, commands); - depends.clear(); - - // Write the dependency generation rule. - std::string depEcho = "Scanning dependencies of target "; - depEcho += target.GetName(); - this->AppendEcho(commands, depEcho.c_str()); - - // Add a command to call CMake to scan dependencies. CMake will - // touch the corresponding depends file after scanning dependencies. - cmOStringStream depCmd; - // TODO: Account for source file properties and directory-level - // definitions when scanning for dependencies. - depCmd << "$(CMAKE_COMMAND) -E cmake_depends " - << " \"" - << m_GlobalGenerator->GetName() << "\" " - << this->Convert(m_Makefile->GetHomeOutputDirectory(),FULL,SHELL) - << " " - << this->Convert(m_Makefile->GetStartOutputDirectory(),FULL,SHELL) - << " " - << this->Convert(ruleFileNameFull.c_str(),FULL,SHELL); - commands.push_back(depCmd.str()); - - // Write the rule. - this->WriteMakeRule(ruleFileStream, 0, - depMark.c_str(), depends, commands); -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteTargetCleanRule(std::ostream& ruleFileStream, - cmTarget& target, - const std::vector& files) -{ - std::vector depends; - const char* sym = m_Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE"); - if(sym) - { - depends.push_back(sym); - } - std::vector commands; - - // Construct the clean target name. - std::string cleanTarget = this->GetRelativeTargetDirectory(target); - cleanTarget += "/clean"; - - // Construct the clean command. - this->AppendCleanCommand(commands, files); - this->CreateCDCommand(commands,m_Makefile->GetStartOutputDirectory(), - m_Makefile->GetHomeOutputDirectory()); - // Write the rule. - this->WriteMakeRule(ruleFileStream, 0, - cleanTarget.c_str(), depends, commands); -} - - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::WriteCMakeArgument(std::ostream& os, const char* s) -{ - // Write the given string to the stream with escaping to get it back - // into CMake through the lexical scanner. - os << "\""; - for(const char* c = s; *c; ++c) - { - if(*c == '\\') - { - os << "\\\\"; - } - else if(*c == '"') - { - os << "\\\""; - } - else - { - os << *c; - } - } - os << "\""; -} - -//---------------------------------------------------------------------------- -std::string -cmLocalUnixMakefileGenerator3::GetTargetDirectory(cmTarget& target) -{ - std::string dir = "CMakeFiles/"; - dir += target.GetName(); - dir += ".dir"; - return dir; -} - -//---------------------------------------------------------------------------- -std::string -cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory(cmTarget& target) -{ - std::string dir = m_Makefile->GetStartOutputDirectory(); - dir += "/"; - dir += this->GetTargetDirectory(target); - dir = cmSystemTools::RelativePath(m_Makefile->GetHomeOutputDirectory(), dir.c_str()); - return this->Convert(dir.c_str(),NONE,MAKEFILE); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalUnixMakefileGenerator3 -::GetObjectFileName(cmTarget& target, - const cmSourceFile& source, - std::string* nameWithoutTargetDir) -{ - // If the full path to the source file includes this directory, - // we want to use the relative path for the filename of the - // object file. Otherwise, we will use just the filename - // portion. - std::string objectName; - if((cmSystemTools::GetFilenamePath( - source.GetFullPath()).find( - m_Makefile->GetCurrentDirectory()) == 0) - || (cmSystemTools::GetFilenamePath( - source.GetFullPath()).find( - m_Makefile->GetStartOutputDirectory()) == 0)) - { - objectName = source.GetSourceName(); - } - else - { - objectName = cmSystemTools::GetFilenameName(source.GetSourceName()); - } - - // Append the object file extension. - objectName += - m_GlobalGenerator->GetLanguageOutputExtensionFromExtension( - source.GetSourceExtension().c_str()); - - // Convert to a safe name. - objectName = this->CreateSafeUniqueObjectFileName(objectName.c_str()); - // Prepend the target directory. - std::string obj = this->GetTargetDirectory(target); - obj += "/"; - obj += objectName; - if(nameWithoutTargetDir) - { - *nameWithoutTargetDir = objectName; - } - return obj; -} - -//---------------------------------------------------------------------------- -const char* -cmLocalUnixMakefileGenerator3 -::GetSourceFileLanguage(const cmSourceFile& source) -{ - // Identify the language of the source file. - return (m_GlobalGenerator - ->GetLanguageFromExtension(source.GetSourceExtension().c_str())); -} - -//---------------------------------------------------------------------------- -std::string -cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p) -{ - - // Split the path into its components. - std::vector components; - cmSystemTools::SplitPath(p, components); - - // Return an empty path if there are no components. - if(components.empty()) - { - return "\"\""; - } - - // Choose a slash direction and fix root component. - const char* slash = "/"; -#if defined(_WIN32) && !defined(__CYGWIN__) - if(!cmSystemTools::GetForceUnixPaths()) - { - slash = "\\"; - for(std::string::iterator i = components[0].begin(); - i != components[0].end(); ++i) - { - if(*i == '/') - { - *i = '\\'; - } - } - } -#endif - - // Begin the quoted result with the root component. - std::string result = "\""; - result += components[0]; - - // Now add the rest of the components separated by the proper slash - // direction for this platform. - bool first = true; - for(unsigned int i=1; i < components.size(); ++i) - { - // Only the last component can be empty to avoid double slashes. - if(components[i].length() > 0 || (i == (components.size()-1))) - { - if(!first) - { - result += slash; - } - result += components[i]; - first = false; - } - } - - // Close the quoted result. - result += "\""; - - return result; -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::AppendTargetDepends(std::vector& depends, - cmTarget& target) -{ - // Static libraries never depend on anything for linking. - if(target.GetType() == cmTarget::STATIC_LIBRARY) - { - return; - } - - // Keep track of dependencies already listed. - std::set emitted; - - // A target should not depend on itself. - emitted.insert(target.GetName()); - - // Loop over all library dependencies. - const cmTarget::LinkLibraries& tlibs = target.GetLinkLibraries(); - for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin(); - lib != tlibs.end(); ++lib) - { - // Don't emit the same library twice for this target. - if(emitted.insert(lib->first).second) - { - // Depend only on other CMake targets. - if(cmTarget* tgt = m_GlobalGenerator->FindTarget(0, lib->first.c_str())) - { - if(const char* location = - tgt->GetLocation(m_ConfigurationName.c_str())) - { - depends.push_back(location); - } - } - } - } -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::AppendRuleDepend(std::vector& depends, - const char* ruleFileName) -{ - // Add a dependency on the rule file itself unless an option to skip - // it is specifically enabled by the user or project. - const char* nodep = m_Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY"); - if(!nodep || cmSystemTools::IsOff(nodep)) - { - depends.push_back(ruleFileName); - } -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::AppendCustomDepends(std::vector& depends, - const std::vector& ccs) -{ - for(std::vector::const_iterator i = ccs.begin(); - i != ccs.end(); ++i) - { - this->AppendCustomDepend(depends, *i); - } -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::AppendCustomDepend(std::vector& depends, - const cmCustomCommand& cc) -{ - for(std::vector::const_iterator d = cc.GetDepends().begin(); - d != cc.GetDepends().end(); ++d) - { - // Lookup the real name of the dependency in case it is a CMake target. - std::string dep = this->GetRealDependency(d->c_str(), - m_ConfigurationName.c_str()); - depends.push_back(dep); - } -} - -//---------------------------------------------------------------------------- -void -cmLocalUnixMakefileGenerator3 -::AppendCustomCommands(std::vector& commands, - const std::vector& ccs) -{ - for(std::vector::const_iterator i = ccs.begin(); - i != ccs.end(); ++i) - { - this->AppendCustomCommand(commands, *i); + this->AppendCustomCommand(commands, *i); } } @@ -2410,15 +926,15 @@ cmLocalUnixMakefileGenerator3 } // push back the custom commands - const char* dir =m_Makefile->GetStartOutputDirectory(); + const char* dir = m_Makefile->GetStartOutputDirectory(); // if the command specified a working directory use it. if(cc.GetWorkingDirectory()) { dir = cc.GetWorkingDirectory(); } - this->CreateCDCommand(commands1, dir, m_Makefile->GetHomeOutputDirectory()); + commands.insert(commands.end(), commands1.begin(), commands1.end()); } @@ -2514,7 +1030,8 @@ cmLocalUnixMakefileGenerator3::CreateSafeUniqueObjectFileName(const char* sin) { if ( m_Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES") ) { - std::map::iterator it = m_UniqueObjectNamesMap.find(sin); + std::map::iterator it = + m_UniqueObjectNamesMap.find(sin); if ( it == m_UniqueObjectNamesMap.end() ) { std::string ssin = sin; @@ -2870,11 +1387,11 @@ void cmLocalUnixMakefileGenerator3 dir = "all"; depends.push_back("cmake_check_build_system"); } - commands.push_back(this->GetRecursiveMakeCall - ("CMakeFiles/Makefile2",dir.c_str())); + commands.push_back + (this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str())); this->CreateCDCommand(commands, - m_Makefile->GetHomeOutputDirectory(), - m_Makefile->GetStartOutputDirectory()); + m_Makefile->GetHomeOutputDirectory(), + m_Makefile->GetStartOutputDirectory()); this->WriteMakeRule(ruleFileStream, "The main all target", "all", depends, commands); // Write the clean rule. @@ -2887,11 +1404,11 @@ void cmLocalUnixMakefileGenerator3 { depends.push_back(sym); } - commands.push_back(this->GetRecursiveMakeCall - ("CMakeFiles/Makefile2",dir.c_str())); + commands.push_back + (this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str())); this->CreateCDCommand(commands, - m_Makefile->GetHomeOutputDirectory(), - m_Makefile->GetStartOutputDirectory()); + m_Makefile->GetHomeOutputDirectory(), + m_Makefile->GetStartOutputDirectory()); this->WriteMakeRule(ruleFileStream, "The main clean target", "clean", depends, commands); // write the depend rule, really a recompute depends rule @@ -2916,133 +1433,292 @@ void cmLocalUnixMakefileGenerator3 depends, commands); } + //---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() +void cmLocalUnixMakefileGenerator3::CheckDependencies(cmMakefile* mf, + bool verbose, + bool clear) { - // generate the includes - std::string ruleFileName = "Makefile"; - - // 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); - cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str()); - if(!ruleFileStream) + // Get the list of target files to check + const char* infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES"); + if(!infoDef) { return; } - // always write the top makefile - if (m_Parent) + std::vector files; + cmSystemTools::ExpandListArgument(infoDef, files); + + // For each info file run the check + cmDependsC checker; + checker.SetVerbose(verbose); + checker.SetFileComparison(m_GlobalGenerator->GetCMakeInstance()->GetFileComparison()); + for(std::vector::iterator l = files.begin(); + l != files.end(); ++l) { - ruleFileStream.SetCopyIfDifferent(true); + // either clear or check the files + std::string dir = cmSystemTools::GetFilenamePath(l->c_str()); + std::string internalDependFile = dir + "/depend.internal"; + std::string dependFile = dir + "/depend.make"; + if (clear) + { + checker.Clear(internalDependFile.c_str()); + checker.Clear(dependFile.c_str()); + } + else + { + checker.Check(dependFile.c_str(), internalDependFile.c_str()); + } + } +} + + +void cmLocalUnixMakefileGenerator3 +::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target) +{ + // now write all the language stuff + // Set the set of files to check for dependency integrity. + std::set checkSetLangs; + std::map& + checkSet = this->GetIntegrityCheckSet()[target.GetName()]; + for(std::map::const_iterator + l = checkSet.begin(); l != checkSet.end(); ++l) + { + checkSetLangs.insert(l->first); } - // write the all rules - this->WriteLocalAllRules(ruleFileStream); + // list the languages + cmakefileStream + << "# The set of files whose dependency integrity should be checked:\n"; + cmakefileStream + << "SET(CMAKE_DEPENDS_LANGUAGES\n"; + for(std::set::iterator + l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l) + { + cmakefileStream << " \"" << l->c_str() << "\"\n"; + } + cmakefileStream << " )\n"; - // only write local targets unless at the top Keep track of targets already - // listed. - std::set emittedTargets; - if (m_Parent) + // now list the files for each language + for(std::set::iterator + l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l) { - // write our targets, and while doing it collect up the object - // file rules - this->WriteLocalMakefileTargets(ruleFileStream,emittedTargets); + cmakefileStream + << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n"; + // get the check set for this local gen and language + cmLocalUnixMakefileGenerator3::IntegrityCheckSet iCheckSet = + checkSet[*l]; + // for each file + for(cmLocalUnixMakefileGenerator3::IntegrityCheckSet::const_iterator + csIter = iCheckSet.begin(); + csIter != iCheckSet.end(); ++csIter) + { + cmakefileStream << " \"" << (*csIter)->GetFullPath() << "\"\n"; + // Get the full path name of the object file. + std::string obj = m_Makefile->GetStartOutputDirectory(); + obj += "/"; + obj += this->GetObjectFileName(target, **csIter); + cmakefileStream << " \"" << + this->Convert(obj.c_str(), + cmLocalGenerator::FULL).c_str() << "\"\n"; + } + cmakefileStream << " )\n"; + } +} + +//---------------------------------------------------------------------------- +std::string +cmLocalUnixMakefileGenerator3 +::GetObjectFileName(cmTarget& target, + const cmSourceFile& source, + std::string* nameWithoutTargetDir) +{ + // If the full path to the source file includes this directory, + // we want to use the relative path for the filename of the + // object file. Otherwise, we will use just the filename + // portion. + std::string objectName; + if((cmSystemTools::GetFilenamePath( + source.GetFullPath()).find( + m_Makefile->GetCurrentDirectory()) == 0) + || (cmSystemTools::GetFilenamePath( + source.GetFullPath()).find( + m_Makefile->GetStartOutputDirectory()) == 0)) + { + objectName = source.GetSourceName(); } else { - cmGlobalUnixMakefileGenerator3 *gg = - static_cast(m_GlobalGenerator); - gg->WriteConvenienceRules(ruleFileStream,emittedTargets); + objectName = cmSystemTools::GetFilenameName(source.GetSourceName()); + } + + // Append the object file extension. + objectName += + m_GlobalGenerator->GetLanguageOutputExtensionFromExtension( + source.GetSourceExtension().c_str()); + + // Convert to a safe name. + objectName = this->CreateSafeUniqueObjectFileName(objectName.c_str()); + // Prepend the target directory. + std::string obj = this->GetTargetDirectory(target); + obj += "/"; + obj += objectName; + if(nameWithoutTargetDir) + { + *nameWithoutTargetDir = objectName; } + return obj; +} + +//---------------------------------------------------------------------------- +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 +::GetRecursiveMakeCall(const char *Makefile, const char* tgt) +{ + // Call make on the given file. + std::string cmd; + cmd += "$(MAKE) -f "; + cmd += Makefile; + cmd += " "; - std::vector depends; - std::vector commands; + // Passg down verbosity level. + if(this->GetMakeSilentFlag().size()) + { + cmd += this->GetMakeSilentFlag(); + cmd += " "; + } - // now write out the object rules - // for each object file name - for (std::map >::iterator lo = - m_LocalObjectFiles.begin(); - lo != m_LocalObjectFiles.end(); ++lo) + // 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(this->GetPassMakeflags()) { - commands.clear(); - // for each target using the object file - for (std::vector::iterator to = - lo->second.begin(); to != lo->second.end(); ++to) + cmd += "-$(MAKEFLAGS) "; + } + + // Add the target. + if (tgt && tgt[0] != '\0') + { + std::string tgt2 = this->Convert(tgt,HOME_OUTPUT,MAKEFILE); + tgt2 = this->ConvertToMakeTarget(tgt2.c_str()); + cmd += tgt2; + } + return cmd; +} + +//---------------------------------------------------------------------------- +void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os) +{ + os + << "#======================================" + << "=======================================\n"; +} + +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator3 +::WriteCMakeArgument(std::ostream& os, const char* s) +{ + // Write the given string to the stream with escaping to get it back + // into CMake through the lexical scanner. + os << "\""; + for(const char* c = s; *c; ++c) + { + if(*c == '\\') { - std::string tgtMakefileName = this->GetRelativeTargetDirectory(**to); - std::string targetName = tgtMakefileName; - tgtMakefileName += "/build.make"; - targetName += "/"; - targetName += lo->first.c_str(); - commands.push_back(this->GetRecursiveMakeCall - (tgtMakefileName.c_str(),targetName.c_str())); - this->CreateCDCommand(commands, - m_Makefile->GetHomeOutputDirectory(), - m_Makefile->GetStartOutputDirectory()); + os << "\\\\"; + } + else if(*c == '"') + { + os << "\\\""; + } + else + { + os << *c; } - this->WriteMakeRule(ruleFileStream, - "target for object file", - lo->first.c_str(), depends, commands); } + os << "\""; +} - // add a help target as long as there isn;t a real target named help - if(emittedTargets.insert("help").second) +//---------------------------------------------------------------------------- +std::string +cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p) +{ + + // Split the path into its components. + std::vector components; + cmSystemTools::SplitPath(p, components); + + // Return an empty path if there are no components. + if(components.empty()) { - cmGlobalUnixMakefileGenerator3 *gg = - static_cast(m_GlobalGenerator); - gg->WriteHelpRule(ruleFileStream,this); + return "\"\""; } - this->WriteSpecialTargetsBottom(ruleFileStream); -} + // Choose a slash direction and fix root component. + const char* slash = "/"; +#if defined(_WIN32) && !defined(__CYGWIN__) + if(!cmSystemTools::GetForceUnixPaths()) + { + slash = "\\"; + for(std::string::iterator i = components[0].begin(); + i != components[0].end(); ++i) + { + if(*i == '/') + { + *i = '\\'; + } + } + } +#endif -void cmLocalUnixMakefileGenerator3 -::WriteLocalMakefileTargets(std::ostream& ruleFileStream, - std::set &emitted) -{ - std::vector depends; - std::vector commands; + // Begin the quoted result with the root component. + std::string result = "\""; + result += components[0]; - // for each target we just provide a rule to cd up to the top and do a make - // on the target - cmTargets& targets = m_Makefile->GetTargets(); - std::string localName; - for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) + // Now add the rest of the components separated by the proper slash + // direction for this platform. + bool first = true; + for(unsigned int i=1; i < components.size(); ++i) { - if((t->second.GetType() == cmTarget::EXECUTABLE) || - (t->second.GetType() == cmTarget::STATIC_LIBRARY) || - (t->second.GetType() == cmTarget::SHARED_LIBRARY) || - (t->second.GetType() == cmTarget::MODULE_LIBRARY) || - (t->second.GetType() == cmTarget::UTILITY)) + // Only the last component can be empty to avoid double slashes. + if(components[i].length() > 0 || (i == (components.size()-1))) { - emitted.insert(t->second.GetName()); - - // for subdirs add a rule to build this specific target by name. - localName = this->GetRelativeTargetDirectory(t->second); - localName += "/rule"; - commands.clear(); - depends.clear(); - - // Build the target for this pass. - commands.push_back(this->GetRecursiveMakeCall - ("CMakeFiles/Makefile2",localName.c_str())); - - this->CreateCDCommand(commands, - m_Makefile->GetHomeOutputDirectory(), - m_Makefile->GetStartOutputDirectory()); - 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()) + if(!first) { - commands.clear(); - depends.push_back(localName); - this->WriteMakeRule(ruleFileStream, "Convenience name for target.", - t->second.GetName(), depends, commands); + result += slash; } + result += components[i]; + first = false; } } + + // Close the quoted result. + result += "\""; + + return result; +} + +//---------------------------------------------------------------------------- +std::string +cmLocalUnixMakefileGenerator3::GetTargetDirectory(cmTarget& target) +{ + std::string dir = "CMakeFiles/"; + dir += target.GetName(); + dir += ".dir"; + return dir; } void cmLocalUnixMakefileGenerator3 @@ -3093,130 +1769,12 @@ void cmLocalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- -void cmLocalUnixMakefileGenerator3::CheckDependencies(cmMakefile* mf, - bool verbose, - bool clear) -{ - // Get the list of target files to check - const char* infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES"); - if(!infoDef) - { - return; - } - std::vector files; - cmSystemTools::ExpandListArgument(infoDef, files); - - // For each info file run the check - cmDependsC checker; - checker.SetVerbose(verbose); - checker.SetFileComparison(m_GlobalGenerator->GetCMakeInstance()->GetFileComparison()); - for(std::vector::iterator l = files.begin(); - l != files.end(); ++l) - { - // either clear or check the files - std::string dir = cmSystemTools::GetFilenamePath(l->c_str()); - std::string internalDependFile = dir + "/depend.internal"; - std::string dependFile = dir + "/depend.make"; - if (clear) - { - checker.Clear(internalDependFile.c_str()); - checker.Clear(dependFile.c_str()); - } - else - { - checker.Check(dependFile.c_str(), internalDependFile.c_str()); - } - } -} - -//---------------------------------------------------------------------------- -std::string +const char* cmLocalUnixMakefileGenerator3 -::GetRecursiveMakeCall(const char *Makefile, const char* tgt) +::GetSourceFileLanguage(const cmSourceFile& source) { - // Call make on the given file. - std::string cmd; - cmd += "$(MAKE) -f "; - cmd += Makefile; - cmd += " "; - - // Passg down verbosity level. - if(this->GetMakeSilentFlag().size()) - { - cmd += this->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(this->GetPassMakeflags()) - { - cmd += "-$(MAKEFLAGS) "; - } - - // Add the target. - if (tgt && tgt[0] != '\0') - { - std::string tgt2 = this->Convert(tgt,HOME_OUTPUT,MAKEFILE); - tgt2 = this->ConvertToMakeTarget(tgt2.c_str()); - cmd += tgt2; - } - return cmd; + // Identify the language of the source file. + return (m_GlobalGenerator + ->GetLanguageFromExtension(source.GetSourceExtension().c_str())); } - -void cmLocalUnixMakefileGenerator3 -::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target) -{ - // now write all the language stuff - // Set the set of files to check for dependency integrity. - std::set checkSetLangs; - std::map& - checkSet = this->GetIntegrityCheckSet()[target.GetName()]; - for(std::map::const_iterator - l = checkSet.begin(); l != checkSet.end(); ++l) - { - checkSetLangs.insert(l->first); - } - - // list the languages - cmakefileStream - << "# The set of files whose dependency integrity should be checked:\n"; - cmakefileStream - << "SET(CMAKE_DEPENDS_LANGUAGES\n"; - for(std::set::iterator - l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l) - { - cmakefileStream << " \"" << l->c_str() << "\"\n"; - } - cmakefileStream << " )\n"; - - // now list the files for each language - for(std::set::iterator - l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l) - { - cmakefileStream - << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n"; - // get the check set for this local gen and language - cmLocalUnixMakefileGenerator3::IntegrityCheckSet iCheckSet = - checkSet[*l]; - // for each file - for(cmLocalUnixMakefileGenerator3::IntegrityCheckSet::const_iterator - csIter = iCheckSet.begin(); - csIter != iCheckSet.end(); ++csIter) - { - cmakefileStream << " \"" << (*csIter)->GetFullPath() << "\"\n"; - // Get the full path name of the object file. - std::string obj = m_Makefile->GetStartOutputDirectory(); - obj += "/"; - obj += this->GetObjectFileName(target, **csIter); - cmakefileStream << " \"" << - this->Convert(obj.c_str(), - cmLocalGenerator::FULL).c_str() << "\"\n"; - } - cmakefileStream << " )\n"; - } -} diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index b0d2599..1f873ce 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -23,6 +23,7 @@ class cmCustomCommand; class cmDependInformation; class cmDepends; class cmMakeDepend; +class cmMakefileTargetGenerator; class cmTarget; class cmSourceFile; @@ -39,19 +40,29 @@ public: virtual ~cmLocalUnixMakefileGenerator3(); /** - * Generate the makefile for this directory. - */ - virtual void Generate(); - - /** * Process the CMakeLists files for this directory to fill in the * m_Makefile ivar */ virtual void Configure(); - /** creates the common disclainer text at the top of each makefile */ - void WriteDisclaimer(std::ostream& os); + /** + * Generate the makefile for this directory. + */ + virtual void Generate(); + + + + + + + + + + + + + // this returns the relative path between the HomeOutputDirectory and this // local generators StartOutputDirectory const std::string &GetHomeRelativeOutputPath(); @@ -66,9 +77,6 @@ public: // 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. @@ -83,10 +91,6 @@ public: void SetMakeSilentFlag(const char* s) { m_MakeSilentFlag = s; } std::string &GetMakeSilentFlag() { return m_MakeSilentFlag; } - /** used to create a recursive make call */ - std::string GetRecursiveMakeCall(const char *makefile, const char* tgt); - - /** Set whether the echo command needs its argument quoted. */ void SetEchoNeedsQuote(bool b) { m_EchoNeedsQuote = b; } @@ -134,8 +138,39 @@ public: */ void SetIgnoreLibPrefix(bool s) { m_IgnoreLibPrefix = s; } - + // used in writing out Cmake files such as WriteDirectoryInformation + static void WriteCMakeArgument(std::ostream& os, const char* s); + + /** creates the common disclainer text at the top of each makefile */ + void WriteDisclaimer(std::ostream& os); + + // write a comment line #====... in the stream + void WriteDivider(std::ostream& os); + + /** used to create a recursive make call */ + std::string GetRecursiveMakeCall(const char *makefile, const char* tgt); + // append an echo command + void AppendEcho(std::vector& commands, const char* text); + + static std::string GetTargetDirectory(cmTarget& target); + + // create a command that cds to the start dir then runs the commands + void CreateCDCommand(std::vector& commands, + const char *targetDir, const char *returnDir); + + static std::string ConvertToQuotedOutputPath(const char* p); + + std::string& CreateSafeUniqueObjectFileName(const char* sin); + std::string CreateMakeVariable(const char* sin, const char* s2in); + + // cleanup the name of a potential target + std::string ConvertToMakeTarget(const char* tgt); + + + const char* GetSourceFileLanguage(const cmSourceFile& source); + + /** Called from command-line hook to scan dependencies. */ @@ -145,10 +180,10 @@ public: virtual void CheckDependencies(cmMakefile* mf, bool verbose, bool clear); - /** write some extra rules suahc as make test etc */ + /** write some extra rules such as make test etc */ void WriteSpecialTargetsTop(std::ostream& makefileStream); - void WriteSpecialTargetsBottom(std::ostream& makefileStream); + std::string GetRelativeTargetDirectory(cmTarget& target); // List the files for which to check dependency integrity. Each @@ -159,140 +194,59 @@ public: std::map &GetIntegrityCheckSet() { return m_CheckDependFiles;} - void AppendTargetDepends(std::vector& depends, - cmTarget& target); - void AppendGlobalTargetDepends(std::vector& depends, cmTarget& target); - void AppendEcho(std::vector& commands, - const char* text); - // write the target rules for the local Makefile into the stream void WriteLocalAllRules(std::ostream& ruleFileStream); std::map > GetLocalObjectFiles() { return m_LocalObjectFiles;} + protected: - // Return the a string with -F flags on apple - std::string GetFrameworkFlags(cmTarget&); - - // write the depend info - void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt); + // these two methods just compute reasonable values for m_LibraryOutputPath + // and m_ExecutableOutputPath + void ConfigureOutputPaths(); + void FormatOutputPath(std::string& path, const char* name); + + void WriteLocalMakefile(); // write the target rules for the local Makefile into the stream void WriteLocalMakefileTargets(std::ostream& ruleFileStream, std::set &emitted); - // write the local help rule - void WriteHelpRule(std::ostream& ruleFileStream); + // this method Writes the Directory informaiton files + void WriteDirectoryInformationFile(); + + - // create a command that cds to the start dir then runs the commands - void CreateCDCommand(std::vector& commands, - const char *targetDir, const char *returnDir); - // 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(std::ostream& os, - std::vector& cleanFiles); - - // 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(cmTarget& target); - void WriteUtilityRuleFiles(cmTarget& target); - - // create the rule files for an object - void WriteObjectRuleFiles(cmTarget& target, - cmSourceFile& source, - std::vector& objects, - std::ostream &filestr, - std::ostream &flagstr); - - // write the build rule for an object - void WriteObjectBuildFile(std::string &obj, - const char *lang, - cmTarget& target, - cmSourceFile& source, - std::vector& depends, - std::ostream &filestr, - std::ostream &flagstr); - - // write the depend.make file for an object - void WriteObjectDependRules(cmSourceFile& source, - std::vector& depends); - - void GenerateCustomRuleFile(const cmCustomCommand& cc, - std::ostream &ruleStream); - - // these three make some simple changes and then call WriteLibraryRule - void WriteStaticLibraryRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::vector& cleanFiles); - - void WriteSharedLibraryRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::vector& cleanFiles); - - void WriteModuleLibraryRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::vector& cleanFiles); - - // the main code for writing the Executable target rules - void WriteExecutableRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::vector& cleanFiles); - - // the main method for writing library rules - void WriteLibraryRule(std::ostream& ruleFileStream, - const char* ruleFileName, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - const char* linkRuleVar, - const char* extraLinkFlags, - std::vector& cleanFiles); + + + + + + + // write the depend info + void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt); - void WriteLocalMakefile(); + // write the local help rule + void WriteHelpRule(std::ostream& ruleFileStream); + // this converts a file name that is relative to the StartOuputDirectory + // into a full path + std::string ConvertToFullPath(const std::string& localPath); + void WriteConvenienceRule(std::ostream& ruleFileStream, const char* realTarget, const char* helpTarget); - void WriteObjectsVariable(std::ostream& ruleFileStream, - cmTarget& target, - const std::vector& objects, - const std::vector& external_objects, - std::string& variableName, - std::string& variableNameExternal); + void WriteTargetDependRule(std::ostream& ruleFileStream, cmTarget& target); void WriteTargetCleanRule(std::ostream& ruleFileStream, @@ -302,12 +256,9 @@ protected: cmTarget& target, const std::vector& objects); - std::string GetTargetDirectory(cmTarget& target); std::string GetObjectFileName(cmTarget& target, const cmSourceFile& source, std::string* nameWithoutTargetDir = 0); - const char* GetSourceFileLanguage(const cmSourceFile& source); - std::string ConvertToQuotedOutputPath(const char* p); void AppendRuleDepend(std::vector& depends, const char* ruleFileName); @@ -322,20 +273,17 @@ protected: void AppendCleanCommand(std::vector& commands, const std::vector& files); - //========================================================================== - std::string& CreateSafeUniqueObjectFileName(const char* sin); - std::string CreateMakeVariable(const char* sin, const char* s2in); - //========================================================================== - private: + friend class cmMakefileTargetGenerator; + friend class cmMakefileExecutableTargetGenerator; + friend class cmMakefileLibraryTargetGenerator; + friend class cmMakefileUtilityTargetGenerator; + std::map m_CheckDependFiles; //========================================================================== // Configuration settings. int m_MakefileVariableSize; - std::map m_MakeVariableMap; - std::map m_ShortMakeVariableMap; - std::map m_UniqueObjectNamesMap; std::string m_IncludeDirective; std::string m_MakeSilentFlag; std::string m_ExecutableOutputPath; @@ -345,17 +293,19 @@ private: bool m_UnixCD; bool m_PassMakeflags; bool m_SilentNoColon; - //========================================================================== - // Flag for whether echo command needs quotes. bool m_EchoNeedsQuote; + //========================================================================== std::string m_HomeRelativeOutputPath; - // Set of object file names that will be built in this directory. - std::set m_ObjectFiles; - std::map > m_LocalObjectFiles; + + /* does the work for each target */ + std::vector TargetGenerators; + std::map m_MakeVariableMap; + std::map m_ShortMakeVariableMap; + std::map m_UniqueObjectNamesMap; }; #endif diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index eaf8f86..143cd7c 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -144,7 +144,7 @@ protected: return this->LocalGenerator->Convert(source, relative, output, optional); } - // constructor to set the ivarscmMakefileTargetGenerator + // constructor to set the ivars cmMakefileTargetGenerator(); }; diff --git a/bootstrap b/bootstrap index e76bbaa..30466cc 100755 --- a/bootstrap +++ b/bootstrap @@ -83,6 +83,10 @@ CMAKE_CXX_SOURCES="\ cmXCodeObject \ cmXCode21Object \ cmLocalUnixMakefileGenerator3 \ + cmMakefileExecutableTargetGenerator \ + cmMakefileLibraryTargetGenerator \ + cmMakefileTargetGenerator \ + cmMakefileUtilityTargetGenerator \ cmBootstrapCommands \ cmCommands \ cmTarget \ -- cgit v0.12