diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index f6d577c77..37c177b3b 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -22,7 +22,11 @@ #include //---------------------------------------------------------------------------- -cmDepends::cmDepends(): Verbose(false), FileComparison(0), +cmDepends::cmDepends(): + CompileDirectory(), + LocalGenerator(0), + Verbose(false), + FileComparison(0), MaxPath(cmSystemTools::GetMaximumFilePathLength()), Dependee(new char[MaxPath]), Depender(new char[MaxPath]) diff --git a/Source/cmDepends.h b/Source/cmDepends.h index ceb78bec5..b6eda70b2 100644 --- a/Source/cmDepends.h +++ b/Source/cmDepends.h @@ -20,6 +20,7 @@ #include "cmStandardIncludes.h" class cmFileTimeComparison; +class cmLocalGenerator; /** \class cmDepends * \brief Dependency scanner superclass. @@ -37,13 +38,13 @@ public: /** at what level will the compile be done from */ void SetCompileDirectory(const char *dir) {this->CompileDirectory = dir;}; - - /** Set the full path to the top of the build tree. This is - the base path from which dependencies are referenced as - relative paths. */ - void SetHomeOutputDirectory(const char *dir) { - this->HomeOutputDirectory = dir;}; - + + /** Set the local generator for the directory in which we are + scanning dependencies. This is not a full local generator; it + has been setup to do relative path conversions for the current + directory. */ + void SetLocalGenerator(cmLocalGenerator* lg) { this->LocalGenerator = lg; } + /** should this be verbose in its output */ void SetVerbose(bool verb) { this->Verbose = verb; } @@ -79,8 +80,8 @@ protected: // The directory in which the build rule for the target file is executed. std::string CompileDirectory; - // The full path to the top of the build tree. - std::string HomeOutputDirectory; + // The local generator. + cmLocalGenerator* LocalGenerator; // Flag for verbose output. bool Verbose; diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index ad1d02152..1a74f5c43 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -16,8 +16,9 @@ =========================================================================*/ #include "cmDependsC.h" -#include "cmSystemTools.h" #include "cmFileTimeComparison.h" +#include "cmLocalGenerator.h" +#include "cmSystemTools.h" #include // isspace @@ -194,13 +195,18 @@ bool cmDependsC::WriteDependencies(const char *src, const char *obj, first = false; } - // Write the dependencies to the output stream. + // Write the dependencies to the output stream. Makefile rules + // written by the original local generator for this directory + // convert the dependencies to paths relative to the home output + // directory. We must do the same here. internalDepends << obj << std::endl; for(std::set::iterator i=dependencies.begin(); i != dependencies.end(); ++i) { makeDepends << obj << ": " - << cmSystemTools::ConvertToOutputPath(i->c_str()).c_str() + << this->LocalGenerator->Convert(i->c_str(), + cmLocalGenerator::HOME_OUTPUT, + cmLocalGenerator::MAKEFILE) << std::endl; internalDepends << " " << i->c_str() << std::endl; } @@ -370,8 +376,9 @@ bool cmDependsC::FileExistsOrIsGenerated(const std::string& fname, // Note that CMAKE_GENERATED_FILES is written with a conversion // relative to the home output directory. std::string rname = - cmSystemTools::RelativePath(this->HomeOutputDirectory.c_str(), - fname.c_str()); + this->LocalGenerator->Convert(fname.c_str(), + cmLocalGenerator::HOME_OUTPUT, + cmLocalGenerator::UNCHANGED); if(this->FileIsGenerated(rname, scanned, dependencies)) { return true; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index d9d0ba482..cc02b1410 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -589,8 +589,6 @@ void cmGlobalGenerator::Configure() } this->LocalGenerators.clear(); - // Setup relative path generation. - this->ConfigureRelativePaths(); this->TotalTargets.clear(); // start with this directory @@ -1219,6 +1217,15 @@ inline std::string removeQuotes(const std::string& s) return s; } +void cmGlobalGenerator::SetCMakeInstance(cmake* cm) +{ + // Store a pointer to the cmake object instance. + this->CMakeInstance = cm; + + // Setup relative path conversion for the instance. + this->ConfigureRelativePaths(); +} + void cmGlobalGenerator::SetupTests() { std::string ctest = this->LocalGenerators[0]->GetMakefile()-> diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 1134c2a99..b8c1d33e6 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -109,7 +109,7 @@ public: ///! Set the CMake instance - void SetCMakeInstance(cmake *cm) { this->CMakeInstance = cm; }; + void SetCMakeInstance(cmake *cm); ///! Get the CMake instance cmake *GetCMakeInstance() { return this->CMakeInstance; }; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index ccc9bef44..6e4c60eab 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -160,8 +160,7 @@ public: bool /* clear */) {}; /** Called from command-line hook to scan dependencies. */ - virtual bool ScanDependencies(std::vector const& /* args */) - {return true;}; + virtual bool ScanDependencies(const char* /* tgtInfo */) { return true; } /** Compute the list of link libraries and directories for the given target and configuration. */ diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index a4b173903..e96dcdeed 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1127,30 +1127,15 @@ cmLocalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- -bool -cmLocalUnixMakefileGenerator3 -::ScanDependencies(std::vector const& args) +bool cmLocalUnixMakefileGenerator3::ScanDependencies(const char* tgtInfo) { - // Format of arguments is: $(CMAKE_COMMAND), cmake_depends, - // GeneratorName, home_output_dir, start_output_dir, info file The - // caller has ensured that all required arguments exist. - // The info file for this target - std::string const& infoFile = args[5]; + std::string const& infoFile = tgtInfo; // Read the directory information file. - cmake cm; - cmGlobalGenerator gg; - gg.SetCMakeInstance(&cm); - std::auto_ptr lg(gg.CreateLocalGenerator()); - lg->SetGlobalGenerator(&gg); - cmMakefile* mf = lg->GetMakefile(); - mf->SetHomeOutputDirectory(args[3].c_str()); - mf->SetStartOutputDirectory(args[4].c_str()); - lg->SetupPathConversions(); - + cmMakefile* mf = this->Makefile; bool haveDirectoryInfo = false; - std::string dirInfoFile = args[4]; + std::string dirInfoFile = this->Makefile->GetStartOutputDirectory(); dirInfoFile += "/CMakeFiles/CMakeDirectoryInformation.cmake"; if(mf->ReadListFile(0, dirInfoFile.c_str()) && !cmSystemTools::GetErrorOccuredFlag()) @@ -1283,7 +1268,7 @@ cmLocalUnixMakefileGenerator3 includeRegexScan.c_str(), includeRegexComplain.c_str(), generatedFiles, includeCacheFileName); - scanner->SetHomeOutputDirectory(mf->GetHomeOutputDirectory()); + scanner->SetLocalGenerator(this); } #ifdef CMAKE_BUILD_WITH_CMAKE else if(lang == "Fortran") @@ -1313,7 +1298,7 @@ cmLocalUnixMakefileGenerator3 ++si; // make sure the object file is relative to home output std::string obj = *si; - obj = lg->Convert(obj.c_str(),HOME_OUTPUT,MAKEFILE); + obj = this->Convert(obj.c_str(),HOME_OUTPUT,MAKEFILE); scanner->Write(src.c_str(),obj.c_str(), ruleFileStream, internalRuleFileStream); } diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index d9b9a8d35..30bd6c7f1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -178,7 +178,7 @@ public: /** Called from command-line hook to scan dependencies. */ - virtual bool ScanDependencies(std::vector const& args); + virtual bool ScanDependencies(const char* tgtInfo); /** Called from command-line hook to check dependencies. */ virtual void CheckDependencies(cmMakefile* mf, bool verbose, diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0c088d48a..96700b50f 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -600,20 +600,31 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() cmLocalGenerator::FULL, cmLocalGenerator::SHELL)) << " && "; #endif - depCmd << "$(CMAKE_COMMAND) -E cmake_depends " - << " \"" + // Generate a call this signature: + // + // cmake -E cmake_depends + // + // + // + // + // This gives the dependency scanner enough information to recreate + // the state of our local generator sufficiently for its needs. + depCmd << "$(CMAKE_COMMAND) -E cmake_depends \"" << this->GlobalGenerator->GetName() << "\" " - << this->LocalGenerator->Convert - (this->Makefile->GetHomeOutputDirectory(), - cmLocalGenerator::FULL,cmLocalGenerator::SHELL) + << this->Convert(this->Makefile->GetHomeDirectory(), + cmLocalGenerator::FULL, cmLocalGenerator::SHELL) << " " - << this->LocalGenerator->Convert - (this->Makefile->GetStartOutputDirectory(), - cmLocalGenerator::FULL,cmLocalGenerator::SHELL) + << this->Convert(this->Makefile->GetStartDirectory(), + cmLocalGenerator::FULL, cmLocalGenerator::SHELL) + << " " + << this->Convert(this->Makefile->GetHomeOutputDirectory(), + cmLocalGenerator::FULL, cmLocalGenerator::SHELL) + << " " + << this->Convert(this->Makefile->GetStartOutputDirectory(), + cmLocalGenerator::FULL, cmLocalGenerator::SHELL) << " " << this->Convert(this->InfoFileNameFull.c_str(), - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); + cmLocalGenerator::FULL, cmLocalGenerator::SHELL); commands.push_back(depCmd.str()); // Write the rule. diff --git a/Source/cmake.cxx b/Source/cmake.cxx index ca9f1c335..08677017f 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1102,14 +1102,71 @@ int cmake::ExecuteCMakeCommand(std::vector& args) // Internal CMake dependency scanning support. else if (args[1] == "cmake_depends" && args.size() >= 6) { + // Create a cmake object instance to process dependencies. cmake cm; - cmGlobalGenerator *ggd = cm.CreateGlobalGenerator(args[2].c_str()); - if (ggd) + std::string gen; + std::string homeDir; + std::string startDir; + std::string homeOutDir; + std::string startOutDir; + std::string depInfo; + if(args.size() >= 8) { - ggd->SetCMakeInstance(&cm); + // Full signature: + // + // -E cmake_depends + // + // + // + // + // All paths are provided. + gen = args[2]; + homeDir = args[3]; + startDir = args[4]; + homeOutDir = args[5]; + startOutDir = args[6]; + depInfo = args[7]; + } + else + { + // Support older signature for existing makefiles: + // + // -E cmake_depends + // + // + // + // Just pretend the source directories are the same as the + // binary directories so at least scanning will work. + gen = args[2]; + homeDir = args[3]; + startDir = args[4]; + homeOutDir = args[3]; + startOutDir = args[3]; + depInfo = args[5]; + } + + // Create a local generator configured for the directory in + // which dependencies will be scanned. + homeDir = cmSystemTools::CollapseFullPath(homeDir.c_str()); + startDir = cmSystemTools::CollapseFullPath(startDir.c_str()); + homeOutDir = cmSystemTools::CollapseFullPath(homeOutDir.c_str()); + startOutDir = cmSystemTools::CollapseFullPath(startOutDir.c_str()); + cm.SetHomeDirectory(homeDir.c_str()); + cm.SetStartDirectory(startDir.c_str()); + cm.SetHomeOutputDirectory(homeOutDir.c_str()); + cm.SetStartOutputDirectory(startOutDir.c_str()); + if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen.c_str())) + { + cm.SetGlobalGenerator(ggd); std::auto_ptr lgd(ggd->CreateLocalGenerator()); lgd->SetGlobalGenerator(ggd); - return lgd->ScanDependencies(args)? 0 : 2; + lgd->GetMakefile()->SetStartDirectory(startDir.c_str()); + lgd->GetMakefile()->SetStartOutputDirectory(startOutDir.c_str()); + lgd->GetMakefile()->MakeStartDirectoriesCurrent(); + lgd->SetupPathConversions(); + + // Actually scan dependencies. + return lgd->ScanDependencies(depInfo.c_str())? 0 : 2; } return 1; }