ENH: add CMakeCache.txt support

This commit is contained in:
Bill Hoffman 2001-02-22 19:24:43 -05:00
parent 5d903c6b0f
commit 0b0d1b1d43
18 changed files with 498 additions and 337 deletions

View File

@ -23,6 +23,13 @@ clean: ${SUBDIR_CLEAN}
CMakeTargets.make: ${CMAKE} ${srcdir}/CMakeLists.txt
${CMAKE} ${currentdir}/CMakeLists.txt -S${currentdir} -O${currentbindir} -H${topdir} -B${CMAKE_CONFIG_DIR}
rebuild_cache: ${CMAKE_CONFIG_DIR}/CMakeCache.txt
rm -f ${CMAKE_CONFIG_DIR}/CMakeCache.txt
${CMAKE} ${topdir}/CMakeLists.txt -MakeCache -S${topdir} -O${CMAKE_CONFIG_DIR} -H${topdir} -B${CMAKE_CONFIG_DIR}
${CMAKE_CONFIG_DIR}/CMakeCache.txt:
${CMAKE} ${topdir}/CMakeLists.txt -MakeCache -S${topdir} -O${CMAKE_CONFIG_DIR} -H${topdir} -B${CMAKE_CONFIG_DIR}
#------------------------------------------------------------------------------
# rules for the normal library
#

View File

@ -0,0 +1,8 @@
srcdir = @srcdir@
VPATH = @srcdir@
topall:
cd . ; ${MAKE} -${MAKEFLAGS} CMakeTargets.make
cd . ; ${MAKE} -${MAKEFLAGS} all
@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_CONFIG_DIR@/CMake/CMakeMaster.make@MAKEQUOTE@

View File

@ -43,6 +43,7 @@ int main(int ac, char** av)
// Create a makefile
cmMakefile mf;
mf.AddDefinition("UNIX", "1");
bool makeCache = false;
// Parse the command line
if(ac > 2)
{
@ -50,6 +51,11 @@ int main(int ac, char** av)
{
std::string arg = av[i];
// Set the start source directory with a -S dir options
if(arg.find("-MakeCache",0) == 0)
{
makeCache = true;
}
// Set the start source directory with a -S dir options
if(arg.find("-S",0) == 0)
{
std::string path = arg.substr(2);
@ -75,7 +81,12 @@ int main(int ac, char** av)
}
}
}
// Only generate makefiles if not trying to make the cache
if(!makeCache)
{
mf.SetMakefileGenerator(new cmUnixMakefileGenerator);
}
// Read and parse the input makefile
mf.MakeStartDirectoriesCurrent();
@ -85,6 +96,24 @@ int main(int ac, char** av)
Usage(av[0]);
return -1;
}
mf.GenerateMakefile();
cmCacheManager::GetInstance()->SaveCache(&mf);
if(makeCache)
{
mf.GenerateCacheOnly();
}
else
{
mf.GenerateMakefile();
}
cmCacheManager::GetInstance()->SaveCache(&mf);
if(makeCache)
{
cmCacheManager::GetInstance()->PrintCache(cout);
}
if(cmSystemTools::GetErrorOccuredFlag())
{
return -1;
}
return 0;
}

View File

@ -272,9 +272,26 @@ void CMakeSetupDialog::OnOK()
mf.ReadListFile(makefileIn);
// Move this to the cache editor
mf.GenerateMakefile();
CDialog::OnOK();
cmCacheManager::GetInstance()->SaveCache(&mf);
std::string command;
command = "notepad ";
std::string cachefile = m_WhereBuild;
cachefile += "/CMakeCache.txt";
command += cachefile.c_str();
long int originalMT = cmSystemTools::ModifiedTime(cachefile.c_str());
system(command.c_str());
long int afterEditMT = cmSystemTools::ModifiedTime(cachefile.c_str());
// if the cache was changed, re-generate the project
if(originalMT != afterEditMT)
{
cmCacheManager::GetInstance()->LoadCache(&mf);
mf.GenerateMakefile();
cmCacheManager::GetInstance()->SaveCache(&mf);
}
// parent class
this->SaveToRegistry();
CDialog::OnOK();
}
void CMakeSetupDialog::OnButton3()

View File

