From ec2104cd31af3c533838fce05534d37d762028d6 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 25 May 2006 09:47:30 -0400 Subject: BUG: Updated Makefile dependency scanning to provide a full local generator to the dependency scanner to do proper path conversions. This allows the rules written into the depend.make files to use the same relative path conversion as those written into the build.make files. Several previous changes added more and more information for use by the dependency scanner and it was converging to having the full local generator anyway. --- Source/cmDepends.cxx | 6 ++- Source/cmDepends.h | 19 +++++----- Source/cmDependsC.cxx | 17 ++++++--- Source/cmGlobalGenerator.cxx | 11 +++++- Source/cmGlobalGenerator.h | 2 +- Source/cmLocalGenerator.h | 3 +- Source/cmLocalUnixMakefileGenerator3.cxx | 27 +++---------- Source/cmLocalUnixMakefileGenerator3.h | 2 +- Source/cmMakefileTargetGenerator.cxx | 31 ++++++++++----- Source/cmake.cxx | 65 ++++++++++++++++++++++++++++++-- 10 files changed, 127 insertions(+), 56 deletions(-) diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index f6d577c..37c177b 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 ceb78be..b6eda70 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 ad1d021..1a74f5c 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 d9d0ba4..cc02b14 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 1134c2a..b8c1d33 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 ccc9bef..6e4c60e 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 a4b1739..e96dcde 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 d9b9a8d..30bd6c7 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 0c088d4..96700b5 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 ca9f1c3..0867701 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; } -- cgit v0.12