ENH: first pass at cache, clean up the unix generator, clean up configure.in some

This commit is contained in:
Bill Hoffman 2001-02-19 15:13:48 -05:00
parent a4bbb55efd
commit 89e037ee19
22 changed files with 683 additions and 544 deletions

View File

@ -17,6 +17,19 @@
#include "cmStandardIncludes.h"
#include "cmMakeDepend.h"
#include "cmUnixMakefileGenerator.h"
#include "cmCacheManager.h"
void Usage(const char* program)
{
std::cerr << "Usage: " << program << " CMakeLists.txt "
<< "-Ssource_start_directory "
<< "-Ooutput_start_directory "
<< "-Hsource_home_directory "
<< "-Boutput_home_directory\n"
<< "Where start directories are the current place in the tree,"
"and the home directories are the top.\n";
}
// This is the main program used to gentrate makefile fragments
// from CMakeLists.txt input files.
@ -24,7 +37,7 @@ int main(int ac, char** av)
{
if(ac < 2)
{
std::cerr << "Usage: " << av[0] << " Makefile.in -Ipath ..." << std::endl;
Usage(av[0]);
return -1;
}
// Create a makefile
@ -66,10 +79,12 @@ int main(int ac, char** av)
// Read and parse the input makefile
mf.MakeStartDirectoriesCurrent();
cmCacheManager::GetInstance()->LoadCache(&mf);
if(!mf.ReadListFile(av[1]))
{
std::cerr << "Usage: " << av[0] << " Makefile.in -Ipath ..." << std::endl;
Usage(av[0]);
return -1;
}
mf.GenerateMakefile();
cmCacheManager::GetInstance()->SaveCache(&mf);
}

View File

@ -16,6 +16,7 @@
#include "cmStandardIncludes.h"
#include "cmMakefile.h"
#include "cmMSProjectGenerator.h"
#include "cmCacheManager.h"
// this is the command line version of CMakeSetup.
@ -59,13 +60,13 @@ int main(int ac, char** av)
if(ac < 3)
{
std::cerr << "Usage: " << av[0] <<
" CMakeLists.txt -[DSP|DSW] -Hinsighthome -Dcurrentdir"
" -Ooutput directory" << std::endl;
" CMakeLists.txt -[DSP|DSW] -Hsource_home -Sstart_source_directory "
" -Ostart_output_directory -Boutput_home" << std::endl;
return -1;
}
std::string arg = av[2];
cmMakefile builder;
SetArgs(builder, ac, av);
cmMakefile makefile;
SetArgs(makefile, ac, av);
cmMSProjectGenerator* pg = new cmMSProjectGenerator;
if(arg.find("-DSP", 0) != std::string::npos)
{
@ -75,10 +76,12 @@ int main(int ac, char** av)
{
pg->BuildDSWOn();
}
builder.SetMakefileGenerator(pg);
builder.MakeStartDirectoriesCurrent();
builder.ReadListFile(av[1]);
builder.GenerateMakefile();
makefile.SetMakefileGenerator(pg);
makefile.MakeStartDirectoriesCurrent();
cmCacheManager::GetInstance()->LoadCache(&makefile);
makefile.ReadListFile(av[1]);
makefile.GenerateMakefile();
cmCacheManager::GetInstance()->SaveCache(&makefile);
return 0;
}

View File

@ -89,7 +89,7 @@ IDD_CMakeSetupDialog_DIALOG DIALOGEX 0, 0, 320, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "CMakeSetupDialog"
FONT 8, "MS Sans Serif"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,260,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,260,23,50,14

View File

@ -7,6 +7,7 @@
#include "../cmDSWMakefile.h"
#include "../cmWindowsConfigure.h"
#include "../cmMSProjectGenerator.h"
#include "../cmCacheManager.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
@ -266,10 +267,13 @@ void CMakeSetupDialog::OnOK()
CString makefileIn = m_WhereSource;
makefileIn += "/CMakeLists.txt";
mf.MakeStartDirectoriesCurrent();
// Create a string for the cache file
cmCacheManager::GetInstance()->LoadCache(&mf);
mf.ReadListFile(makefileIn);
// Move this to the cache editor
mf.GenerateMakefile();
CDialog::OnOK();
cmCacheManager::GetInstance()->SaveCache(&mf);
this->SaveToRegistry();
}

View File

