From c44e6d30e5127457060f8e027fbff17ac89e98a5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 7 Feb 2005 15:10:20 -0500 Subject: ENH: Added generation of CMakeDirectoryInformation.cmake file in each directory next to the Makefile. The include file search path is now stored in this file instead of duplicating it for every object file. This will also allow more information to be passed in the future. --- Source/cmLocalUnixMakefileGenerator2.cxx | 132 ++++++++++++++++++++++++++----- Source/cmLocalUnixMakefileGenerator2.h | 2 + 2 files changed, 115 insertions(+), 19 deletions(-) diff --git a/Source/cmLocalUnixMakefileGenerator2.cxx b/Source/cmLocalUnixMakefileGenerator2.cxx index db52f50..cd229e9 100644 --- a/Source/cmLocalUnixMakefileGenerator2.cxx +++ b/Source/cmLocalUnixMakefileGenerator2.cxx @@ -21,6 +21,7 @@ #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmake.h" // Include dependency scanners for supported languages. Only the // C/C++ scanner is needed for bootstrapping CMake. @@ -44,7 +45,6 @@ // TODO: Add "help" target. // TODO: Identify remaining relative path violations. -// TODO: Add test to drive installation through native build system. // TODO: Need test for separate executable/library output path. //---------------------------------------------------------------------------- @@ -121,6 +121,9 @@ void cmLocalUnixMakefileGenerator2::Generate(bool fromTheTop) // Generate the cmake file that keeps the makefile up to date. this->GenerateCMakefile(); + + // Generate the cmake file with information for this directory. + this->GenerateDirectoryInformationFile(); } //---------------------------------------------------------------------------- @@ -182,8 +185,6 @@ void cmLocalUnixMakefileGenerator2::GenerateCMakefile() std::string cmakefileName = makefileName; cmakefileName += ".cmake"; - // TODO: Use relative paths in this generated file. - // Open the output file. cmGeneratedFileStream cmakefileStream(cmakefileName.c_str()); if(!cmakefileStream) @@ -267,6 +268,62 @@ void cmLocalUnixMakefileGenerator2::GenerateCMakefile() } //---------------------------------------------------------------------------- +void cmLocalUnixMakefileGenerator2::GenerateDirectoryInformationFile() +{ + std::string infoFileName = m_Makefile->GetStartOutputDirectory(); + infoFileName += "/CMakeDirectoryInformation.cmake"; + + // Open the output file. + cmGeneratedFileStream infoFileStream(infoFileName.c_str()); + if(!infoFileStream) + { + return; + } + + // Write the do not edit header. + this->WriteDisclaimer(infoFileStream); + + // Store the include search path for this directory. + infoFileStream + << "# The C and CXX include file search paths:\n"; + infoFileStream + << "SET(CMAKE_C_INCLUDE_PATH\n"; + std::vector includeDirs; + this->GetIncludeDirectories(includeDirs); + for(std::vector::iterator i = includeDirs.begin(); + i != includeDirs.end(); ++i) + { + infoFileStream + << " \"" << this->ConvertToRelativePath(i->c_str()).c_str() << "\"\n"; + } + infoFileStream + << " )\n"; + infoFileStream + << "SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH})\n"; + + // Store the include regular expressions for this directory. + infoFileStream + << "\n" + << "# The C and CXX include file regular expressions for this directory.\n"; + infoFileStream + << "SET(CMAKE_C_INCLUDE_REGEX_SCAN "; + this->WriteCMakeArgument(infoFileStream, + m_Makefile->GetIncludeRegularExpression()); + infoFileStream + << ")\n"; + infoFileStream + << "SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "; + this->WriteCMakeArgument(infoFileStream, + m_Makefile->GetComplainRegularExpression()); + infoFileStream + << ")\n"; + infoFileStream + << "SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})\n"; + infoFileStream + << "SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN})\n"; +} + +//---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator2 ::GenerateTargetRuleFile(const cmTarget& target) @@ -468,17 +525,11 @@ cmLocalUnixMakefileGenerator2 // touch the corresponding depends file after scanning dependencies. cmOStringStream depCmd; // TODO: Account for source file properties and directory-level - // definitions when scanning for dependencies. + // definitions when scanning for dependencies. Also account for + // include/ignore regular expressions. depCmd << "$(CMAKE_COMMAND) -E cmake_depends " << lang << " " << this->ConvertToRelativeOutputPath(obj.c_str()) << " " << this->ConvertToRelativeOutputPath(source.GetFullPath().c_str()); - std::vector includeDirs; - this->GetIncludeDirectories(includeDirs); - for(std::vector::iterator i = includeDirs.begin(); - i != includeDirs.end(); ++i) - { - depCmd << " -I" << this->ConvertToRelativeOutputPath(i->c_str()); - } std::vector commands; commands.push_back(depCmd.str()); @@ -2020,6 +2071,32 @@ cmLocalUnixMakefileGenerator2 } //---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator2 +::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 cmLocalUnixMakefileGenerator2 ::GetTargetDirectory(const cmTarget& target) @@ -2738,29 +2815,46 @@ cmLocalUnixMakefileGenerator2 ::ScanDependencies(std::vector const& args) { // Format of arguments is: - // $(CMAKE_COMMAND), cmake_depends, , , , [include-flags] + // $(CMAKE_COMMAND), cmake_depends, , , // The caller has ensured that all required arguments exist. + // The language for which we are scanning dependencies. + std::string const& lang = args[2]; + // The file to which to write dependencies. const char* objFile = args[3].c_str(); // The source file at which to start the scan. const char* srcFile = args[4].c_str(); - // Convert the include flags to full paths. + // 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(); + bool haveDirectoryInfo = false; + if(mf->ReadListFile(0, "CMakeDirectoryInformation.cmake") && + !cmSystemTools::GetErrorOccuredFlag()) + { + haveDirectoryInfo = true; + } + + // Get the set of include directories. std::vector includes; - for(unsigned int i=5; i < args.size(); ++i) + if(haveDirectoryInfo) { - if(args[i].substr(0, 2) == "-I") + std::string includePathVar = "CMAKE_"; + includePathVar += lang; + includePathVar += "_INCLUDE_PATH"; + if(const char* includePath = mf->GetDefinition(includePathVar.c_str())) { - // Get the include path without the -I flag. - std::string inc = args[i].substr(2); - includes.push_back(cmSystemTools::CollapseFullPath(inc.c_str())); + cmSystemTools::ExpandListArgument(includePath, includes); } } // Dispatch the scan for each language. - std::string const& lang = args[2]; if(lang == "C" || lang == "CXX" || lang == "RC") { // TODO: Handle RC (resource files) dependencies correctly. diff --git a/Source/cmLocalUnixMakefileGenerator2.h b/Source/cmLocalUnixMakefileGenerator2.h index d861499..2fb3a12 100644 --- a/Source/cmLocalUnixMakefileGenerator2.h +++ b/Source/cmLocalUnixMakefileGenerator2.h @@ -64,6 +64,7 @@ protected: void GenerateMakefile(); void GenerateCMakefile(); + void GenerateDirectoryInformationFile(); void GenerateTargetRuleFile(const cmTarget& target); void GenerateObjectRuleFile(const cmTarget& target, const cmSourceFile& source, @@ -153,6 +154,7 @@ protected: void WriteTargetRequiresRule(std::ostream& ruleFileStream, const cmTarget& target, const std::vector& provides_requires); + void WriteCMakeArgument(std::ostream& os, const char* s); std::string GetTargetDirectory(const cmTarget& target); std::string GetSubdirTargetName(const char* pass, const char* subdir); std::string GetObjectFileName(const cmTarget& target, -- cgit v0.12