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

@ -20,9 +20,16 @@ depend: ${CMAKE} ${SUBDIR_DEPEND}
clean: ${SUBDIR_CLEAN} clean: ${SUBDIR_CLEAN}
rm -f ${SRC_OBJ} ${EXECUTABLES} rm -f ${SRC_OBJ} ${EXECUTABLES}
CMakeTargets.make: ${CMAKE} ${srcdir}/CMakeLists.txt CMakeTargets.make: ${CMAKE} ${srcdir}/CMakeLists.txt
${CMAKE} ${currentdir}/CMakeLists.txt -S${currentdir} -O${currentbindir} -H${topdir} -B${CMAKE_CONFIG_DIR} ${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 # 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 // Create a makefile
cmMakefile mf; cmMakefile mf;
mf.AddDefinition("UNIX", "1"); mf.AddDefinition("UNIX", "1");
bool makeCache = false;
// Parse the command line // Parse the command line
if(ac > 2) if(ac > 2)
{ {
@ -50,6 +51,11 @@ int main(int ac, char** av)
{ {
std::string arg = av[i]; std::string arg = av[i];
// Set the start source directory with a -S dir options // 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) if(arg.find("-S",0) == 0)
{ {
std::string path = arg.substr(2); std::string path = arg.substr(2);
@ -75,7 +81,12 @@ int main(int ac, char** av)
} }
} }
} }
mf.SetMakefileGenerator(new cmUnixMakefileGenerator); // Only generate makefiles if not trying to make the cache
if(!makeCache)
{
mf.SetMakefileGenerator(new cmUnixMakefileGenerator);
}
// Read and parse the input makefile // Read and parse the input makefile
mf.MakeStartDirectoriesCurrent(); mf.MakeStartDirectoriesCurrent();
@ -85,6 +96,24 @@ int main(int ac, char** av)
Usage(av[0]); Usage(av[0]);
return -1; return -1;
} }
mf.GenerateMakefile(); if(makeCache)
{
mf.GenerateCacheOnly();
}
else
{
mf.GenerateMakefile();
}
cmCacheManager::GetInstance()->SaveCache(&mf); 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); mf.ReadListFile(makefileIn);
// Move this to the cache editor // Move this to the cache editor
mf.GenerateMakefile(); mf.GenerateMakefile();
CDialog::OnOK();
cmCacheManager::GetInstance()->SaveCache(&mf); 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(); this->SaveToRegistry();
CDialog::OnOK();
} }
void CMakeSetupDialog::OnButton3() void CMakeSetupDialog::OnButton3()

View File

