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.

This commit is contained in:
Brad King 2005-02-07 15:10:20 -05:00
parent 1d1bd31933
commit c44e6d30e5
2 changed files with 116 additions and 20 deletions

View File

@ -21,6 +21,7 @@
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmake.h"
// Include dependency scanners for supported languages. Only the // Include dependency scanners for supported languages. Only the
// C/C++ scanner is needed for bootstrapping CMake. // C/C++ scanner is needed for bootstrapping CMake.
@ -44,7 +45,6 @@
// TODO: Add "help" target. // TODO: Add "help" target.
// TODO: Identify remaining relative path violations. // 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. // 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. // Generate the cmake file that keeps the makefile up to date.
this->GenerateCMakefile(); this->GenerateCMakefile();
// Generate the cmake file with information for this directory.
this->GenerateDirectoryInformationFile();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -182,8 +185,6 @@ void cmLocalUnixMakefileGenerator2::GenerateCMakefile()
std::string cmakefileName = makefileName; std::string cmakefileName = makefileName;
cmakefileName += ".cmake"; cmakefileName += ".cmake";
// TODO: Use relative paths in this generated file.
// Open the output file. // Open the output file.
cmGeneratedFileStream cmakefileStream(cmakefileName.c_str()); cmGeneratedFileStream cmakefileStream(cmakefileName.c_str());
if(!cmakefileStream) if(!cmakefileStream)
@ -266,6 +267,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<std::string> includeDirs;
this->GetIncludeDirectories(includeDirs);
for(std::vector<std::string>::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 void
cmLocalUnixMakefileGenerator2 cmLocalUnixMakefileGenerator2
@ -468,17 +525,11 @@ cmLocalUnixMakefileGenerator2
// touch the corresponding depends file after scanning dependencies. // touch the corresponding depends file after scanning dependencies.
cmOStringStream depCmd; cmOStringStream depCmd;
// TODO: Account for source file properties and directory-level // 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 << " " depCmd << "$(CMAKE_COMMAND) -E cmake_depends " << lang << " "
<< this->ConvertToRelativeOutputPath(obj.c_str()) << " " << this->ConvertToRelativeOutputPath(obj.c_str()) << " "
<< this->ConvertToRelativeOutputPath(source.GetFullPath().c_str()); << this->ConvertToRelativeOutputPath(source.GetFullPath().c_str());
std::vector<std::string> includeDirs;
this->GetIncludeDirectories(includeDirs);
for(std::vector<std::string>::iterator i = includeDirs.begin();
i != includeDirs.end(); ++i)
{
depCmd << " -I" << this->ConvertToRelativeOutputPath(i->c_str());
}
std::vector<std::string> commands; std::vector<std::string> commands;
commands.push_back(depCmd.str()); commands.push_back(depCmd.str());
@ -2019,6 +2070,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 std::string
cmLocalUnixMakefileGenerator2 cmLocalUnixMakefileGenerator2
@ -2738,29 +2815,46 @@ cmLocalUnixMakefileGenerator2
::ScanDependencies(std::vector<std::string> const& args) ::ScanDependencies(std::vector<std::string> const& args)
{ {
// Format of arguments is: // Format of arguments is:
// $(CMAKE_COMMAND), cmake_depends, <lang>, <obj>, <src>, [include-flags] // $(CMAKE_COMMAND), cmake_depends, <lang>, <obj>, <src>
// The caller has ensured that all required arguments exist. // 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. // The file to which to write dependencies.
const char* objFile = args[3].c_str(); const char* objFile = args[3].c_str();
// The source file at which to start the scan. // The source file at which to start the scan.
const char* srcFile = args[4].c_str(); const char* srcFile = args[4].c_str();
// Convert the include flags to full paths. // Read the directory information file.
std::vector<std::string> includes; cmake cm;
for(unsigned int i=5; i < args.size(); ++i) cmGlobalGenerator gg;
gg.SetCMakeInstance(&cm);
std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
lg->SetGlobalGenerator(&gg);
cmMakefile* mf = lg->GetMakefile();
bool haveDirectoryInfo = false;
if(mf->ReadListFile(0, "CMakeDirectoryInformation.cmake") &&
!cmSystemTools::GetErrorOccuredFlag())
{ {
if(args[i].substr(0, 2) == "-I") haveDirectoryInfo = true;
}
// Get the set of include directories.
std::vector<std::string> includes;
if(haveDirectoryInfo)
{
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. cmSystemTools::ExpandListArgument(includePath, includes);
std::string inc = args[i].substr(2);
includes.push_back(cmSystemTools::CollapseFullPath(inc.c_str()));
} }
} }
// Dispatch the scan for each language. // Dispatch the scan for each language.
std::string const& lang = args[2];
if(lang == "C" || lang == "CXX" || lang == "RC") if(lang == "C" || lang == "CXX" || lang == "RC")
{ {
// TODO: Handle RC (resource files) dependencies correctly. // TODO: Handle RC (resource files) dependencies correctly.

View File

@ -64,6 +64,7 @@ protected:
void GenerateMakefile(); void GenerateMakefile();
void GenerateCMakefile(); void GenerateCMakefile();
void GenerateDirectoryInformationFile();
void GenerateTargetRuleFile(const cmTarget& target); void GenerateTargetRuleFile(const cmTarget& target);
void GenerateObjectRuleFile(const cmTarget& target, void GenerateObjectRuleFile(const cmTarget& target,
const cmSourceFile& source, const cmSourceFile& source,
@ -153,6 +154,7 @@ protected:
void WriteTargetRequiresRule(std::ostream& ruleFileStream, void WriteTargetRequiresRule(std::ostream& ruleFileStream,
const cmTarget& target, const cmTarget& target,
const std::vector<std::string>& provides_requires); const std::vector<std::string>& provides_requires);
void WriteCMakeArgument(std::ostream& os, const char* s);
std::string GetTargetDirectory(const cmTarget& target); std::string GetTargetDirectory(const cmTarget& target);
std::string GetSubdirTargetName(const char* pass, const char* subdir); std::string GetSubdirTargetName(const char* pass, const char* subdir);
std::string GetObjectFileName(const cmTarget& target, std::string GetObjectFileName(const cmTarget& target,