@ -16,9 +16,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_CONTROL_VALUE 1004
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -21,7 +21,8 @@ cmClassFile.o \
cmSystemTools.o \
cmDirectory.o \
cmUnixMakefileGenerator.o \
cmCommands.o
cmCommands.o \
cmCacheManager.o
cmCollectFlags.o : $(srcdir)/*.h
@ -35,6 +36,7 @@ cmClassFile.o : $(srcdir)/*.h
cmDirectory.o : $(srcdir)/*.h
cmUnixMakefileGenerator.o : $(srcdir)/*.h
cmCommands.o : $(srcdir)/*.h
cmCacheManager.o : $(srcdir)/*.h

View File

@ -16,10 +16,13 @@
#include "cmCacheManager.h"
#include "cmSystemTools.h"
#include "cmCacheManager.h"
#include "cmMakefile.h"
const char* cmCacheManagerTypes[] =
{ "BOOL",
"PATH",
"FILEPATH",
"STRING",
0
};
@ -33,6 +36,7 @@ cmCacheManager::CacheEntryType cmCacheManager::StringToType(const char* s)
{
return static_cast<CacheEntryType>(i);
}
++i;
}
return STRING;
}
@ -51,12 +55,15 @@ cmCacheManager* cmCacheManager::GetInstance()
bool cmCacheManager::LoadCache(const char* path)
bool cmCacheManager::LoadCache(cmMakefile* mf)
{
std::ifstream fin(path);
std::string cacheFile = mf->GetHomeOutputDirectory();
cacheFile += "/CMakeCache.txt";
// clear the old cache
m_Cache.clear();
std::ifstream fin(cacheFile.c_str());
if(!fin)
{
cmSystemTools::Error("Unable to open cache file for load. ", path);
return false;
}
const int bsize = 4096;
@ -64,37 +71,45 @@ bool cmCacheManager::LoadCache(const char* path)
std::string inputLine;
while(fin)
{
// Format is key:type=value
CacheEntry e;
std::string key;
fin.getline(buffer, bsize, '|');
fin.getline(buffer, bsize, ':');
key = buffer;
fin.getline(buffer, bsize, '|');
e.m_Value = buffer;
fin.getline(buffer, bsize); // last token is separated by a newline
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;
}
}
return true;
}
bool cmCacheManager::SaveCache(const char* path)
bool cmCacheManager::SaveCache(cmMakefile* mf)
{
std::ofstream fout(path);
std::string cacheFile = mf->GetHomeOutputDirectory();
cacheFile += "/CMakeCache.txt";
std::ofstream fout(cacheFile.c_str());
if(!fout)
{
cmSystemTools::Error("Unable to open cache file for save. ", path);
cmSystemTools::Error("Unable to open cache file for save. ",
cacheFile.c_str());
return false;
}
for( std::map<std::string, CacheEntry>::iterator i = m_Cache.begin();
i != m_Cache.end(); ++i)
{
fout << (*i).first.c_str() << " | " << (*i).second.m_Value << " | ";
CacheEntryType t = (*i).second.m_Type;
fout << cmCacheManagerTypes[t];
// Format is key:type=value
fout << (*i).first.c_str() << ":"
<< cmCacheManagerTypes[t] << "="
<< (*i).second.m_Value << "\n";
}
fout << "\n";
return true;
}
void cmCacheManager::AddCacheEntry(const char* key,

View File

@ -17,6 +17,7 @@
#define cmCacheManager_h
#include "cmStandardIncludes.h"
class cmMakefile;
/** \class cmCacheManager
* \brief Control class for cmake's cache
@ -31,24 +32,26 @@ public:
* Types for the cache entries. These are useful as
* hints for a cache editor program. Path should bring
* up a file chooser, BOOL a check box, and STRING a
* text entry box.
* text entry box, FILEPATH is a full path to a file which
* can be different than just a path input
*/
enum CacheEntryType{ BOOL=0, PATH, STRING };
enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING };
static CacheEntryType StringToType(const char*);
//! Singleton pattern get instance of the cmCacheManager.
static cmCacheManager* GetInstance();
//! Load a cache from file
bool LoadCache(const char* path);
//! Load a cache for given makefile. Loads from ouput home.
bool LoadCache(cmMakefile*);
//! Save the cache to a file
bool SaveCache(const char* path);
//! Save cache for given makefile. Saves to ouput home CMakeCache.txt
bool SaveCache(cmMakefile*);
//! Add an entry into the cache
void AddCacheEntry(const char* key, const char* value, CacheEntryType type);
//! Get a value from the cache given a key
const char* GetCacheValue(const char* key);
private:
static cmCacheManager* s_Instance;
class CacheEntry

View File

@ -53,15 +53,11 @@ public:
/**
* This is called at the end after all the information
* specified by the command is accumulated. Most commands do
* not implement this method.
* not implement this method. At this point, reading and
* writing to the cache can be done.
*/
virtual void FinalPass() {};
/**
* This is called to let the command check the cache.
*/
virtual void LoadCache() {}
/**
* This is a virtual constructor for the command.
*/

View File