@ -7,7 +7,7 @@ VPATH = @srcdir@
# command for changing into this directory # command for changing into this directory
# let cmake know that this was done with autoconf # 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/CMakeVariables.make@MAKEQUOTE@
@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_CONFIG_DIR@/CMake/CMakeSimpleRules.make@MAKEQUOTE@ @MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_CONFIG_DIR@/CMake/CMakeSimpleRules.make@MAKEQUOTE@
@ -24,22 +24,23 @@ cmUnixMakefileGenerator.o \
cmCommands.o \ cmCommands.o \
cmCacheManager.o cmCacheManager.o
DEPENDS = $(srcdir)/*.h ${CMAKE_CONFIG_DIR}/CMake/Source/cmConfigure.h
cmCollectFlags.o : $(srcdir)/*.h cmCollectFlags.o : $(DEPENDS)
CMakeBuildTargets.o : $(srcdir)/*.h CMakeBuildTargets.o : $(DEPENDS)
cmMakeDepend.o : $(srcdir)/*.h cmMakeDepend.o : $(DEPENDS)
cmMakefile.o : $(srcdir)/*.h cmMakefile.o : $(DEPENDS)
cmMakefileGenerator.o : $(srcdir)/*.h cmMakefileGenerator.o : $(DEPENDS)
cmAuxSourceDirectoryCommand.o : $(srcdir)/*.h cmAuxSourceDirectoryCommand.o : $(DEPENDS)
cmRegularExpression.o : $(srcdir)/*.h cmRegularExpression.o : $(DEPENDS)
cmClassFile.o : $(srcdir)/*.h cmClassFile.o : $(DEPENDS)
cmDirectory.o : $(srcdir)/*.h cmDirectory.o : $(DEPENDS)
cmUnixMakefileGenerator.o : $(srcdir)/*.h cmUnixMakefileGenerator.o : $(DEPENDS)
cmCommands.o : $(srcdir)/*.h cmCommands.o : $(DEPENDS)
cmCacheManager.o : $(srcdir)/*.h cmCacheManager.o : $(DEPENDS)
CMakeBuildTargets: ${OBJS} CMakeBuildTargets: ${OBJS}
${CXX} ${OBJS} ${CXX_FLAGS} -o CMakeBuildTargets ${CXX} ${OBJS} ${CXX_FLAGS} -o CMakeBuildTargets

View File

@ -18,6 +18,7 @@
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmCacheManager.h" #include "cmCacheManager.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmRegularExpression.h"
const char* cmCacheManagerTypes[] = const char* cmCacheManagerTypes[] =
{ "BOOL", { "BOOL",
@ -68,21 +69,27 @@ bool cmCacheManager::LoadCache(cmMakefile* mf)
} }
const int bsize = 4096; const int bsize = 4096;
char buffer[bsize]; char buffer[bsize];
std::string inputLine; // input line is: key:type=value
cmRegularExpression reg("(.*):(.*)=(.*)");
while(fin) while(fin)
{ {
// Format is key:type=value // Format is key:type=value
CacheEntry e; CacheEntry e;
std::string key; fin.getline(buffer, bsize);
fin.getline(buffer, bsize, ':'); // skip blank lines and comment lines
key = buffer; if(buffer[0] == '#' || buffer[0] == 0)
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)
{ {
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; return true;
@ -92,13 +99,25 @@ bool cmCacheManager::SaveCache(cmMakefile* mf)
{ {
std::string cacheFile = mf->GetHomeOutputDirectory(); std::string cacheFile = mf->GetHomeOutputDirectory();
cacheFile += "/CMakeCache.txt"; cacheFile += "/CMakeCache.txt";
std::ofstream fout(cacheFile.c_str()); std::string tempFile = cacheFile;
tempFile += ".tmp";
std::ofstream fout(tempFile.c_str());
if(!fout) if(!fout)
{ {
cmSystemTools::Error("Unable to open cache file for save. ", cmSystemTools::Error("Unable to open cache file for save. ",
cacheFile.c_str()); cacheFile.c_str());
return false; 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(); for( std::map<std::string, CacheEntry>::iterator i = m_Cache.begin();
i != m_Cache.end(); ++i) i != m_Cache.end(); ++i)
{ {
@ -109,6 +128,10 @@ bool cmCacheManager::SaveCache(cmMakefile* mf)
<< (*i).second.m_Value << "\n"; << (*i).second.m_Value << "\n";
} }
fout << "\n"; fout << "\n";
fout.close();
cmSystemTools::CopyFileIfDifferent(tempFile.c_str(),
cacheFile.c_str());
cmSystemTools::RemoveFile(tempFile.c_str());
return true; return true;
} }
@ -130,3 +153,20 @@ const char* cmCacheManager::GetCacheValue(const char* key)
} }
return 0; 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 //! Get a value from the cache given a key
const char* GetCacheValue(const char* key); const char* GetCacheValue(const char* key);
//! Print the cache to a stream
void PrintCache(std::ostream&);
private: private:
static cmCacheManager* s_Instance; static cmCacheManager* s_Instance;
class CacheEntry 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); std::string path = m_OuputFile.substr(0, pos);
cmSystemTools::MakeDirectory(path.c_str()); 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) if(!fout)
{ {
cmSystemTools::Error("Could not open file for write in copy operatation", cmSystemTools::Error("Could not open file for write in copy operatation",
m_OuputFile.c_str()); tempOutputFile.c_str());
return; return;
} }
// now copy input to output and expand varibles in the // now copy input to output and expand varibles in the
@ -64,10 +66,19 @@ void cmConfigureFileNoAutoconf::FinalPass()
while(fin) while(fin)
{ {
fin.getline(buffer, bufSize); fin.getline(buffer, bufSize);
inLine = buffer; if(fin)
m_Makefile->ExpandVariablesInString(inLine); {
fout << inLine << "\n"; 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 #endif
} }

View File

@ -16,15 +16,8 @@
#include "cmDSPMakefile.h" #include "cmDSPMakefile.h"
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
#include "cmSystemTools.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() cmDSPMakefile::~cmDSPMakefile()
{ {
} }
@ -37,7 +30,18 @@ cmDSPMakefile::cmDSPMakefile(cmMakefile*mf)
void cmDSPMakefile::OutputDSPFile() 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>& includes = m_Makefile->GetIncludeDirectories();
std::vector<std::string>::iterator i; std::vector<std::string>::iterator i;
for(i = includes.begin(); i != includes.end(); ++i) for(i = includes.begin(); i != includes.end(); ++i)
@ -77,20 +81,10 @@ void cmDSPMakefile::OutputDSPFile()
// add any extra define flags // add any extra define flags
m_ReleaseLibraryOptions = m_DebugLibraryOptions; m_ReleaseLibraryOptions = m_DebugLibraryOptions;
cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release"); 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) if(strlen(m_Makefile->GetLibraryName()) != 0)
{ {
this->SetBuildType(STATIC_LIBRARY); this->SetBuildType(STATIC_LIBRARY);
@ -117,9 +111,8 @@ void cmDSPMakefile::CreateExecutableDSPFiles()
std::ofstream fout(fname.c_str()); std::ofstream fout(fname.c_str());
if(!fout) if(!fout)
{ {
std::string message = "Error Writing "; cmSystemTools::Error("Error Writing ",
message += fname; fname.c_str());
Die(message.c_str());
} }
else else
{ {
@ -153,9 +146,8 @@ void cmDSPMakefile::CreateSingleDSP()
std::ofstream fout(fname.c_str()); std::ofstream fout(fname.c_str());
if(!fout) if(!fout)
{ {
std::string message = "Error Writing "; cmSystemTools::Error("Error Writing ",
message += fname; fname.c_str());
Die(message.c_str());
} }
this->WriteDSPFile(fout); this->WriteDSPFile(fout);
} }
@ -257,9 +249,7 @@ void cmDSPMakefile::WriteDSPHeader(std::ostream& fout)
std::ifstream fin(m_DSPHeaderTemplate.c_str()); std::ifstream fin(m_DSPHeaderTemplate.c_str());
if(!fin) if(!fin)
{ {
std::string message = "Error Reading "; cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
message += m_DSPHeaderTemplate;
Die(message.c_str());
} }
char buffer[2048]; char buffer[2048];
@ -288,9 +278,8 @@ void cmDSPMakefile::WriteDSPFooter(std::ostream& fout)
std::ifstream fin(m_DSPFooterTemplate.c_str()); std::ifstream fin(m_DSPFooterTemplate.c_str());
if(!fin) if(!fin)
{ {
std::string message = "Error Reading "; cmSystemTools::Error("Error Reading ",
message += m_DSPFooterTemplate; m_DSPFooterTemplate.c_str());
Die(message.c_str());
} }
char buffer[2048]; char buffer[2048];
while(fin) while(fin)

View File

@ -16,15 +16,8 @@
#include "cmDSPMakefile.h" #include "cmDSPMakefile.h"
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
#include "cmSystemTools.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() cmDSPMakefile::~cmDSPMakefile()
{ {
} }
@ -37,7 +30,18 @@ cmDSPMakefile::cmDSPMakefile(cmMakefile*mf)
void cmDSPMakefile::OutputDSPFile() 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>& includes = m_Makefile->GetIncludeDirectories();
std::vector<std::string>::iterator i; std::vector<std::string>::iterator i;
for(i = includes.begin(); i != includes.end(); ++i) for(i = includes.begin(); i != includes.end(); ++i)
@ -77,20 +81,10 @@ void cmDSPMakefile::OutputDSPFile()
// add any extra define flags // add any extra define flags
m_ReleaseLibraryOptions = m_DebugLibraryOptions; m_ReleaseLibraryOptions = m_DebugLibraryOptions;
cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release"); 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) if(strlen(m_Makefile->GetLibraryName()) != 0)
{ {
this->SetBuildType(STATIC_LIBRARY); this->SetBuildType(STATIC_LIBRARY);
@ -117,9 +111,8 @@ void cmDSPMakefile::CreateExecutableDSPFiles()
std::ofstream fout(fname.c_str()); std::ofstream fout(fname.c_str());
if(!fout) if(!fout)
{ {
std::string message = "Error Writing "; cmSystemTools::Error("Error Writing ",
message += fname; fname.c_str());
Die(message.c_str());
} }
else else
{ {
@ -153,9 +146,8 @@ void cmDSPMakefile::CreateSingleDSP()
std::ofstream fout(fname.c_str()); std::ofstream fout(fname.c_str());
if(!fout) if(!fout)
{ {
std::string message = "Error Writing "; cmSystemTools::Error("Error Writing ",
message += fname; fname.c_str());
Die(message.c_str());
} }
this->WriteDSPFile(fout); this->WriteDSPFile(fout);
} }
@ -257,9 +249,7 @@ void cmDSPMakefile::WriteDSPHeader(std::ostream& fout)
std::ifstream fin(m_DSPHeaderTemplate.c_str()); std::ifstream fin(m_DSPHeaderTemplate.c_str());
if(!fin) if(!fin)
{ {
std::string message = "Error Reading "; cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
message += m_DSPHeaderTemplate;
Die(message.c_str());
} }
char buffer[2048]; char buffer[2048];
@ -288,9 +278,8 @@ void cmDSPMakefile::WriteDSPFooter(std::ostream& fout)
std::ifstream fin(m_DSPFooterTemplate.c_str()); std::ifstream fin(m_DSPFooterTemplate.c_str());
if(!fin) if(!fin)
{ {
std::string message = "Error Reading "; cmSystemTools::Error("Error Reading ",
message += m_DSPFooterTemplate; m_DSPFooterTemplate.c_str());
Die(message.c_str());
} }
char buffer[2048]; char buffer[2048];
while(fin) while(fin)

View File

@ -20,9 +20,6 @@
#include "cmMSProjectGenerator.h" #include "cmMSProjectGenerator.h"
#include <windows.h> #include <windows.h>
// microsoft nonsense
#undef GetCurrentDirectory
#undef SetCurrentDirectory
cmDSWMakefile::cmDSWMakefile(cmMakefile* m) cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
{ {
@ -32,22 +29,17 @@ cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
// output the DSW file // output the DSW file
void cmDSWMakefile::OutputDSWFile() void cmDSWMakefile::OutputDSWFile()
{ {
if(m_Makefile->GetStartOutputDirectory() == "") // if this is an out of source build, create the output directory
{
// default to build in place
m_Makefile->SetStartOutputDirectory(m_Makefile->GetHomeDirectory());
}
// If the output directory is not the m_cmHomeDirectory
// then create it.
if(strcmp(m_Makefile->GetStartOutputDirectory(), if(strcmp(m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeDirectory()) != 0) m_Makefile->GetHomeDirectory()) != 0)
{ {
if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory())) if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
{ {
MessageBox(0, "Error creating directory ", 0, MB_OK); cmSystemTools::Error("Error creating output directory for DSW file",
MessageBox(0, m_Makefile->GetStartOutputDirectory(), 0, MB_OK); m_Makefile->GetStartOutputDirectory());
} }
} }
// create the dsw file name
std::string fname; std::string fname;
fname = m_Makefile->GetStartOutputDirectory(); fname = m_Makefile->GetStartOutputDirectory();
fname += "/"; fname += "/";
@ -56,139 +48,72 @@ void cmDSWMakefile::OutputDSWFile()
std::ofstream fout(fname.c_str()); std::ofstream fout(fname.c_str());
if(!fout) 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; return;
} }
this->WriteDSWFile(fout); 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 // Write a DSW file to the stream
void cmDSWMakefile::WriteDSWFile(std::ostream& fout) void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
{ {
// Write out the header for a DSW file // Write out the header for a DSW file
this->WriteDSWHeader(fout); this->WriteDSWHeader(fout);
// Create an array of dsp files for the project
std::vector<cmMSProjectGenerator*> dspfiles; // Create a list of cmMakefile created from all the
// loop over all the subdirectories for the DSW file, // CMakeLists.txt files that are in sub directories of
// and find all sub directory projects // this one.
const std::vector<std::string>& dirs = m_Makefile->GetSubDirectories(); std::vector<cmMakefile*> allListFiles;
for(std::vector<std::string>::const_iterator j = dirs.begin(); m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
j != dirs.end(); ++j)
// 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); cmMakefile* mf = *k;
} // Create an MS generator with DSW off, so it only creates dsp files
// For each DSP file created insert them into the DSW file cmMSProjectGenerator* pg = new cmMSProjectGenerator;
for(std::vector<cmMSProjectGenerator*>::iterator k = dspfiles.begin(); pg->BuildDSWOff();
k != dspfiles.end(); ++k) mf->SetMakefileGenerator(pg);
{ mf->GenerateMakefile();
// Get the directory for the dsp file, it comes // Get the source directory from the makefile
// from the source, so it has the source path which needs std::string dir = mf->GetStartDirectory();
// to be removed as this may be built in a different directory
// than the source
std::string dir = (*k)->GetDSPMakefile()->
GetMakefile()->GetStartDirectory();
// Get the home directory with the trailing slash // Get the home directory with the trailing slash
std::string homedir = m_Makefile->GetHomeDirectory(); std::string homedir = m_Makefile->GetHomeDirectory();
homedir += "/"; 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(), ""); 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 // than one dsp could have been created per input CMakeLists.txt file
std::vector<std::string> dspnames = std::vector<std::string> dspnames =
(*k)->GetDSPMakefile()->GetCreatedProjectNames(); pg->GetDSPMakefile()->GetCreatedProjectNames();
for(std::vector<std::string>::iterator si = dspnames.begin(); for(std::vector<std::string>::iterator si = dspnames.begin();
si != dspnames.end(); ++si) si != dspnames.end(); ++si)
{ {
// Write the project into the DSW file // Write the project into the DSW file
this->WriteProject(fout, si->c_str(), dir.c_str(), this->WriteProject(fout, si->c_str(), dir.c_str(),
(*k)->GetDSPMakefile()); pg->GetDSPMakefile());
} }
// delete the cmDSPMakefile object once done with it to avoid // delete the cmMakefile which also deletes the cmMSProjectGenerator
// leaks delete mf;
delete (*k)->GetDSPMakefile()->GetMakefile();
} }
// Write the footer for the DSW file // Write the footer for the DSW file
this->WriteDSWFooter(fout); 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, void cmDSWMakefile::WriteProject(std::ostream& fout,
const char* dspname, const char* dspname,
const char* dir, const char* dir,
cmDSPMakefile* project) cmDSPMakefile* project)
{ {
project->GetMakefile()->ExpandVariables();
fout << "#########################################################" fout << "#########################################################"
"######################\n\n"; "######################\n\n";
fout << "Project: \"" << dspname << "\"=" fout << "Project: \"" << dspname << "\"="
@ -204,17 +129,18 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
end = project->GetMakefile()->GetLinkLibraries().end(); end = project->GetMakefile()->GetLinkLibraries().end();
for(;i!= end; ++i) for(;i!= end; ++i)
{ {
if (strcmp(i->c_str(),dspname)) if (strcmp(i->c_str(),dspname))
{ {
fout << "Begin Project Dependency\n"; fout << "Begin Project Dependency\n";
fout << "Project_Dep_Name " << *i << "\n"; fout << "Project_Dep_Name " << *i << "\n";
fout << "End Project Dependency\n"; fout << "End Project Dependency\n";
} }
} }
} }
fout << "}}}\n\n"; fout << "}}}\n\n";
} }
// Standard end of dsw file
void cmDSWMakefile::WriteDSWFooter(std::ostream& fout) void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
{ {
fout << "######################################################" fout << "######################################################"
@ -227,6 +153,7 @@ void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
} }
// ouput standard header for dsw file
void cmDSWMakefile::WriteDSWHeader(std::ostream& fout) void cmDSWMakefile::WriteDSWHeader(std::ostream& fout)
{ {
fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n"; fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n";

View File

@ -20,9 +20,6 @@
#include "cmMSProjectGenerator.h" #include "cmMSProjectGenerator.h"
#include <windows.h> #include <windows.h>
// microsoft nonsense
#undef GetCurrentDirectory
#undef SetCurrentDirectory
cmDSWMakefile::cmDSWMakefile(cmMakefile* m) cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
{ {
@ -32,22 +29,17 @@ cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
// output the DSW file // output the DSW file
void cmDSWMakefile::OutputDSWFile() void cmDSWMakefile::OutputDSWFile()
{ {
if(m_Makefile->GetStartOutputDirectory() == "") // if this is an out of source build, create the output directory
{
// default to build in place
m_Makefile->SetStartOutputDirectory(m_Makefile->GetHomeDirectory());
}
// If the output directory is not the m_cmHomeDirectory
// then create it.
if(strcmp(m_Makefile->GetStartOutputDirectory(), if(strcmp(m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeDirectory()) != 0) m_Makefile->GetHomeDirectory()) != 0)
{ {
if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory())) if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
{ {
MessageBox(0, "Error creating directory ", 0, MB_OK); cmSystemTools::Error("Error creating output directory for DSW file",
MessageBox(0, m_Makefile->GetStartOutputDirectory(), 0, MB_OK); m_Makefile->GetStartOutputDirectory());
} }
} }
// create the dsw file name
std::string fname; std::string fname;
fname = m_Makefile->GetStartOutputDirectory(); fname = m_Makefile->GetStartOutputDirectory();
fname += "/"; fname += "/";
@ -56,139 +48,72 @@ void cmDSWMakefile::OutputDSWFile()
std::ofstream fout(fname.c_str()); std::ofstream fout(fname.c_str());
if(!fout) 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; return;
} }
this->WriteDSWFile(fout); 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 // Write a DSW file to the stream
void cmDSWMakefile::WriteDSWFile(std::ostream& fout) void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
{ {
// Write out the header for a DSW file // Write out the header for a DSW file
this->WriteDSWHeader(fout); this->WriteDSWHeader(fout);
// Create an array of dsp files for the project
std::vector<cmMSProjectGenerator*> dspfiles; // Create a list of cmMakefile created from all the
// loop over all the subdirectories for the DSW file, // CMakeLists.txt files that are in sub directories of
// and find all sub directory projects // this one.
const std::vector<std::string>& dirs = m_Makefile->GetSubDirectories(); std::vector<cmMakefile*> allListFiles;
for(std::vector<std::string>::const_iterator j = dirs.begin(); m_Makefile->FindSubDirectoryCMakeListsFiles(allListFiles);
j != dirs.end(); ++j)
// 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); cmMakefile* mf = *k;
} // Create an MS generator with DSW off, so it only creates dsp files
// For each DSP file created insert them into the DSW file cmMSProjectGenerator* pg = new cmMSProjectGenerator;
for(std::vector<cmMSProjectGenerator*>::iterator k = dspfiles.begin(); pg->BuildDSWOff();
k != dspfiles.end(); ++k) mf->SetMakefileGenerator(pg);
{ mf->GenerateMakefile();
// Get the directory for the dsp file, it comes // Get the source directory from the makefile
// from the source, so it has the source path which needs std::string dir = mf->GetStartDirectory();
// to be removed as this may be built in a different directory
// than the source
std::string dir = (*k)->GetDSPMakefile()->
GetMakefile()->GetStartDirectory();
// Get the home directory with the trailing slash // Get the home directory with the trailing slash
std::string homedir = m_Makefile->GetHomeDirectory(); std::string homedir = m_Makefile->GetHomeDirectory();
homedir += "/"; 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(), ""); 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 // than one dsp could have been created per input CMakeLists.txt file
std::vector<std::string> dspnames = std::vector<std::string> dspnames =
(*k)->GetDSPMakefile()->GetCreatedProjectNames(); pg->GetDSPMakefile()->GetCreatedProjectNames();
for(std::vector<std::string>::iterator si = dspnames.begin(); for(std::vector<std::string>::iterator si = dspnames.begin();
si != dspnames.end(); ++si) si != dspnames.end(); ++si)
{ {
// Write the project into the DSW file // Write the project into the DSW file
this->WriteProject(fout, si->c_str(), dir.c_str(), this->WriteProject(fout, si->c_str(), dir.c_str(),
(*k)->GetDSPMakefile()); pg->GetDSPMakefile());
} }
// delete the cmDSPMakefile object once done with it to avoid // delete the cmMakefile which also deletes the cmMSProjectGenerator
// leaks delete mf;
delete (*k)->GetDSPMakefile()->GetMakefile();
} }
// Write the footer for the DSW file // Write the footer for the DSW file
this->WriteDSWFooter(fout); 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, void cmDSWMakefile::WriteProject(std::ostream& fout,
const char* dspname, const char* dspname,
const char* dir, const char* dir,
cmDSPMakefile* project) cmDSPMakefile* project)
{ {
project->GetMakefile()->ExpandVariables();
fout << "#########################################################" fout << "#########################################################"
"######################\n\n"; "######################\n\n";
fout << "Project: \"" << dspname << "\"=" fout << "Project: \"" << dspname << "\"="
@ -204,17 +129,18 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
end = project->GetMakefile()->GetLinkLibraries().end(); end = project->GetMakefile()->GetLinkLibraries().end();
for(;i!= end; ++i) for(;i!= end; ++i)
{ {
if (strcmp(i->c_str(),dspname)) if (strcmp(i->c_str(),dspname))
{ {
fout << "Begin Project Dependency\n"; fout << "Begin Project Dependency\n";
fout << "Project_Dep_Name " << *i << "\n"; fout << "Project_Dep_Name " << *i << "\n";
fout << "End Project Dependency\n"; fout << "End Project Dependency\n";
} }
} }
} }
fout << "}}}\n\n"; fout << "}}}\n\n";
} }
// Standard end of dsw file
void cmDSWMakefile::WriteDSWFooter(std::ostream& fout) void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
{ {
fout << "######################################################" fout << "######################################################"
@ -227,6 +153,7 @@ void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
} }
// ouput standard header for dsw file
void cmDSWMakefile::WriteDSWHeader(std::ostream& fout) void cmDSWMakefile::WriteDSWHeader(std::ostream& fout)
{ {
fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n"; 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(); 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: protected:
std::string m_Prefix; std::string m_Prefix;
std::vector<std::string> m_AuxSourceDirectories; // std::vector<std::string> m_AuxSourceDirectories; //

View File

@ -20,6 +20,11 @@
#ifndef cmStandardIncludes_h #ifndef cmStandardIncludes_h
#define 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 #ifdef _MSC_VER
#pragma warning ( disable : 4786 ) #pragma warning ( disable : 4786 )

View File

@ -15,12 +15,14 @@
=========================================================================*/ =========================================================================*/
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "errno.h" #include "errno.h"
#include "stdio.h"
#include <sys/stat.h> #include <sys/stat.h>
#include "cmRegularExpression.h" #include "cmRegularExpression.h"
#if defined(_MSC_VER) || defined(__BORLANDC__) #if defined(_MSC_VER) || defined(__BORLANDC__)
#include <windows.h> #include <windows.h>
#include <direct.h> #include <direct.h>
#define _unlink unlink
inline int Mkdir(const char* dir) inline int Mkdir(const char* dir)
{ {
return _mkdir(dir); return _mkdir(dir);
@ -35,6 +37,8 @@ inline int Mkdir(const char* dir)
} }
#endif #endif
bool cmSystemTools::s_ErrorOccured = false;
// adds the elements of the env variable path to the arg passed in // adds the elements of the env variable path to the arg passed in
void cmSystemTools::GetPath(std::vector<std::string>& path) void cmSystemTools::GetPath(std::vector<std::string>& path)
{ {
@ -327,6 +331,7 @@ void cmSystemTools::Error(const char* m1, const char* m2)
{ {
message += m2; message += m2;
} }
cmSystemTools::s_ErrorOccured = true;
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
::MessageBox(0, message.c_str(), 0, MB_OK); ::MessageBox(0, message.c_str(), 0, MB_OK);
std::cerr << message.c_str() << std::endl; std::cerr << message.c_str() << std::endl;
@ -335,3 +340,100 @@ void cmSystemTools::Error(const char* m1, const char* m2)
#endif #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); 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); static bool FileExists(const char* filename);
/** /**
@ -91,7 +89,36 @@ public:
* Display an error message. * Display an error message.
*/ */
static void Error(const char* m, const char* m2=0 ); 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;
}; };