@ -7,7 +7,7 @@ VPATH = @srcdir@
# command for changing into this directory
# let cmake know that this was done with autoconf
KIT_FLAGS = -DCMAKE_HAS_AUTOCONF
KIT_FLAGS = -DCMAKE_HAS_AUTOCONF -I${CMAKE_CONFIG_DIR}/CMake/Source
@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_CONFIG_DIR@/CMake/CMakeVariables.make@MAKEQUOTE@
@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_CONFIG_DIR@/CMake/CMakeSimpleRules.make@MAKEQUOTE@
@ -24,19 +24,20 @@ cmUnixMakefileGenerator.o \
cmCommands.o \
cmCacheManager.o
DEPENDS = $(srcdir)/*.h ${CMAKE_CONFIG_DIR}/CMake/Source/cmConfigure.h
cmCollectFlags.o : $(srcdir)/*.h
CMakeBuildTargets.o : $(srcdir)/*.h
cmMakeDepend.o : $(srcdir)/*.h
cmMakefile.o : $(srcdir)/*.h
cmMakefileGenerator.o : $(srcdir)/*.h
cmAuxSourceDirectoryCommand.o : $(srcdir)/*.h
cmRegularExpression.o : $(srcdir)/*.h
cmClassFile.o : $(srcdir)/*.h
cmDirectory.o : $(srcdir)/*.h
cmUnixMakefileGenerator.o : $(srcdir)/*.h
cmCommands.o : $(srcdir)/*.h
cmCacheManager.o : $(srcdir)/*.h
cmCollectFlags.o : $(DEPENDS)
CMakeBuildTargets.o : $(DEPENDS)
cmMakeDepend.o : $(DEPENDS)
cmMakefile.o : $(DEPENDS)
cmMakefileGenerator.o : $(DEPENDS)
cmAuxSourceDirectoryCommand.o : $(DEPENDS)
cmRegularExpression.o : $(DEPENDS)
cmClassFile.o : $(DEPENDS)
cmDirectory.o : $(DEPENDS)
cmUnixMakefileGenerator.o : $(DEPENDS)
cmCommands.o : $(DEPENDS)
cmCacheManager.o : $(DEPENDS)

View File

@ -18,6 +18,7 @@
#include "cmSystemTools.h"
#include "cmCacheManager.h"
#include "cmMakefile.h"
#include "cmRegularExpression.h"
const char* cmCacheManagerTypes[] =
{ "BOOL",
@ -68,21 +69,27 @@ bool cmCacheManager::LoadCache(cmMakefile* mf)
}
const int bsize = 4096;
char buffer[bsize];
std::string inputLine;
// input line is: key:type=value
cmRegularExpression reg("(.*):(.*)=(.*)");
while(fin)
{
// Format is key:type=value
CacheEntry e;
std::string key;
fin.getline(buffer, bsize, ':');
key = buffer;
fin.getline(buffer, bsize, '=');
e.m_Type = cmCacheManager::StringToType(buffer);
fin.getline(buffer, bsize); // last token is separated by a newline
e.m_Value = buffer;
if(fin)
fin.getline(buffer, bsize);
// skip blank lines and comment lines
if(buffer[0] == '#' || buffer[0] == 0)
{
m_Cache[key] = e;
continue;
}
if(reg.find(buffer))
{
e.m_Type = cmCacheManager::StringToType(reg.match(2).c_str());
e.m_Value = reg.match(3);
m_Cache[reg.match(1)] = e;
}
else
{
cmSystemTools::Error("Parse error in cache file ", cacheFile.c_str());
}
}
return true;
@ -92,13 +99,25 @@ bool cmCacheManager::SaveCache(cmMakefile* mf)
{
std::string cacheFile = mf->GetHomeOutputDirectory();
cacheFile += "/CMakeCache.txt";
std::ofstream fout(cacheFile.c_str());
std::string tempFile = cacheFile;
tempFile += ".tmp";
std::ofstream fout(tempFile.c_str());
if(!fout)
{
cmSystemTools::Error("Unable to open cache file for save. ",
cacheFile.c_str());
return false;
}
fout << "# This is the CMakeCache file.\n"
<< "# You can edit this file to change values found and used by cmake.\n"
<< "# If you do not want to change any of the values, simply exit the editor.\n"
<< "# If you do want to change a value, simply edit, save, and exit the editor.\n"
<< "# The syntax for the file is as follows:\n"
<< "# KEY:TYPE=VALUE\n"
<< "# KEY is the name of a varible in the cache.\n"
<< "# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!.\n"
<< "# VALUE is the current value for the KEY.\n\n";
for( std::map<std::string, CacheEntry>::iterator i = m_Cache.begin();
i != m_Cache.end(); ++i)
{
@ -109,6 +128,10 @@ bool cmCacheManager::SaveCache(cmMakefile* mf)
<< (*i).second.m_Value << "\n";
}
fout << "\n";
fout.close();
cmSystemTools::CopyFileIfDifferent(tempFile.c_str(),
cacheFile.c_str());
cmSystemTools::RemoveFile(tempFile.c_str());
return true;
}
@ -130,3 +153,20 @@ const char* cmCacheManager::GetCacheValue(const char* key)
}
return 0;
}
void cmCacheManager::PrintCache(std::ostream& out)
{
out << "=================================================" << std::endl;
out << "CMakeCache Contents:" << std::endl;
for(std::map<std::string, CacheEntry>::iterator i = m_Cache.begin();
i != m_Cache.end(); ++i)
{
out << (*i).first.c_str() << " = " << (*i).second.m_Value.c_str() << std::endl;
}
out << "\n\n";
out << "To change values in the CMakeCache, \nedit CMakeCache.txt in your output directory.\n";
out << "=================================================" << std::endl;
}

View File

@ -52,6 +52,8 @@ public:
//! Get a value from the cache given a key
const char* GetCacheValue(const char* key);
//! Print the cache to a stream
void PrintCache(std::ostream&);
private:
static cmCacheManager* s_Instance;
class CacheEntry

2
Source/cmConfigure.h.in Normal file
View File

@ -0,0 +1,2 @@
#undef CMAKE_NO_STD_NAMESPACE
#undef CMAKE_NO_ANSI_STREAM_HEADERS

View File

@ -49,11 +49,13 @@ void cmConfigureFileNoAutoconf::FinalPass()
std::string path = m_OuputFile.substr(0, pos);
cmSystemTools::MakeDirectory(path.c_str());
}
std::ofstream fout(m_OuputFile.c_str());
std::string tempOutputFile = m_OuputFile;
tempOutputFile += ".tmp";
std::ofstream fout(tempOutputFile.c_str());
if(!fout)
{
cmSystemTools::Error("Could not open file for write in copy operatation",
m_OuputFile.c_str());
tempOutputFile.c_str());
return;
}
// now copy input to output and expand varibles in the
@ -64,10 +66,19 @@ void cmConfigureFileNoAutoconf::FinalPass()
while(fin)
{
fin.getline(buffer, bufSize);
if(fin)
{
inLine = buffer;
m_Makefile->ExpandVariablesInString(inLine);
fout << inLine << "\n";
}
}
// close the files before attempting to copy
fin.close();
fout.close();
cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
m_OuputFile.c_str());
cmSystemTools::RemoveFile(tempOutputFile.c_str());
#endif
}

View File

@ -16,15 +16,8 @@
#include "cmDSPMakefile.h"
#include "cmStandardIncludes.h"
#include "cmSystemTools.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef GetCurrentDirectory
static void Die(const char* message)
{
MessageBox(0, message, 0, MB_OK);
exit(-1);
}
cmDSPMakefile::~cmDSPMakefile()
{
}
@ -37,7 +30,18 @@ cmDSPMakefile::cmDSPMakefile(cmMakefile*mf)
void cmDSPMakefile::OutputDSPFile()
{
// Setup /I and /LIBPATH options
// If not an in source build, then create the output directory
if(strcmp(m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeDirectory()) != 0)
{
if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
{
cmSystemTools::Error("Error creating directory ",
m_Makefile->GetStartOutputDirectory());
}
}
// Setup /I and /LIBPATH options for the resulting DSP file
std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
std::vector<std::string>::iterator i;
for(i = includes.begin(); i != includes.end(); ++i)
@ -77,20 +81,10 @@ void cmDSPMakefile::OutputDSPFile()
// add any extra define flags
m_ReleaseLibraryOptions = m_DebugLibraryOptions;
cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release");
// If the output directory is not the m_cmHomeDirectory
// then create it.
if(strcmp(m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeDirectory()) != 0)
{
if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
{
std::string message = "Error creating directory ";
message += m_Makefile->GetStartOutputDirectory();
Die(message.c_str());
}
}
// if there is a library, build it
// Create the DSP or set of DSP's for libraries and executables
if(strlen(m_Makefile->GetLibraryName()) != 0)
{
this->SetBuildType(STATIC_LIBRARY);
@ -117,9 +111,8 @@ void cmDSPMakefile::CreateExecutableDSPFiles()
std::ofstream fout(fname.c_str());
if(!fout)
{
std::string message = "Error Writing ";
message += fname;
Die(message.c_str());
cmSystemTools::Error("Error Writing ",
fname.c_str());
}
else
{
@ -153,9 +146,8 @@ void cmDSPMakefile::CreateSingleDSP()
std::ofstream fout(fname.c_str());
if(!fout)
{
std::string message = "Error Writing ";
message += fname;
Die(message.c_str());
cmSystemTools::Error("Error Writing ",
fname.c_str());
}
this->WriteDSPFile(fout);
}
@ -257,9 +249,7 @@ void cmDSPMakefile::WriteDSPHeader(std::ostream& fout)
std::ifstream fin(m_DSPHeaderTemplate.c_str());
if(!fin)
{
std::string message = "Error Reading ";
message += m_DSPHeaderTemplate;
Die(message.c_str());
cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
}
char buffer[2048];
@ -288,9 +278,8 @@ void cmDSPMakefile::WriteDSPFooter(std::ostream& fout)
std::ifstream fin(m_DSPFooterTemplate.c_str());
if(!fin)
{
std::string message = "Error Reading ";
message += m_DSPFooterTemplate;
Die(message.c_str());
cmSystemTools::Error("Error Reading ",
m_DSPFooterTemplate.c_str());
}
char buffer[2048];
while(fin)

View File

@ -16,15 +16,8 @@
#include "cmDSPMakefile.h"
#include "cmStandardIncludes.h"
#include "cmSystemTools.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef GetCurrentDirectory
static void Die(const char* message)
{
MessageBox(0, message, 0, MB_OK);
exit(-1);
}
cmDSPMakefile::~cmDSPMakefile()
{
}
@ -37,7 +30,18 @@ cmDSPMakefile::cmDSPMakefile(cmMakefile*mf)
void cmDSPMakefile::OutputDSPFile()
{
// Setup /I and /LIBPATH options
// If not an in source build, then create the output directory
if(strcmp(m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeDirectory()) != 0)
{
if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
{
cmSystemTools::Error("Error creating directory ",
m_Makefile->GetStartOutputDirectory());
}
}
// Setup /I and /LIBPATH options for the resulting DSP file
std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
std::vector<std::string>::iterator i;
for(i = includes.begin(); i != includes.end(); ++i)
@ -77,20 +81,10 @@ void cmDSPMakefile::OutputDSPFile()
// add any extra define flags
m_ReleaseLibraryOptions = m_DebugLibraryOptions;
cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release");
// If the output directory is not the m_cmHomeDirectory
// then create it.
if(strcmp(m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeDirectory()) != 0)
{
if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
{
std::string message = "Error creating directory ";
message += m_Makefile->GetStartOutputDirectory();
Die(message.c_str());
}
}
// if there is a library, build it
// Create the DSP or set of DSP's for libraries and executables
if(strlen(m_Makefile->GetLibraryName()) != 0)
{
this->SetBuildType(STATIC_LIBRARY);
@ -117,9 +111,8 @@ void cmDSPMakefile::CreateExecutableDSPFiles()
std::ofstream fout(fname.c_str());
if(!fout)
{
std::string message = "Error Writing ";
message += fname;
Die(message.c_str());
cmSystemTools::Error("Error Writing ",
fname.c_str());
}
else
{
@ -153,9 +146,8 @@ void cmDSPMakefile::CreateSingleDSP()
std::ofstream fout(fname.c_str());
if(!fout)
{
std::string message = "Error Writing ";
message += fname;
Die(message.c_str());
cmSystemTools::Error("Error Writing ",
fname.c_str());
}
this->WriteDSPFile(fout);
}
@ -257,9 +249,7 @@ void cmDSPMakefile::WriteDSPHeader(std::ostream& fout)
std::ifstream fin(m_DSPHeaderTemplate.c_str());
if(!fin)
{
std::string message = "Error Reading ";
message += m_DSPHeaderTemplate;
Die(message.c_str());
cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
}
char buffer[2048];
@ -288,9 +278,8 @@ void cmDSPMakefile::WriteDSPFooter(std::ostream& fout)
std::ifstream fin(m_DSPFooterTemplate.c_str());
if(!fin)
{
std::string message = "Error Reading ";
message += m_DSPFooterTemplate;
Die(message.c_str());
cmSystemTools::Error("Error Reading ",
m_DSPFooterTemplate.c_str());
}
char buffer[2048];
while(fin)

View File

@ -20,9 +20,6 @@
#include "cmMSProjectGenerator.h"
#include <windows.h>
// microsoft nonsense
#undef GetCurrentDirectory
#undef SetCurrentDirectory
cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
{
@ -32,22 +29,17 @@ cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
// output the DSW file
void cmDSWMakefile::OutputDSWFile()
{
if(m_Makefile->GetStartOutputDirectory() == "")
{
// default to build in place
m_Makefile->SetStartOutputDirectory(m_Makefile->GetHomeDirectory());
}
// If the output directory is not the m_cmHomeDirectory
// then create it.
// if this is an out of source build, create the output directory
if(strcmp(m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeDirectory()) != 0)
{
if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
{
MessageBox(0, "Error creating directory ", 0, MB_OK);
MessageBox(0, m_Makefile->GetStartOutputDirectory(), 0, MB_OK);
cmSystemTools::Error("Error creating output directory for DSW file",
m_Makefile->GetStartOutputDirectory());
}
}
// create the dsw file name
std::string fname;
fname = m_Makefile->GetStartOutputDirectory();
fname += "/";
@ -56,139 +48,72 @@ void cmDSWMakefile::OutputDSWFile()
std::ofstream fout(fname.c_str());
if(!fout)
{
cmSystemTools::Error("Error can not open for write: " , fname.c_str());
cmSystemTools::Error("Error can not open DSW file for write: "
,fname.c_str());
return;
}
this->WriteDSWFile(fout);
}
// ------------------------------------------------
// Recursive function to find all the CMakeLists.txt files
// in a project. As each file is read in, any directories in
// the SUBDIR variable are also passed back to this function.
// The result is a vector of cmDSPMakefile objects, one for
// each directory with a CMakeLists.txt file
//
void
cmDSWMakefile
::FindAllCMakeListsFiles(const char* subdir,
std::vector<cmMSProjectGenerator*>& makefiles)
{
std::string currentDir = m_Makefile->GetCurrentDirectory();
currentDir += "/";
currentDir += subdir;
currentDir += "/";
currentDir += "CMakeLists.txt";
// CMakeLists.txt exits in the subdirectory
// then create a cmDSPMakefile for it
if(cmSystemTools::FileExists(currentDir.c_str()))
{
// Create a new cmDSPMakefile to read the currentDir CMakeLists.txt file
cmMSProjectGenerator* pg = new cmMSProjectGenerator;
pg->BuildDSWOff();
cmMakefile* mf = new cmMakefile;
mf->SetMakefileGenerator(pg);
// add it to the vector
makefiles.push_back(pg);
// Set up the file with the current context
mf->SetHomeOutputDirectory(m_Makefile->GetStartOutputDirectory());
mf->SetHomeDirectory(m_Makefile->GetHomeDirectory());
// Set the output directory which may be different than the source
std::string outdir = m_Makefile->GetStartOutputDirectory();
outdir += "/";
outdir += subdir;
mf->SetStartOutputDirectory(outdir.c_str());
// set the current directory in the Source as a full
// path
std::string currentDir = m_Makefile->GetStartDirectory();
currentDir += "/";
currentDir += subdir;
mf->SetStartDirectory(currentDir.c_str());
// Parse the CMakeLists.txt file
currentDir += "/CMakeLists.txt";
mf->MakeStartDirectoriesCurrent();
mf->ReadListFile(currentDir.c_str());
// Create the DSP file
mf->GenerateMakefile();
// Look at any sub directories parsed (SUBDIRS) and
// recurse into them
const std::vector<std::string>& subdirs = mf->GetSubDirectories();
for(std::vector<std::string>::const_iterator i = subdirs.begin();
i != subdirs.end(); ++i)
{
// append the subdirectory to the current directoy subdir
std::string nextDir = subdir;
nextDir += "/";
nextDir += i->c_str();
// recurse into nextDir
this->FindAllCMakeListsFiles(nextDir.c_str(),
makefiles);
}
}
else
{
cmSystemTools::Error("Can not find CMakeLists.txt in ",
currentDir.c_str());
}
}
// Write a DSW file to the stream
void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
{
// Write out the header for a DSW file
this->WriteDSWHeader(fout);
// Create an array of dsp files for the project
std::vector<cmMSProjectGenerator*> dspfiles;
// loop over all the subdirectories for the DSW file,
// and find all sub directory projects
const std::vector<std::string>& dirs = m_Makefile->GetSubDirectories();
for(std::vector<std::string>::const_iterator j = dirs.begin();
j != dirs.end(); ++j)
// Create a list of cmMakefile created from all the
// CMakeLists.txt files that are in sub directories of
// this one.
std::vector<cmMakefile*> allListFiles;
m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
// For each cmMakefile, create a DSP for it, and
// add it to this DSW file
for(std::vector<cmMakefile*>::iterator k = allListFiles.begin();
k != allListFiles.end(); ++k)
{
this->FindAllCMakeListsFiles(j->c_str(), dspfiles);
}
// For each DSP file created insert them into the DSW file
for(std::vector<cmMSProjectGenerator*>::iterator k = dspfiles.begin();
k != dspfiles.end(); ++k)
{
// Get the directory for the dsp file, it comes
// from the source, so it has the source path which needs
// to be removed as this may be built in a different directory
// than the source
std::string dir = (*k)->GetDSPMakefile()->
GetMakefile()->GetStartDirectory();
cmMakefile* mf = *k;
// Create an MS generator with DSW off, so it only creates dsp files
cmMSProjectGenerator* pg = new cmMSProjectGenerator;
pg->BuildDSWOff();
mf->SetMakefileGenerator(pg);
mf->GenerateMakefile();
// Get the source directory from the makefile
std::string dir = mf->GetStartDirectory();
// Get the home directory with the trailing slash
std::string homedir = m_Makefile->GetHomeDirectory();
homedir += "/";
// make the directory relative by removing the home directory part
// remove the home directory and / from the source directory
// this gives a relative path
cmSystemTools::ReplaceString(dir, homedir.c_str(), "");
// Get the list of create dsp files from the cmDSPMakefile, more
// Get the list of create dsp files names from the cmDSPMakefile, more
// than one dsp could have been created per input CMakeLists.txt file
std::vector<std::string> dspnames =
(*k)->GetDSPMakefile()->GetCreatedProjectNames();
pg->GetDSPMakefile()->GetCreatedProjectNames();
for(std::vector<std::string>::iterator si = dspnames.begin();
si != dspnames.end(); ++si)
{
// Write the project into the DSW file
this->WriteProject(fout, si->c_str(), dir.c_str(),
(*k)->GetDSPMakefile());
pg->GetDSPMakefile());
}
// delete the cmDSPMakefile object once done with it to avoid
// leaks
delete (*k)->GetDSPMakefile()->GetMakefile();
// delete the cmMakefile which also deletes the cmMSProjectGenerator
delete mf;
}
// Write the footer for the DSW file
this->WriteDSWFooter(fout);
}
// Write a dsp file into the DSW file,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmDSWMakefile::WriteProject(std::ostream& fout,
const char* dspname,
const char* dir,
cmDSPMakefile* project)
{
project->GetMakefile()->ExpandVariables();
fout << "#########################################################"
"######################\n\n";
fout << "Project: \"" << dspname << "\"="
@ -215,6 +140,7 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
fout << "}}}\n\n";
}
// Standard end of dsw file
void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
{
fout << "######################################################"
@ -227,6 +153,7 @@ void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
}
// ouput standard header for dsw file
void cmDSWMakefile::WriteDSWHeader(std::ostream& fout)
{
fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n";

View File

@ -20,9 +20,6 @@
#include "cmMSProjectGenerator.h"
#include <windows.h>
// microsoft nonsense
#undef GetCurrentDirectory
#undef SetCurrentDirectory
cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
{
@ -32,22 +29,17 @@ cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
// output the DSW file
void cmDSWMakefile::OutputDSWFile()
{
if(m_Makefile->GetStartOutputDirectory() == "")
{
// default to build in place
m_Makefile->SetStartOutputDirectory(m_Makefile->GetHomeDirectory());
}
// If the output directory is not the m_cmHomeDirectory
// then create it.
// if this is an out of source build, create the output directory
if(strcmp(m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeDirectory()) != 0)
{
if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
{
MessageBox(0, "Error creating directory ", 0, MB_OK);
MessageBox(0, m_Makefile->GetStartOutputDirectory(), 0, MB_OK);
cmSystemTools::Error("Error creating output directory for DSW file",
m_Makefile->GetStartOutputDirectory());
}
}
// create the dsw file name
std::string fname;
fname = m_Makefile->GetStartOutputDirectory();
fname += "/";
@ -56,139 +48,72 @@ void cmDSWMakefile::OutputDSWFile()
std::ofstream fout(fname.c_str());
if(!fout)
{
cmSystemTools::Error("Error can not open for write: " , fname.c_str());
cmSystemTools::Error("Error can not open DSW file for write: "
,fname.c_str());
return;
}
this->WriteDSWFile(fout);
}
// ------------------------------------------------
// Recursive function to find all the CMakeLists.txt files
// in a project. As each file is read in, any directories in
// the SUBDIR variable are also passed back to this function.
// The result is a vector of cmDSPMakefile objects, one for
// each directory with a CMakeLists.txt file
//
void
cmDSWMakefile
::FindAllCMakeListsFiles(const char* subdir,
std::vector<cmMSProjectGenerator*>& makefiles)
{
std::string currentDir = m_Makefile->GetCurrentDirectory();
currentDir += "/";
currentDir += subdir;
currentDir += "/";
currentDir += "CMakeLists.txt";
// CMakeLists.txt exits in the subdirectory
// then create a cmDSPMakefile for it
if(cmSystemTools::FileExists(currentDir.c_str()))
{
// Create a new cmDSPMakefile to read the currentDir CMakeLists.txt file
cmMSProjectGenerator* pg = new cmMSProjectGenerator;
pg->BuildDSWOff();
cmMakefile* mf = new cmMakefile;
mf->SetMakefileGenerator(pg);
// add it to the vector
makefiles.push_back(pg);
// Set up the file with the current context
mf->SetHomeOutputDirectory(m_Makefile->GetStartOutputDirectory());
mf->SetHomeDirectory(m_Makefile->GetHomeDirectory());
// Set the output directory which may be different than the source
std::string outdir = m_Makefile->GetStartOutputDirectory();
outdir += "/";
outdir += subdir;
mf->SetStartOutputDirectory(outdir.c_str());
// set the current directory in the Source as a full
// path
std::string currentDir = m_Makefile->GetStartDirectory();
currentDir += "/";
currentDir += subdir;
mf->SetStartDirectory(currentDir.c_str());
// Parse the CMakeLists.txt file
currentDir += "/CMakeLists.txt";
mf->MakeStartDirectoriesCurrent();
mf->ReadListFile(currentDir.c_str());
// Create the DSP file
mf->GenerateMakefile();
// Look at any sub directories parsed (SUBDIRS) and
// recurse into them
const std::vector<std::string>& subdirs = mf->GetSubDirectories();
for(std::vector<std::string>::const_iterator i = subdirs.begin();
i != subdirs.end(); ++i)
{
// append the subdirectory to the current directoy subdir
std::string nextDir = subdir;
nextDir += "/";
nextDir += i->c_str();
// recurse into nextDir
this->FindAllCMakeListsFiles(nextDir.c_str(),
makefiles);
}
}
else
{
cmSystemTools::Error("Can not find CMakeLists.txt in ",
currentDir.c_str());
}
}
// Write a DSW file to the stream
void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
{
// Write out the header for a DSW file
this->WriteDSWHeader(fout);
// Create an array of dsp files for the project
std::vector<cmMSProjectGenerator*> dspfiles;
// loop over all the subdirectories for the DSW file,
// and find all sub directory projects
const std::vector<std::string>& dirs = m_Makefile->GetSubDirectories();
for(std::vector<std::string>::const_iterator j = dirs.begin();
j != dirs.end(); ++j)
// Create a list of cmMakefile created from all the
// CMakeLists.txt files that are in sub directories of
// this one.
std::vector<cmMakefile*> allListFiles;
m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
// For each cmMakefile, create a DSP for it, and
// add it to this DSW file
for(std::vector<cmMakefile*>::iterator k = allListFiles.begin();
k != allListFiles.end(); ++k)
{
this->FindAllCMakeListsFiles(j->c_str(), dspfiles);
}
// For each DSP file created insert them into the DSW file
for(std::vector<cmMSProjectGenerator*>::iterator k = dspfiles.begin();
k != dspfiles.end(); ++k)
{
// Get the directory for the dsp file, it comes
// from the source, so it has the source path which needs
// to be removed as this may be built in a different directory
// than the source
std::string dir = (*k)->GetDSPMakefile()->
GetMakefile()->GetStartDirectory();
cmMakefile* mf = *k;
// Create an MS generator with DSW off, so it only creates dsp files
cmMSProjectGenerator* pg = new cmMSProjectGenerator;
pg->BuildDSWOff();
mf->SetMakefileGenerator(pg);
mf->GenerateMakefile();
// Get the source directory from the makefile
std::string dir = mf->GetStartDirectory();
// Get the home directory with the trailing slash
std::string homedir = m_Makefile->GetHomeDirectory();
homedir += "/";
// make the directory relative by removing the home directory part
// remove the home directory and / from the source directory
// this gives a relative path
cmSystemTools::ReplaceString(dir, homedir.c_str(), "");
// Get the list of create dsp files from the cmDSPMakefile, more
// Get the list of create dsp files names from the cmDSPMakefile, more
// than one dsp could have been created per input CMakeLists.txt file
std::vector<std::string> dspnames =
(*k)->GetDSPMakefile()->GetCreatedProjectNames();
pg->GetDSPMakefile()->GetCreatedProjectNames();
for(std::vector<std::string>::iterator si = dspnames.begin();
si != dspnames.end(); ++si)
{
// Write the project into the DSW file
this->WriteProject(fout, si->c_str(), dir.c_str(),
(*k)->GetDSPMakefile());
pg->GetDSPMakefile());
}
// delete the cmDSPMakefile object once done with it to avoid
// leaks
delete (*k)->GetDSPMakefile()->GetMakefile();
// delete the cmMakefile which also deletes the cmMSProjectGenerator
delete mf;
}
// Write the footer for the DSW file
this->WriteDSWFooter(fout);
}
// Write a dsp file into the DSW file,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmDSWMakefile::WriteProject(std::ostream& fout,
const char* dspname,
const char* dir,
cmDSPMakefile* project)
{
project->GetMakefile()->ExpandVariables();
fout << "#########################################################"
"######################\n\n";
fout << "Project: \"" << dspname << "\"="
@ -215,6 +140,7 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
fout << "}}}\n\n";
}
// Standard end of dsw file
void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
{
fout << "######################################################"
@ -227,6 +153,7 @@ void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
}
// ouput standard header for dsw file
void cmDSWMakefile::WriteDSWHeader(std::ostream& fout)
{
fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n";

View File

@ -460,3 +460,68 @@ void cmMakefile::ExpandVariablesInString(std::string& source)
}
}
// recursive function to create a vector of cmMakefile objects
// This is done by reading the sub directory CMakeLists.txt files,
// then calling this function with the new cmMakefile object
void
cmMakefile::FindSubDirectoryCMakeListsFiles(std::vector<cmMakefile*>&
makefiles)
{
// loop over all the sub directories of this makefile
const std::vector<std::string>& subdirs = this->GetSubDirectories();
for(std::vector<std::string>::const_iterator i = subdirs.begin();
i != subdirs.end(); ++i)
{
std::string subdir = *i;
// Create a path to the list file in the sub directory
std::string listFile = this->GetCurrentDirectory();
listFile += "/";
listFile += subdir;
listFile += "/CMakeLists.txt";
// if there is a CMakeLists.txt file read it
if(!cmSystemTools::FileExists(listFile.c_str()))
{
cmSystemTools::Error("CMakeLists.txt file missing from sub directory:",
listFile.c_str());
}
else
{
cmMakefile* mf = new cmMakefile;
makefiles.push_back(mf);
// initialize new makefile
mf->SetHomeOutputDirectory(this->GetHomeOutputDirectory());
mf->SetHomeDirectory(this->GetHomeDirectory());
// add the subdir to the start output directory
std::string outdir = this->GetStartOutputDirectory();
outdir += "/";
outdir += subdir;
mf->SetStartOutputDirectory(outdir.c_str());
// add the subdir to the start source directory
std::string currentDir = this->GetStartDirectory();
currentDir += "/";
currentDir += subdir;
mf->SetStartDirectory(currentDir.c_str());
// Parse the CMakeLists.txt file
currentDir += "/CMakeLists.txt";
mf->MakeStartDirectoriesCurrent();
mf->ReadListFile(currentDir.c_str());
// recurse into nextDir
mf->FindSubDirectoryCMakeListsFiles(makefiles);
}
}
}
void cmMakefile::GenerateCacheOnly()
{
std::vector<cmMakefile*> makefiles;
this->FindSubDirectoryCMakeListsFiles(makefiles);
for(int i =0; i < makefiles.size(); ++i)
{
delete makefiles[i];
}
}

View File

@ -346,6 +346,19 @@ public:
*/
void ExpandVariables();
/** Recursivly read and create a cmMakefile object for
* all CMakeLists.txt files in the GetSubDirectories list.
* Once the file is found, it ReadListFile is called on
* the cmMakefile created for it.
*/
void FindSubDirectoryCMakeListsFiles(std::vector<cmMakefile*>& makefiles);
/** Generate the cache file only. This is done
* by calling FindSubDirectoryCMakeListsFiles which
* will cause all the rules to fire, and the cache to
* be filled.
*/
void GenerateCacheOnly();
protected:
std::string m_Prefix;
std::vector<std::string> m_AuxSourceDirectories; //