@ -165,7 +165,8 @@ void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
cmSystemTools::ReplaceString(dir, homedir.c_str(), "");
// Get the list of create dsp files from the cmDSPMakefile, more
// than one dsp could have been created per input CMakeLists.txt file
std::vector<std::string> dspnames = (*k)->GetDSPMakefile()->GetCreatedProjectNames();
std::vector<std::string> dspnames =
(*k)->GetDSPMakefile()->GetCreatedProjectNames();
for(std::vector<std::string>::iterator si = dspnames.begin();
si != dspnames.end(); ++si)
{
@ -188,7 +189,8 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
cmDSPMakefile* project)
{
project->GetMakefile()->ExpandVariables();
fout << "###############################################################################\n\n";
fout << "#########################################################"
"######################\n\n";
fout << "Project: \"" << dspname << "\"="
<< dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n";
fout << "Package=<5>\n{{{\n}}}\n\n";
@ -215,11 +217,13 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
{
fout << "###############################################################################\n\n";
fout << "######################################################"
"#########################\n\n";
fout << "Global:\n\n";
fout << "Package=<5>\n{{{\n}}}\n\n";
fout << "Package=<3>\n{{{\n}}}\n\n";
fout << "###############################################################################\n\n";
fout << "#####################################################"
"##########################\n\n";
}

View File

@ -165,7 +165,8 @@ void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
cmSystemTools::ReplaceString(dir, homedir.c_str(), "");
// Get the list of create dsp files from the cmDSPMakefile, more
// than one dsp could have been created per input CMakeLists.txt file
std::vector<std::string> dspnames = (*k)->GetDSPMakefile()->GetCreatedProjectNames();
std::vector<std::string> dspnames =
(*k)->GetDSPMakefile()->GetCreatedProjectNames();
for(std::vector<std::string>::iterator si = dspnames.begin();
si != dspnames.end(); ++si)
{
@ -188,7 +189,8 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
cmDSPMakefile* project)
{
project->GetMakefile()->ExpandVariables();
fout << "###############################################################################\n\n";
fout << "#########################################################"
"######################\n\n";
fout << "Project: \"" << dspname << "\"="
<< dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n";
fout << "Package=<5>\n{{{\n}}}\n\n";
@ -215,11 +217,13 @@ void cmDSWMakefile::WriteProject(std::ostream& fout,
void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
{
fout << "###############################################################################\n\n";
fout << "######################################################"
"#########################\n\n";
fout << "Global:\n\n";
fout << "Package=<5>\n{{{\n}}}\n\n";
fout << "Package=<3>\n{{{\n}}}\n\n";
fout << "###############################################################################\n\n";
fout << "#####################################################"
"##########################\n\n";
}

View File

@ -14,6 +14,7 @@
=========================================================================*/
#include "cmFindIncludeCommand.h"
#include "cmCacheManager.h"
// cmFindIncludeCommand
bool cmFindIncludeCommand::Invoke(std::vector<std::string>& args)
@ -23,7 +24,15 @@ bool cmFindIncludeCommand::Invoke(std::vector<std::string>& args)
this->SetError("called with incorrect number of arguments");
return false;
}
// Now check and see if the value has been stored in the cache
// already, if so use that value and don't look for the program
const char* cacheValue
= cmCacheManager::GetInstance()->GetCacheValue(args[0].c_str());
if(cacheValue)
{
m_Makefile->AddDefinition(args[0].c_str(), cacheValue);
return true;
}
std::vector<std::string> path;
// add any user specified paths
for (int j = 2; j < args.size(); j++)
@ -45,8 +54,13 @@ bool cmFindIncludeCommand::Invoke(std::vector<std::string>& args)
if(cmSystemTools::FileExists(tryPath.c_str()))
{
m_Makefile->AddDefinition(args[0].c_str(), path[k].c_str());
// Save the value in the cache
cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
path[k].c_str(),
cmCacheManager::PATH);
return true;
}
}
return false;
}

View File

@ -14,6 +14,7 @@
=========================================================================*/
#include "cmFindLibraryCommand.h"
#include "cmCacheManager.h"
// cmFindLibraryCommand
bool cmFindLibraryCommand::Invoke(std::vector<std::string>& args)
@ -23,7 +24,15 @@ bool cmFindLibraryCommand::Invoke(std::vector<std::string>& args)
this->SetError("called with incorrect number of arguments");
return false;
}
// Now check and see if the value has been stored in the cache
// already, if so use that value and don't look for the program
const char* cacheValue
= cmCacheManager::GetInstance()->GetCacheValue(args[0].c_str());
if(cacheValue)
{
m_Makefile->AddDefinition(args[0].c_str(), cacheValue);
return true;
}
std::vector<std::string> path;
// add any user specified paths
for (int j = 2; j < args.size(); j++)
@ -45,8 +54,12 @@ bool cmFindLibraryCommand::Invoke(std::vector<std::string>& args)
if(cmSystemTools::FileExists(tryPath.c_str()))
{
m_Makefile->AddDefinition(args[0].c_str(), path[k].c_str());
cmCacheManager::GetInstance()->AddCacheEntry(args[0].c_str(),
path[k].c_str(),
cmCacheManager::PATH);
return true;
}
}
return false;
}

