Commit 0b0d1b1d authored by Bill Hoffman's avatar Bill Hoffman
Browse files

ENH: add CMakeCache.txt support

parent 5d903c6b
......@@ -20,9 +20,16 @@ depend: ${CMAKE} ${SUBDIR_DEPEND}
clean: ${SUBDIR_CLEAN}
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}
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
#
......
srcdir = @srcdir@
VPATH = @srcdir@
topall:
cd . ; ${MAKE} -${MAKEFLAGS} CMakeTargets.make
cd . ; ${MAKE} -${MAKEFLAGS} all
@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_CONFIG_DIR@/CMake/CMakeMaster.make@MAKEQUOTE@
......@@ -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)
}
}
}
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
mf.MakeStartDirectoriesCurrent();
......@@ -85,6 +96,24 @@ int main(int ac, char** av)
Usage(av[0]);
return -1;
}
mf.GenerateMakefile();
if(makeCache)
{
mf.GenerateCacheOnly();
}
else
{
mf.GenerateMakefile();
}
cmCacheManager::GetInstance()->SaveCache(&mf);
if(makeCache)
{
cmCacheManager::GetInstance()->PrintCache(cout);
}
if(cmSystemTools::GetErrorOccuredFlag())
{
return -1;
}
return 0;
}
......@@ -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()
......
......@@ -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,22 +24,23 @@ 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)
CMakeBuildTargets: ${OBJS}
${CXX} ${OBJS} ${CXX_FLAGS} -o CMakeBuildTargets
${CXX} ${OBJS} ${CXX_FLAGS} -o CMakeBuildTargets
......@@ -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;
}
......@@ -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
......
#undef CMAKE_NO_STD_NAMESPACE
#undef CMAKE_NO_ANSI_STREAM_HEADERS
......@@ -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);
inLine = buffer;
m_Makefile->ExpandVariablesInString(inLine);
fout << inLine << "\n";
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
}
......
......@@ -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)
......
......@@ -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)
......
......@@ -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();