View File

@ -20,6 +20,11 @@
#ifndef cmStandardIncludes_h
#define cmStandardIncludes_h
// include configure generated header to define
// CMAKE_NO_ANSI_STREAM_HEADERS and CMAKE_NO_STD_NAMESPACE
#ifdef CMAKE_HAS_AUTOCONF
#include "cmConfigure.h"
#endif
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )

View File

@ -15,12 +15,14 @@
=========================================================================*/
#include "cmSystemTools.h"
#include "errno.h"
#include "stdio.h"
#include <sys/stat.h>
#include "cmRegularExpression.h"
#if defined(_MSC_VER) || defined(__BORLANDC__)
#include <windows.h>
#include <direct.h>
#define _unlink unlink
inline int Mkdir(const char* dir)
{
return _mkdir(dir);
@ -35,6 +37,8 @@ inline int Mkdir(const char* dir)
}
#endif
bool cmSystemTools::s_ErrorOccured = false;
// adds the elements of the env variable path to the arg passed in
void cmSystemTools::GetPath(std::vector<std::string>& path)
{
@ -327,6 +331,7 @@ void cmSystemTools::Error(const char* m1, const char* m2)
{
message += m2;
}
cmSystemTools::s_ErrorOccured = true;
#if defined(_WIN32) && !defined(__CYGWIN__)
::MessageBox(0, message.c_str(), 0, MB_OK);
std::cerr << message.c_str() << std::endl;
@ -335,3 +340,100 @@ void cmSystemTools::Error(const char* m1, const char* m2)
#endif
}
void cmSystemTools::CopyFileIfDifferent(const char* source,
const char* destination)
{
if(cmSystemTools::FilesDiffer(source, destination))
{
cmSystemTools::Error("doing copy ", destination);
cmSystemTools::cmCopyFile(source, destination);
}
}
bool cmSystemTools::FilesDiffer(const char* source,
const char* destination)
{
struct stat statSource;
if (stat(source, &statSource) != 0)
{
return true;
}
struct stat statDestination;
if (stat(destination, &statDestination) != 0)
{
return true;
}
if(statSource.st_size != statDestination.st_size)
{
return true;
}
std::ifstream finSource(source);
std::ifstream finDestination(destination);
if(!finSource || !finDestination)
{
return true;
}
while(finSource && finDestination)
{
char s, d;
finSource >> s;
finDestination >> d;
if(s != d)
{
return true;
}
}
return false;
}
void cmSystemTools::cmCopyFile(const char* source,
const char* destination)
{
std::ifstream fin(source);
char buff[4096];
std::ofstream fout(destination);
if(!fout )
{
cmSystemTools::Error("CopyFile failed to open input file", source);
}
if(!fin)
{
cmSystemTools::Error("CopyFile failed to open output file", destination);
}
while(fin)
{
fin.getline(buff, 4096);
if(fin)
{
fout << buff << "\n";
}
}
}
// return true if the file exists
long int cmSystemTools::ModifiedTime(const char* filename)
{
struct stat fs;
if (stat(filename, &fs) != 0)
{
return 0;
}
else
{
return (long int)fs.st_mtime;
}
}
void cmSystemTools::RemoveFile(const char* source)
{
unlink(source);
}

View File

@ -47,9 +47,7 @@ public:
*/
static void ConvertToUnixSlashes(std::string& path);
/**
* Return true if a file exists in the current directory.
*/
///! Return true if a file exists in the current directory.
static bool FileExists(const char* filename);
/**
@ -92,6 +90,35 @@ public:
*/
static void Error(const char* m, const char* m2=0 );
///! Return true if there was an error at any point.
static bool GetErrorOccuredFlag()
{
return cmSystemTools::s_ErrorOccured;
}
/**
* Copy the source file to the destination file only
* if the two files differ.
*/
static void CopyFileIfDifferent(const char* source,
const char* destination);
///! Compare the contents of two files. Return true if different.
static bool FilesDiffer(const char* source,
const char* destination);
///! Copy a file.
static void cmCopyFile(const char* source,
const char* destination);
///! Remove a file.
static void RemoveFile(const char* source);
static long int ModifiedTime(const char* filename);
private:
static bool s_ErrorOccured;
};