View File

@ -14,6 +14,7 @@
=========================================================================*/
#include "cmFindProgramCommand.h"
#include "cmCacheManager.h"
#include <stdlib.h>
#include <stdio.h>
@ -26,13 +27,22 @@ bool cmFindProgramCommand::Invoke(std::vector<std::string>& args)
this->SetError("called with incorrect number of arguments");
return false;
}
std::vector<std::string>::iterator i = args.begin();
// Use the first argument as the name of something to be defined
const char* define = (*i).c_str();
i++; // move iterator to next arg
// Now check and see if the value has been stored in the cache
// already, if so use that value and don't look for the program
const char* cacheValue
= cmCacheManager::GetInstance()->GetCacheValue(define);
if(cacheValue)
{
m_Makefile->AddDefinition(define, cacheValue);
return true;
}
// if it is not in the cache, then search the system path
std::vector<std::string> path;
cmSystemTools::GetPath(path);
std::vector<std::string>::iterator i = args.begin();
const char* define = (*i).c_str();
i++;
for(; i != args.end(); ++i)
{
for(int k=0; k < path.size(); k++)
@ -45,6 +55,10 @@ bool cmFindProgramCommand::Invoke(std::vector<std::string>& args)
#endif
if(cmSystemTools::FileExists(tryPath.c_str()))
{
// Save the value in the cache
cmCacheManager::GetInstance()->AddCacheEntry(define,
tryPath.c_str(),
cmCacheManager::FILEPATH);
m_Makefile->AddDefinition(define, tryPath.c_str());
return true;
}

View File

@ -14,7 +14,7 @@
=========================================================================*/
#include "cmIncludeDirectoryCommand.h"
#include "cmCacheManager.h"
// cmIncludeDirectoryCommand
bool cmIncludeDirectoryCommand::Invoke(std::vector<std::string>& args)
{

View File

@ -21,6 +21,7 @@
#include "cmSystemTools.h"
#include "cmMakefileGenerator.h"
#include "cmCommands.h"
#include "cmCacheManager.h"
// default is not to be building executables
cmMakefile::cmMakefile()
@ -170,7 +171,6 @@ bool cmMakefile::ReadListFile(const char* filename)
cmCommand* rm = (*pos).second;
cmCommand* usedCommand = rm->Clone();
usedCommand->SetMakefile(this);
usedCommand->LoadCache();
bool keepCommand = false;
if(usedCommand->GetEnabled())
{

View File

@ -56,7 +56,7 @@ const int NSUBEXP = 10;
* regular expression is a sequence of characters used to
* search for exact character matches. However, many times the
* exact sequence to be found is not known, or only a match at
* the beginning or end of a string is desired. The vbl regu-
* the beginning or end of a string is desired. The cmRegularExpression regu-
* lar expression class implements regular expression pattern
* matching as is found and implemented in many UNIX commands
* and utilities.
@ -68,7 +68,7 @@ const int NSUBEXP = 10;
*
* Is written as follows in C++
*
* vbl_reg_exp re("([a-z]+)\\.cc");
* cmRegularExpression re("([a-z]+)\\.cc");
* re.find(filename);
* cerr << re.match(1);
*

View File

@ -146,7 +146,8 @@ void cmSystemTools::ConvertToUnixSlashes(std::string& path)
}
int cmSystemTools::Grep(const char* dir, const char* file, const char* expression)
int cmSystemTools::Grep(const char* dir, const char* file,
const char* expression)
{
std::string path = dir;
path += "/";
@ -327,7 +328,7 @@ void cmSystemTools::Error(const char* m1, const char* m2)
message += m2;
}
#ifdef _WIN32
// MessageBox(0, message.c_str(), 0, MB_OK);
::MessageBox(0, message.c_str(), 0, MB_OK);
std::cerr << message.c_str() << std::endl;
#else
std::cerr << message.c_str() << std::endl;

View File

@ -22,12 +22,314 @@
void cmUnixMakefileGenerator::GenerateMakefile()
{
// Generate depends
cmMakeDepend md;
md.SetMakefile(m_Makefile);
md.DoDepends();
// output the makefile fragment
this->OutputMakefile("CMakeTargets.make");
}
// This is where CMakeTargets.make is generated
void cmUnixMakefileGenerator::OutputMakefile(const char* file)
{
// Create sub directories fro aux source directories
std::vector<std::string>& auxSourceDirs =
m_Makefile->GetAuxSourceDirectories();
if( auxSourceDirs.size() )
{
// For the case when this is running as a remote build
// on unix, make the directory
for(std::vector<std::string>::iterator i = auxSourceDirs.begin();
i != auxSourceDirs.end(); ++i)
{
cmSystemTools::MakeDirectory(i->c_str());
}
}
std::ofstream fout(file);
if(!fout)
{
cmSystemTools::Error("Error can not open for write: ", file);
return;
}
this->OutputMakeFlags(fout);
this->OutputSourceToObjectList(fout);
this->OutputVerbatim(fout);
this->OutputExecutableRules(fout);
this->OutputSubDirectoryRules(fout);
this->OutputDepends(fout);
}
// Output the LIBRARY and SRC_OBJS list based on
// the library name and cmClassFile objects in the
// makefile
void cmUnixMakefileGenerator::OutputSourceToObjectList(std::ostream& fout)
{
std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
if(Classes.size() == 0)
{
return;
}
// Ouput Library name if there are SRC_OBJS
if(strlen(m_Makefile->GetLibraryName()) > 0)
{
fout << "LIBRARY = " << m_Makefile->GetLibraryName() << "\n\n";
fout << "BUILD_LIB_FILE = lib${LIBRARY}${CMAKE_LIB_EXT}\n\n";
}
// Output SRC_OBJ list for all the classes to be compiled
fout << "SRC_OBJ = \\\n";
for(unsigned int i = 0; i < Classes.size(); i++)
{
if(!Classes[i].m_AbstractClass && !Classes[i].m_HeaderFileOnly
&& !Classes[i].m_IsExecutable)
{
fout << Classes[i].m_ClassName << ".o ";
if(i == Classes.size() -1)
{
fout << "\n\n";
}
else
{
fout << "\\\n";
}
}
}
fout << "\n";
}
// output the list of libraries that the executables
// in this makefile will depend on.
void cmUnixMakefileGenerator::OutputDependLibraries(std::ostream& fout)
{
std::vector<std::string>& libs = m_Makefile->GetLinkLibraries();
std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
std::vector<std::string>::iterator dir, lib, endlibs, enddirs;
// Search the list of libraries that will be linked into
// the executable
for(lib = libs.begin(); lib != libs.end(); ++lib)
{
bool found = false;
// loop over the list of directories that the libraries might
// be in, looking for a LIBRARY=(lib) line.
for(dir = libdirs.begin(); dir != libdirs.end() && !found; ++dir)
{
std::string expression = "LIBRARY.*=.*";
expression += lib->c_str();
if(cmSystemTools::Grep(dir->c_str(), "CMakeTargets.make",
expression.c_str()))
{
std::string libpath = *dir;
libpath += "/lib";
libpath += *lib;
libpath += "${CMAKE_LIB_EXT}";
fout << libpath << " ";
found = true;
}
}
}
fout << "\n";
}
// output make include flags
void cmUnixMakefileGenerator::OutputMakeFlags(std::ostream& fout)
{
// Output Include paths
fout << "INCLUDE_FLAGS = ";
std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
std::vector<std::string>::iterator i;
for(i = includes.begin(); i != includes.end(); ++i)
{
std::string include = *i;
fout << "-I" << i->c_str() << " ";
}
fout << " ${LOCAL_INCLUDE_FLAGS} ";
fout << "\n";
fout << "default_target: all\n\n";
// see if there are files to compile in this makefile
// These are used for both libraries and executables
}
// output verbatim section
void cmUnixMakefileGenerator::OutputVerbatim(std::ostream& fout)
{
std::vector<std::string>& MakeVerbatim = m_Makefile->GetMakeVerbatim();
// Ouput user make text embeded in the input file
for(unsigned int i =0; i < MakeVerbatim.size(); i++)
{
fout << MakeVerbatim[i] << "\n";
}
fout << "\n\n";
}
// output executables
void cmUnixMakefileGenerator::OutputExecutableRules(std::ostream& fout)
{
if(!m_Makefile->HasExecutables())
{
return ;
}
// collect all the flags needed for linking libraries
std::string linkLibs;
std::vector<std::string>::iterator j;
std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
for(j = libdirs.begin(); j != libdirs.end(); ++j)
{
std::string::size_type pos = (*j).find("-L");
if((pos == std::string::npos || pos > 0)
&& (*j).find("${") == std::string::npos)
{
linkLibs += "-L";
}
linkLibs += *j;
linkLibs += " ";
}
std::vector<std::string>& libs = m_Makefile->GetLinkLibraries();
for(j = libs.begin(); j != libs.end(); ++j)
{
std::string::size_type pos = (*j).find("-l");
if((pos == std::string::npos || pos > 0)
&& (*j).find("${") == std::string::npos)
{
linkLibs += "-l";
}
linkLibs += *j;
linkLibs += " ";
}
std::vector<std::string>& libsUnix = m_Makefile->GetLinkLibrariesUnix();
for(j = libsUnix.begin(); j != libsUnix.end(); ++j)
{
linkLibs += *j;
linkLibs += " ";
}
linkLibs += " ${LOCAL_LINK_FLAGS} ";
// create and output a varible in the makefile that
// each executable will depend on. This will have all the
// libraries that the executable uses
fout << "CMAKE_DEPEND_LIBS = ";
this->OutputDependLibraries(fout);
// Now create rules for all of the executables to be built
std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
for(unsigned int i = 0; i < Classes.size(); i++)
{
if(!Classes[i].m_AbstractClass && !Classes[i].m_HeaderFileOnly
&& Classes[i].m_IsExecutable)
{
std::string DotO = Classes[i].m_ClassName;
DotO += ".o";
fout << Classes[i].m_ClassName << ": " << DotO << " ";
fout << "${CMAKE_DEPEND_LIBS}\n";
fout << "\t${CXX} ${CXX_FLAGS} " << m_Makefile->GetDefineFlags()
<< DotO.c_str() << " "
<< linkLibs.c_str()
<< " -o $@ ""\n\n";
}
}
// ouput the list of executables
fout << "EXECUTABLES = \\\n";
for(unsigned int i = 0; i < Classes.size(); i++)
{
if(!Classes[i].m_AbstractClass && !Classes[i].m_HeaderFileOnly
&& Classes[i].m_IsExecutable)
{
fout << Classes[i].m_ClassName;
if(i < Classes.size()-1)
{
fout << " \\";
}
fout << "\n";
}
}
fout << "\n";
}
// fix up names of directories so they can be used
// as targets in makefiles.
inline std::string FixDirectoryName(const char* dir)
{
std::string s = dir;
// replace ../ with 3 under bars
size_t pos = s.find("../");
if(pos != std::string::npos)
{
s.replace(pos, 3, "___");
}
// replace / directory separators with a single under bar
pos = s.find("/");
while(pos != std::string::npos)
{
s.replace(pos, 1, "_");
pos = s.find("/");
}
return s;
}
// output rules for decending into sub directories
void cmUnixMakefileGenerator::OutputSubDirectoryRules(std::ostream& fout)
{
// Output Sub directory build rules
const std::vector<std::string>& SubDirectories
= m_Makefile->GetSubDirectories();
if( SubDirectories.size() == 0)
{
return;
}
fout << "SUBDIR_BUILD = \\\n";
unsigned int i;
for(i =0; i < SubDirectories.size(); i++)
{
std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
fout << "build_" << subdir.c_str();
if(i == SubDirectories.size()-1)
{
fout << " \n\n";
}
else
{
fout << " \\\n";
}
}
fout << std::endl;
fout << "SUBDIR_CLEAN = \\\n";
for(i =0; i < SubDirectories.size(); i++)
{
std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
fout << "clean_" << subdir.c_str();
if(i == SubDirectories.size()-1)
{
fout << " \n\n";
}
else
{
fout << " \\\n";
}
}
fout << std::endl;
fout << "alldirs : ${SUBDIR_BUILD}\n\n";
for(i =0; i < SubDirectories.size(); i++)
{
std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
fout << "build_" << subdir.c_str() << ":\n";
fout << "\tcd " << SubDirectories[i].c_str()
<< "; ${MAKE} -${MAKEFLAGS} CMakeTargets.make\n";
fout << "\tcd " << SubDirectories[i].c_str()
<< "; ${MAKE} -${MAKEFLAGS} all\n\n";
fout << "clean_" << subdir.c_str() << ": \n";
fout << "\tcd " << SubDirectories[i].c_str()
<< "; ${MAKE} -${MAKEFLAGS} clean\n\n";
}
}
// Output the depend information for all the classes
// in the makefile. These would have been generated
// by the class cmMakeDepend GenerateMakefile
@ -59,260 +361,3 @@ void cmUnixMakefileGenerator::OutputDepends(std::ostream& fout)
}
}
}
// fix up names of directories so they can be used
// as targets in makefiles.
inline std::string FixDirectoryName(const char* dir)
{
std::string s = dir;
// replace ../ with 3 under bars
size_t pos = s.find("../");
if(pos != std::string::npos)
{
s.replace(pos, 3, "___");
}
// replace / directory separators with a single under bar
pos = s.find("/");
while(pos != std::string::npos)
{
s.replace(pos, 1, "_");
pos = s.find("/");
}
return s;
}
// This is where CMakeTargets.make is generated
// This function ouputs the following:
// 1. Include flags for the compiler
// 2. List of .o files that need to be compiled
// 3. Rules to build executables including -l and -L options
// 4. Rules to build in sub directories
// 5. The name of the library being built, if it is a library
void cmUnixMakefileGenerator::OutputMakefile(const char* file)
{
std::vector<std::string>& auxSourceDirs = m_Makefile->GetAuxSourceDirectories();
if( auxSourceDirs.size() )
{
// For the case when this is running as a remote build
// on unix, make the directory
for(std::vector<std::string>::iterator i = auxSourceDirs.begin();
i != auxSourceDirs.end(); ++i)
{
cmSystemTools::MakeDirectory(i->c_str());
}
}
std::ofstream fout(file);
if(!fout)
{
cmSystemTools::Error("Error can not open for write: ", file);
return;
}
// Output Include paths
fout << "INCLUDE_FLAGS = ";
std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
std::vector<std::string>::iterator i;
for(i = includes.begin(); i != includes.end(); ++i)
{
std::string include = *i;
fout << "-I" << i->c_str() << " ";
}
fout << " ${LOCAL_INCLUDE_FLAGS} ";
fout << "\n";
// see if there are files to compile in this makefile
// These are used for both libraries and executables
std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
if(Classes.size() )
{
// Ouput Library name if there are SRC_OBJS
if(strlen(m_Makefile->GetLibraryName()) > 0)
{
fout << "LIBRARY = " << m_Makefile->GetLibraryName() << "\n\n";
fout << "BUILD_LIB_FILE = lib${LIBRARY}${CMAKE_LIB_EXT}\n\n";
}
// Output SRC_OBJ list for all the classes to be compiled
fout << "SRC_OBJ = \\\n";
for(unsigned int i = 0; i < Classes.size(); i++)
{
if(!Classes[i].m_AbstractClass && !Classes[i].m_HeaderFileOnly)
{
fout << Classes[i].m_ClassName << ".o ";
if(i == Classes.size() -1)
{
fout << "\n\n";
}
else
{
fout << "\\\n";
}
}
}
fout << "\n";
}
std::vector<std::string>& MakeVerbatim = m_Makefile->GetMakeVerbatim();
// Ouput user make text embeded in the input file
for(unsigned int i =0; i < MakeVerbatim.size(); i++)
{
fout << MakeVerbatim[i] << "\n";
}
fout << "\n\n";
// Output rules for building executables
if( m_Makefile->HasExecutables() )
{
// collect all the flags needed for linking libraries
std::string linkLibs;
std::vector<std::string>::iterator j;
std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
for(j = libdirs.begin(); j != libdirs.end(); ++j)
{
std::string::size_type pos = (*j).find("-L");
if((pos == std::string::npos || pos > 0)
&& (*j).find("${") == std::string::npos)
{
linkLibs += "-L";
}
linkLibs += *j;
linkLibs += " ";
}
std::vector<std::string>& libs = m_Makefile->GetLinkLibraries();
for(j = libs.begin(); j != libs.end(); ++j)
{
std::string::size_type pos = (*j).find("-l");
if((pos == std::string::npos || pos > 0)
&& (*j).find("${") == std::string::npos)
{
linkLibs += "-l";
}
linkLibs += *j;
linkLibs += " ";
}
std::vector<std::string>& libsUnix = m_Makefile->GetLinkLibrariesUnix();
for(j = libsUnix.begin(); j != libsUnix.end(); ++j)
{
linkLibs += *j;
linkLibs += " ";
}
linkLibs += " ${LOCAL_LINK_FLAGS} ";
// create and output a varible in the makefile that
// each executable will depend on. This will have all the
// libraries that the executable uses
fout << "CMAKE_DEPEND_LIBS = ";
this->OutputDependLibraries(fout);
// Now create rules for all of the executables to be built
for(unsigned int i = 0; i < Classes.size(); i++)
{
if(!Classes[i].m_AbstractClass && !Classes[i].m_HeaderFileOnly)
{
std::string DotO = Classes[i].m_ClassName;
DotO += ".o";
fout << Classes[i].m_ClassName << ": " << DotO << " ";
fout << "${CMAKE_DEPEND_LIBS}\n";
fout << "\t${CXX} ${CXX_FLAGS} " << m_Makefile->GetDefineFlags()
<< DotO.c_str() << " "
<< linkLibs.c_str()
<< " -o $@ ""\n\n";
}
}
// ouput the list of executables
fout << "EXECUTABLES = \\\n";
for(unsigned int i = 0; i < Classes.size(); i++)
{
if(!Classes[i].m_AbstractClass && !Classes[i].m_HeaderFileOnly)
{
fout << Classes[i].m_ClassName;
if(i < Classes.size()-1)
{
fout << " \\";
}
fout << "\n";
}
}
fout << "\n";
}
// Output Sub directory build rules
const std::vector<std::string>& SubDirectories
= m_Makefile->GetSubDirectories();
if( SubDirectories.size() )
{
fout << "SUBDIR_BUILD = \\\n";
unsigned int i;
for(i =0; i < SubDirectories.size(); i++)
{
std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
fout << "build_" << subdir.c_str();
if(i == SubDirectories.size()-1)
{
fout << " \n\n";
}
else
{
fout << " \\\n";
}
}
fout << std::endl;
fout << "SUBDIR_CLEAN = \\\n";
for(i =0; i < SubDirectories.size(); i++)
{
std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
fout << "clean_" << subdir.c_str();
if(i == SubDirectories.size()-1)
{
fout << " \n\n";
}
else
{
fout << " \\\n";
}
}
fout << std::endl;
fout << "alldirs : ${SUBDIR_BUILD}\n\n";
for(i =0; i < SubDirectories.size(); i++)
{
std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
fout << "build_" << subdir.c_str() << ":\n";
fout << "\tcd " << SubDirectories[i].c_str()
<< "; ${MAKE} -${MAKEFLAGS} CMakeTargets.make\n";
fout << "\tcd " << SubDirectories[i].c_str()
<< "; ${MAKE} -${MAKEFLAGS} all\n\n";
fout << "clean_" << subdir.c_str() << ": \n";
fout << "\tcd " << SubDirectories[i].c_str()
<< "; ${MAKE} -${MAKEFLAGS} clean\n\n";
}
}
this->OutputDepends(fout);
}
// output the list of libraries that the executables
// in this makefile will depend on.
void cmUnixMakefileGenerator::OutputDependLibraries(std::ostream& fout)
{
std::vector<std::string>& libs = m_Makefile->GetLinkLibraries();
std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
std::vector<std::string>::iterator dir, lib, endlibs, enddirs;
for(lib = libs.begin(); lib != libs.end(); ++lib)
{
bool found = false;
for(dir = libdirs.begin(); dir != libdirs.end() && !found; ++dir)
{
std::string expression = "LIBRARY.*=.*";
expression += lib->c_str();
if(cmSystemTools::Grep(dir->c_str(), "CMakeTargets.make", expression.c_str()))
{
std::string libpath = *dir;
libpath += "/lib";
libpath += *lib;
libpath += "${CMAKE_LIB_EXT}";
fout << libpath << " ";
found = true;
}
}
}
fout << "\n";
}

View File

@ -42,6 +42,12 @@ public:
protected:
void OutputMakefile(const char* file);
void OutputMakeFlags(std::ostream&);
void OutputVerbatim(std::ostream&);
void OutputSourceToObjectList(std::ostream& fout);
void OutputExecutableRules(std::ostream&);
void OutputSubDirectoryRules(std::ostream&);
void OutputDependInformation(std::ostream&);
void OutputDependLibraries(std::ostream&);
};

View File

@ -583,7 +583,7 @@ if test "x$srcdir" = x.; then
else
allDirs=`echo $allDirs | sed -e "s|$srcdir/||g"`
fi
SUBDIR_MAKEFILES=`echo $allDirs | sed -e 's|\\([[A-Za-z0-9_/]][[A-Za-z0-9_/]]*\\)|\1/Makefile:CMake/MakefileTemplate.in|g'`
SUBDIR_MAKEFILES=`echo $allDirs | sed -e 's|\\([[A-Za-z0-9_/]][[A-Za-z0-9_/]]*\\)|\1/Makefile:CMake/CMakeMakefileTemplate.in|g'`
SUBDIR_CMAKE_TARGETS=`echo $allDirs | sed -e 's|\\([[A-Za-z0-9_/]][[A-Za-z0-9_/]]*\\)|\1/CMakeTargets.make:CMake/CMakeTargets.make.in|g'`
@ -601,7 +601,7 @@ SUBDIR_CMAKE_TARGETS=`echo $allDirs | sed -e 's|\\([[A-Za-z0-9_/]][[A-Za-z0-9_/]
# sub directories found in CMakeLists.txt files
AC_OUTPUT(
Makefile:CMake/MakefileTemplate.in
Makefile:CMake/CMakeMakefileTemplate.in
CMakeTargets.make:CMake/CMakeTargets.make.in
CMake/CMakeSimpleRules.make
CMake/CMakeMaster.make