ENH: add cmExternalMakefileProjectGenerator, which should make it easier to

write generators for IDE projects, which use already existing makefiles
(current the kdevelop generator)
-first stept of the export interface, iniitial export() command
-more replacements for the FIND_XXX docs

Alex
This commit is contained in:
Alexander Neundorf 2007-06-08 11:57:16 -04:00
parent 79077f8373
commit 0ddc9f62e5
16 changed files with 950 additions and 359 deletions

View File

@ -37,6 +37,7 @@
#include "cmEndForEachCommand.cxx" #include "cmEndForEachCommand.cxx"
#include "cmEndIfCommand.cxx" #include "cmEndIfCommand.cxx"
#include "cmExecProgramCommand.cxx" #include "cmExecProgramCommand.cxx"
#include "cmExternalMakefileProjectGenerator.cxx"
#include "cmFindBase.cxx" #include "cmFindBase.cxx"
#include "cmFileCommand.cxx" #include "cmFileCommand.cxx"
#include "cmFindFileCommand.cxx" #include "cmFindFileCommand.cxx"

View File

@ -24,6 +24,7 @@
#include "cmEndMacroCommand.cxx" #include "cmEndMacroCommand.cxx"
#include "cmEndWhileCommand.cxx" #include "cmEndWhileCommand.cxx"
#include "cmExecuteProcessCommand.cxx" #include "cmExecuteProcessCommand.cxx"
#include "cmExportCommand.cxx"
#include "cmExportLibraryDependencies.cxx" #include "cmExportLibraryDependencies.cxx"
#include "cmFLTKWrapUICommand.cxx" #include "cmFLTKWrapUICommand.cxx"
#include "cmGetDirectoryPropertyCommand.cxx" #include "cmGetDirectoryPropertyCommand.cxx"
@ -76,6 +77,7 @@ void GetPredefinedCommands(std::list<cmCommand*>&
commands.push_back(new cmEndMacroCommand); commands.push_back(new cmEndMacroCommand);
commands.push_back(new cmEndWhileCommand); commands.push_back(new cmEndWhileCommand);
commands.push_back(new cmExecuteProcessCommand); commands.push_back(new cmExecuteProcessCommand);
commands.push_back(new cmExportCommand);
commands.push_back(new cmExportLibraryDependenciesCommand); commands.push_back(new cmExportLibraryDependenciesCommand);
commands.push_back(new cmFLTKWrapUICommand); commands.push_back(new cmFLTKWrapUICommand);
commands.push_back(new cmGetDirectoryPropertyCommand); commands.push_back(new cmGetDirectoryPropertyCommand);

233
Source/cmExportCommand.cxx Normal file
View File

@ -0,0 +1,233 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmExportCommand.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmake.h"
#include <cmsys/auto_ptr.hxx>
// cmExportCommand
bool cmExportCommand
::InitialPass(std::vector<std::string> const& args)
{
if(args.size() < 2 )
{
this->SetError("called with too few arguments");
return false;
}
std::string filename;
std::string prefix;
std::string exportName;
std::vector<std::string> targets;
bool append = false;
if (!this->ParseArgs(args, filename, prefix, exportName, targets, append))
{
return false;
}
if ( !this->Makefile->CanIWriteThisFile(filename.c_str()) )
{
std::string e = "attempted to write a file: " + filename
+ " into a source directory.";
this->SetError(e.c_str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
if ((targets.empty()) || (filename.empty()))
{
return true;
}
// Use copy-if-different if not appending.
cmsys::auto_ptr<std::ofstream> foutPtr;
if(append)
{
cmsys::auto_ptr<std::ofstream> ap(
new std::ofstream(filename.c_str(), std::ios::app));
foutPtr = ap;
}
else
{
cmsys::auto_ptr<cmGeneratedFileStream> ap(
new cmGeneratedFileStream(filename.c_str(), true));
ap->SetCopyIfDifferent(true);
foutPtr = ap;
}
std::ostream& fout = *foutPtr.get();
if (!fout)
{
cmSystemTools::Error("Error Writing ", filename.c_str());
cmSystemTools::ReportLastSystemError("");
return true;
}
// the following code may move into an "export generator"
// Compute the set of configurations.
std::vector<std::string> configurationTypes;
if(const char* types =
this->Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
{
cmSystemTools::ExpandListArgument(types, configurationTypes);
}
if(configurationTypes.empty())
{
const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
if (config!=0)
{
configurationTypes.push_back(config);
}
}
for(std::vector<std::string>::const_iterator currentTarget = targets.begin();
currentTarget != targets.end();
++currentTarget)
{
// Look for a CMake target with the given name, which is an executable
// and which can be run
cmTarget* target = this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->FindTarget(0, currentTarget->c_str(), true);
if ((target != 0)
&& ((target->GetType() == cmTarget::EXECUTABLE)
|| (target->GetType() == cmTarget::STATIC_LIBRARY)
|| (target->GetType() == cmTarget::SHARED_LIBRARY)
|| (target->GetType() == cmTarget::MODULE_LIBRARY)))
{
switch (target->GetType())
{
case cmTarget::EXECUTABLE:
fout << "ADD_EXECUTABLE(" << prefix.c_str() << currentTarget->c_str() << " IMPORT )\n";
break;
case cmTarget::STATIC_LIBRARY:
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " STATIC IMPORT )\n";
break;
case cmTarget::SHARED_LIBRARY:
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " SHARED IMPORT )\n";
break;
case cmTarget::MODULE_LIBRARY:
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str() << " MODULE IMPORT )\n";
break;
default: // should never happen
break;
}
fout << "SET_TARGET_PROPERTIES(" << prefix.c_str() << currentTarget->c_str() << " PROPERTIES \n";
fout << " LOCATION " << target->GetLocation(0) << "\n";
for(std::vector<std::string>::const_iterator currentConfig = configurationTypes.begin();
currentConfig != configurationTypes.end();
++currentConfig)
{
if (!currentConfig->empty())
{
const char* loc = target->GetLocation(currentConfig->c_str());
if (loc && *loc)
{
fout << " " << currentConfig->c_str()<< "_LOCATION " << loc << "\n";
}
}
}
fout << " )\n\n";
}
else
{
}
}
return true;
}
bool cmExportCommand::ParseArgs(const std::vector<std::string>& args,
std::string& filename,
std::string& prefix,
std::string& exportName,
std::vector<std::string>& targets,
bool& append) const
{
bool doingFile = false;
bool doingPrefix = false;
bool doingTargets = false;
bool doingName = true;
for(std::vector<std::string>::const_iterator it = args.begin();
it != args.end();
++it)
{
if (*it == "FILE")
{
doingFile = true;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else if (*it == "PREFIX")
{
doingFile = false;
doingPrefix = true;
doingName = false;
doingTargets = false;
}
else if (*it == "TARGETS")
{
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = true;
}
else if (*it == "APPEND")
{
append = true;
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else if (doingFile)
{
filename = *it;
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else if (doingPrefix)
{
prefix = *it;
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else if (doingTargets)
{
targets.push_back(*it);
}
else if (doingName)
{
exportName = *it;
doingFile = false;
doingPrefix = false;
doingName = false;
doingTargets = false;
}
else
{
}
}
return true;
}

85
Source/cmExportCommand.h Normal file
View File

@ -0,0 +1,85 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmExportCommand_h
#define cmExportCommand_h
#include "cmCommand.h"
/** \class cmExportLibraryDependenciesCommand
* \brief Add a test to the lists of tests to run.
*
* cmExportLibraryDependenciesCommand adds a test to the list of tests to run
*
*/
class cmExportCommand : public cmCommand
{
public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
return new cmExportCommand;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args);
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "EXPORT";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return
"Write out the dependency information for all targets of a project.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
" EXPORT(TARGETS tgt1 tgt2 ... [PREFIX <prefix>] FILE <filename> [APPEND])\n"
"Create a file that can be included into a CMake listfile with the "
"INCLUDE command. The file will contain a number of SET commands "
"that will set all the variables needed for library dependency "
"information. This should be the last command in the top level "
"CMakeLists.txt file of the project. If the APPEND option is "
"specified, the SET commands will be appended to the given file "
"instead of replacing it.";
}
cmTypeMacro(cmExportCommand, cmCommand);
private:
bool ParseArgs(const std::vector<std::string>& args, std::string& filename,
std::string& prefix, std::string& exportName,
std::vector<std::string>& targets, bool& append ) const;
};
#endif

View File

@ -0,0 +1,70 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2007 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include <assert.h>
#include "cmExternalMakefileProjectGenerator.h"
std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
const char* globalGenerator,
const char* extraGenerator)
{
std::string fullName;
if (globalGenerator)
{
fullName = globalGenerator;
if (extraGenerator && *extraGenerator)
{
fullName += " - ";
fullName += extraGenerator;
}
}
return fullName;
}
const char* cmExternalMakefileProjectGenerator::GetGlobalGeneratorName(
const char* fullName)
{
// at least one global generator must be supported
assert(!this->SupportedGlobalGenerators.empty());
if (fullName==0)
{
return 0;
}
std::string currentName = fullName;
// if we get only the short name, take the first global generator as default
if (currentName == this->GetName())
{
return this->SupportedGlobalGenerators[0].c_str();
}
// otherwise search for the matching global generator
for (std::vector<std::string>::const_iterator
it = this->SupportedGlobalGenerators.begin();
it != this->SupportedGlobalGenerators.end();
++it)
{
if (this->CreateFullGeneratorName(it->c_str(), this->GetName())
== currentName)
{
return it->c_str();
}
}
return 0;
}

View File

@ -0,0 +1,73 @@
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2007 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmExternalMakefileProjectGenerator_h
#define cmExternalMakefileProjectGenerator_h
#include <vector>
#include <string>
#include "cmDocumentation.h"
class cmGlobalGenerator;
/** \class cmExternalMakefileProjectGenerator
* \brief Base class for generators for "External Makefile based IDE projects".
*
* cmExternalMakefileProjectGenerator is a base class for generators
* for "external makefile based projects", i.e. IDE projects which work
* an already existing makefiles.
* See cmGlobalKdevelopGenerator as an example.
* After the makefiles have been generated by one of the Makefile
* generators, the Generate() method is called and this generator
* can iterate over the local generators and/or projects to produce the
* project files for the IDE.
*/
class cmExternalMakefileProjectGenerator
{
public:
///! Get the name for this generator.
virtual const char* GetName() const = 0;
/** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry,
const char* fullName) const = 0;
///! set the global generator which will generate the makefiles
virtual void SetGlobalGenerator(cmGlobalGenerator* generator)
{this->GlobalGenerator = generator;}
///! Return the list of global generators supported by this extra generator
const std::vector<std::string>& GetSupportedGlobalGenerators() const
{return this->SupportedGlobalGenerators;}
///! Get the name of the global generator for the given full name
const char* GetGlobalGeneratorName(const char* fullName);
/** Create a full name from the given global generator name and the
* extra generator name
*/
static std::string CreateFullGeneratorName(const char* globalGenerator,
const char* extraGenerator);
///! Generate the project files, the Makefiles have already been generated
virtual void Generate() = 0;
protected:
///! Contains the names of the global generators support by this generator.
std::vector<std::string> SupportedGlobalGenerators;
///! the global generator which creates the makefiles
const cmGlobalGenerator* GlobalGenerator;
};
#endif

View File

@ -32,6 +32,10 @@ cmFindLibraryCommand::cmFindLibraryCommand()
"SEARCH_XXX_DESC", "library"); "SEARCH_XXX_DESC", "library");
cmSystemTools::ReplaceString(this->GenericDocumentation, cmSystemTools::ReplaceString(this->GenericDocumentation,
"SEARCH_XXX", "library"); "SEARCH_XXX", "library");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_LIBRARY");
this->GenericDocumentation += this->GenericDocumentation +=
"\n" "\n"
"If the library found is a framework, then VAR will be set to " "If the library found is a framework, then VAR will be set to "

View File

@ -36,6 +36,10 @@ cmFindPathCommand::cmFindPathCommand()
"directory containing the named file"); "directory containing the named file");
cmSystemTools::ReplaceString(this->GenericDocumentation, cmSystemTools::ReplaceString(this->GenericDocumentation,
"SEARCH_XXX", "file in a directory"); "SEARCH_XXX", "file in a directory");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
this->ExtraDocAdded = false; this->ExtraDocAdded = false;
} }

View File

@ -37,6 +37,9 @@ cmFindProgramCommand::cmFindProgramCommand()
"SEARCH_XXX_DESC", "program"); "SEARCH_XXX_DESC", "program");
cmSystemTools::ReplaceString(this->GenericDocumentation, cmSystemTools::ReplaceString(this->GenericDocumentation,
"SEARCH_XXX", "program"); "SEARCH_XXX", "program");
cmSystemTools::ReplaceString(this->GenericDocumentation,
"CMAKE_FIND_ROOT_PATH_MODE_XXX",
"CMAKE_FIND_ROOT_PATH_MODE_PROGRAM");
} }
// cmFindProgramCommand // cmFindProgramCommand

View File

@ -16,6 +16,7 @@
=========================================================================*/ =========================================================================*/
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h" #include "cmLocalGenerator.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmake.h" #include "cmake.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmVersion.h" #include "cmVersion.h"
@ -47,6 +48,8 @@ cmGlobalGenerator::cmGlobalGenerator()
// how long to let try compiles run // how long to let try compiles run
this->TryCompileTimeout = 0; this->TryCompileTimeout = 0;
this->ExtraGenerator = 0;
} }
cmGlobalGenerator::~cmGlobalGenerator() cmGlobalGenerator::~cmGlobalGenerator()
@ -58,6 +61,11 @@ cmGlobalGenerator::~cmGlobalGenerator()
delete this->LocalGenerators[i]; delete this->LocalGenerators[i];
} }
this->LocalGenerators.clear(); this->LocalGenerators.clear();
if (this->ExtraGenerator)
{
delete this->ExtraGenerator;
}
} }
// Find the make program for the generator, required for try compiles // Find the make program for the generator, required for try compiles
@ -791,6 +799,12 @@ void cmGlobalGenerator::Generate()
this->CMakeInstance->UpdateProgress("Generating", this->CMakeInstance->UpdateProgress("Generating",
(i+1.0f)/this->LocalGenerators.size()); (i+1.0f)/this->LocalGenerators.size());
} }
if (this->ExtraGenerator != 0)
{
this->ExtraGenerator->Generate();
}
this->CMakeInstance->UpdateProgress("Generating done", -1); this->CMakeInstance->UpdateProgress("Generating done", -1);
} }
@ -1617,3 +1631,14 @@ void cmGlobalGenerator::AddTarget(cmTargets::value_type &v)
this->TotalTargets[v.first] = &v.second; this->TotalTargets[v.first] = &v.second;
} }
} }
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
cmExternalMakefileProjectGenerator *extraGenerator)
{
this->ExtraGenerator = extraGenerator;
if (this->ExtraGenerator!=0)
{
this->ExtraGenerator->SetGlobalGenerator(this);
}
}

View File

@ -19,6 +19,7 @@
#define cmGlobalGenerator_h #define cmGlobalGenerator_h
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmTarget.h" // For cmTargets #include "cmTarget.h" // For cmTargets
@ -123,6 +124,13 @@ public:
void AddLocalGenerator(cmLocalGenerator *lg); void AddLocalGenerator(cmLocalGenerator *lg);
///! Set an generator for an "external makefile based project"
void SetExternalMakefileProjectGenerator(
cmExternalMakefileProjectGenerator *extraGenerator);
const char* GetExtraGeneratorName() const
{return this->ExtraGenerator!=0 ? this->ExtraGenerator->GetName():0;}
void AddInstallComponent(const char* component); void AddInstallComponent(const char* component);
void EnableInstallTarget(); void EnableInstallTarget();
@ -130,6 +138,8 @@ public:
bool GetForceUnixPaths() {return this->ForceUnixPaths;} bool GetForceUnixPaths() {return this->ForceUnixPaths;}
bool GetToolSupportsColor() { return this->ToolSupportsColor; } bool GetToolSupportsColor() { return this->ToolSupportsColor; }
bool SetToolSupportsColor(bool enable) { this->ToolSupportsColor = enable; }
///! return the language for the given extension ///! return the language for the given extension
const char* GetLanguageFromExtension(const char* ext); const char* GetLanguageFromExtension(const char* ext);
///! is an extension to be ignored ///! is an extension to be ignored
@ -196,6 +206,7 @@ public:
// what targets does the specified target depend on // what targets does the specified target depend on
std::vector<cmTarget *>& GetTargetDepends(cmTarget& target); std::vector<cmTarget *>& GetTargetDepends(cmTarget& target);
const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap() const {return this->ProjectMap;}
protected: protected:
// Fill the ProjectMap, this must be called after LocalGenerators // Fill the ProjectMap, this must be called after LocalGenerators
// has been populated. // has been populated.
@ -242,6 +253,8 @@ private:
std::map<cmStdString,cmTarget *> ImportedTotalTargets; std::map<cmStdString,cmTarget *> ImportedTotalTargets;
std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies; std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies;
cmExternalMakefileProjectGenerator* ExtraGenerator;
}; };
#endif #endif

View File

@ -17,6 +17,7 @@
=========================================================================*/ =========================================================================*/
#include "cmGlobalKdevelopGenerator.h" #include "cmGlobalKdevelopGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmake.h" #include "cmake.h"
@ -25,18 +26,9 @@
#include <cmsys/SystemTools.hxx> #include <cmsys/SystemTools.hxx>
cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
{
// This type of makefile always requires unix style paths
this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
this->ToolSupportsColor = false;
this->SetForceVerboseMakefiles(true);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmGlobalKdevelopGenerator void cmGlobalKdevelopGenerator
::GetDocumentation(cmDocumentationEntry& entry) const ::GetDocumentation(cmDocumentationEntry& entry, const char*) const
{ {
entry.name = this->GetName(); entry.name = this->GetName();
entry.brief = "Generates KDevelop 3 project files."; entry.brief = "Generates KDevelop 3 project files.";
@ -52,13 +44,31 @@ void cmGlobalKdevelopGenerator
"default make target. A \"make install\" target is also provided."; "default make target. A \"make install\" target is also provided.";
} }
cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
:cmExternalMakefileProjectGenerator()
{
this->SupportedGlobalGenerators.push_back("Unix Makefiles");
}
void cmGlobalKdevelopGenerator::SetGlobalGenerator(
cmGlobalGenerator* generator)
{
cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator);
cmGlobalUnixMakefileGenerator3* mf = (cmGlobalUnixMakefileGenerator3*)
generator;
mf->SetToolSupportsColor(false);
mf->SetForceVerboseMakefiles(true);
}
void cmGlobalKdevelopGenerator::Generate() void cmGlobalKdevelopGenerator::Generate()
{ {
this->cmGlobalUnixMakefileGenerator3::Generate();
// for each sub project in the project create // for each sub project in the project create
// a kdevelop project // a kdevelop project
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it; for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it) it = this->GlobalGenerator->GetProjectMap().begin();
it!= this->GlobalGenerator->GetProjectMap().end();
++it)
{ {
cmMakefile* mf = it->second[0]->GetMakefile(); cmMakefile* mf = it->second[0]->GetMakefile();
std::string outputDir=mf->GetStartOutputDirectory(); std::string outputDir=mf->GetStartOutputDirectory();
@ -66,10 +76,9 @@ void cmGlobalKdevelopGenerator::Generate()
std::string projectName=mf->GetProjectName(); std::string projectName=mf->GetProjectName();
std::string cmakeFilePattern("CMakeLists.txt;*.cmake;"); std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
std::string fileToOpen; std::string fileToOpen;
std::vector<cmLocalGenerator*>& lgs= it->second; const std::vector<cmLocalGenerator*>& lgs= it->second;
// create the project.kdevelop.filelist file // create the project.kdevelop.filelist file
if(!this->CreateFilelistFile(it->second[0], lgs, if(!this->CreateFilelistFile(lgs, outputDir, projectDir,
outputDir, projectDir,
projectName, cmakeFilePattern, fileToOpen)) projectName, cmakeFilePattern, fileToOpen))
{ {
cmSystemTools::Error("Can not create filelist file"); cmSystemTools::Error("Can not create filelist file");
@ -104,8 +113,7 @@ void cmGlobalKdevelopGenerator::Generate()
} }
bool cmGlobalKdevelopGenerator bool cmGlobalKdevelopGenerator
::CreateFilelistFile(cmLocalGenerator* , ::CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
std::vector<cmLocalGenerator*>& lgs,
const std::string& outputDir, const std::string& outputDir,
const std::string& projectDirIn, const std::string& projectDirIn,
const std::string& projectname, const std::string& projectname,

View File

@ -18,7 +18,9 @@
#ifndef cmGlobalKdevelopGenerator_h #ifndef cmGlobalKdevelopGenerator_h
#define cmGlobalKdevelopGenerator_h #define cmGlobalKdevelopGenerator_h
#include "cmGlobalUnixMakefileGenerator3.h" #include "cmExternalMakefileProjectGenerator.h"
class cmLocalGenerator;
/** \class cmGlobalKdevelopGenerator /** \class cmGlobalKdevelopGenerator
* \brief Write Unix Makefiles accompanied by KDevelop3 project files. * \brief Write Unix Makefiles accompanied by KDevelop3 project files.
@ -31,32 +33,27 @@
* file, which lists the source files relative to the kdevelop project * file, which lists the source files relative to the kdevelop project
* directory. The kdevelop project directory is the base source directory. * directory. The kdevelop project directory is the base source directory.
*/ */
class cmGlobalKdevelopGenerator : public cmGlobalUnixMakefileGenerator3 class cmGlobalKdevelopGenerator : public cmExternalMakefileProjectGenerator
{ {
public: public:
cmGlobalKdevelopGenerator(); cmGlobalKdevelopGenerator();
static cmGlobalGenerator* New() { return new cmGlobalKdevelopGenerator; } virtual void SetGlobalGenerator(cmGlobalGenerator* generator);
///! Get the name for the generator.
virtual const char* GetName() const {
return cmGlobalKdevelopGenerator::GetActualName();}
static const char* GetActualName() {return "KDevelop3";}
virtual const char* GetName() const
{ return cmGlobalKdevelopGenerator::GetActualName();}
static const char* GetActualName() { return "KDevelop3";}
static cmExternalMakefileProjectGenerator* New()
{ return new cmGlobalKdevelopGenerator; }
/** Get the documentation entry for this generator. */ /** Get the documentation entry for this generator. */
virtual void GetDocumentation(cmDocumentationEntry& entry) const; virtual void GetDocumentation(cmDocumentationEntry& entry,
const char* fullName) const;
/**
* Generate the all required files for building this project/tree. This
* basically creates a series of LocalGenerators for each directory and
* requests that they Generate.
*/
virtual void Generate(); virtual void Generate();
private:
/*** Create the foo.kdevelop.filelist file, return false if it doesn't /*** Create the foo.kdevelop.filelist file, return false if it doesn't
succeed. If the file already exists the contents will be merged. succeed. If the file already exists the contents will be merged.
*/ */
bool CreateFilelistFile(cmLocalGenerator* lg, bool CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
std::vector<cmLocalGenerator*>& lgs,
const std::string& outputDir, const std::string& outputDir,
const std::string& projectDirIn, const std::string& projectDirIn,
const std::string& projectname, const std::string& projectname,
@ -95,6 +92,7 @@ public:
const std::string& fileToOpen, const std::string& fileToOpen,
const std::string& sessionFilename); const std::string& sessionFilename);
}; };
#endif #endif

View File

@ -169,6 +169,7 @@ cmake::cmake()
#endif #endif
this->AddDefaultGenerators(); this->AddDefaultGenerators();
this->AddDefaultExtraGenerators();
this->AddDefaultCommands(); this->AddDefaultCommands();
// Make sure we can capture the build tool output. // Make sure we can capture the build tool output.
@ -1405,6 +1406,40 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
return 1; return 1;
} }
void cmake::AddExtraGenerator(const char* name,
CreateExtraGeneratorFunctionType newFunction)
{
this->ExtraGenerators[name] = newFunction;
cmExternalMakefileProjectGenerator* extraGenerator = newFunction();
const std::vector<std::string>& supportedGlobalGenerators =
extraGenerator->GetSupportedGlobalGenerators();
for(std::vector<std::string>::const_iterator
it = supportedGlobalGenerators.begin();
it != supportedGlobalGenerators.end();
++it )
{
std::string fullName = cmExternalMakefileProjectGenerator::
CreateFullGeneratorName(it->c_str(), name);
this->ExtraGenerators[fullName.c_str()] = newFunction;
}
delete extraGenerator;
}
void cmake::AddDefaultExtraGenerators()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
# if !defined(CMAKE_BOOT_MINGW)
// e.g. codeblocks, kdevelop4 ?
# endif
#endif
// e.g. eclipse ?
#ifdef CMAKE_USE_KDEVELOP
this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(), &cmGlobalKdevelopGenerator::New);
#endif
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmake::GetRegisteredGenerators(std::vector<std::string>& names) void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
{ {
@ -1417,17 +1452,30 @@ void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name) cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
{ {
RegisteredGeneratorsMap::const_iterator i = this->Generators.find(name); cmGlobalGenerator* generator = 0;
if(i != this->Generators.end()) cmExternalMakefileProjectGenerator* extraGenerator = 0;
RegisteredGeneratorsMap::const_iterator genIt = this->Generators.find(name);
if(genIt == this->Generators.end())
{ {
cmGlobalGenerator* generator = (i->second)(); RegisteredExtraGeneratorsMap::const_iterator extraGenIt =
generator->SetCMakeInstance(this); this->ExtraGenerators.find(name);
return generator; if (extraGenIt == this->ExtraGenerators.end())
} {
else return 0;
{ }
return 0; extraGenerator = (extraGenIt->second)();
} genIt=this->Generators.find(extraGenerator->GetGlobalGeneratorName(name));
if(genIt == this->Generators.end())
{
delete extraGenerator;
return 0;
}
}
generator = (genIt->second)();
generator->SetCMakeInstance(this);
generator->SetExternalMakefileProjectGenerator(extraGenerator);
return generator;
} }
void cmake::SetHomeDirectory(const char* dir) void cmake::SetHomeDirectory(const char* dir)
@ -1599,9 +1647,13 @@ int cmake::Configure()
{ {
const char* genName = const char* genName =
this->CacheManager->GetCacheValue("CMAKE_GENERATOR"); this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
const char* extraGenName =
this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR");
if(genName) if(genName)
{ {
this->GlobalGenerator = this->CreateGlobalGenerator(genName); std::string fullName = cmExternalMakefileProjectGenerator::
CreateFullGeneratorName(genName, extraGenName);
this->GlobalGenerator = this->CreateGlobalGenerator(fullName.c_str());
} }
if(this->GlobalGenerator) if(this->GlobalGenerator)
{ {
@ -1688,6 +1740,10 @@ int cmake::Configure()
this->GlobalGenerator->GetName(), this->GlobalGenerator->GetName(),
"Name of generator.", "Name of generator.",
cmCacheManager::INTERNAL); cmCacheManager::INTERNAL);
this->CacheManager->AddCacheEntry("CMAKE_EXTRA_GENERATOR",
this->GlobalGenerator->GetExtraGeneratorName(),
"Name of external makefile project generator.",
cmCacheManager::INTERNAL);
} }
// reset any system configuration information, except for when we are // reset any system configuration information, except for when we are
@ -1750,6 +1806,7 @@ int cmake::Configure()
// We must have a bad generator selection. Wipe the cache entry so the // We must have a bad generator selection. Wipe the cache entry so the
// user can select another. // user can select another.
this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR"); this->CacheManager->RemoveCacheEntry("CMAKE_GENERATOR");
this->CacheManager->RemoveCacheEntry("CMAKE_EMP_GENERATOR");
} }
// only save the cache if there were no fatal errors // only save the cache if there were no fatal errors
if ( !this->ScriptMode ) if ( !this->ScriptMode )
@ -2001,10 +2058,6 @@ void cmake::AddDefaultGenerators()
this->Generators[cmGlobalXCodeGenerator::GetActualName()] = this->Generators[cmGlobalXCodeGenerator::GetActualName()] =
&cmGlobalXCodeGenerator::New; &cmGlobalXCodeGenerator::New;
#endif #endif
#ifdef CMAKE_USE_KDEVELOP
this->Generators[cmGlobalKdevelopGenerator::GetActualName()] =
&cmGlobalKdevelopGenerator::New;
#endif
} }
int cmake::LoadCache() int cmake::LoadCache()
@ -2121,6 +2174,16 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
delete generator; delete generator;
v.push_back(e); v.push_back(e);
} }
for(RegisteredExtraGeneratorsMap::const_iterator
i = this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i)
{
cmDocumentationEntry e;
cmExternalMakefileProjectGenerator* generator = (i->second)();
generator->GetDocumentation(e, i->first.c_str());
e.name = i->first.c_str();
delete generator;
v.push_back(e);
}
cmDocumentationEntry empty = {0,0,0}; cmDocumentationEntry empty = {0,0,0};
v.push_back(empty); v.push_back(empty);
} }

View File

@ -51,6 +51,7 @@ class cmMakefile;
class cmCommand; class cmCommand;
class cmVariableWatch; class cmVariableWatch;
class cmFileTimeComparison; class cmFileTimeComparison;
class cmExternalMakefileProjectGenerator;
class cmake class cmake
{ {
@ -306,13 +307,21 @@ protected:
cmPropertyDefinitionMap TestProperties; cmPropertyDefinitionMap TestProperties;
cmPropertyDefinitionMap GlobalProperties; cmPropertyDefinitionMap GlobalProperties;
typedef
cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)();
typedef std::map<cmStdString,
CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap;
typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)(); typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)();
typedef std::map<cmStdString, typedef std::map<cmStdString,
CreateGeneratorFunctionType> RegisteredGeneratorsMap; CreateGeneratorFunctionType> RegisteredGeneratorsMap;
RegisteredCommandsMap Commands; RegisteredCommandsMap Commands;
RegisteredGeneratorsMap Generators; RegisteredGeneratorsMap Generators;
RegisteredExtraGeneratorsMap ExtraGenerators;
void AddDefaultCommands(); void AddDefaultCommands();
void AddDefaultGenerators(); void AddDefaultGenerators();
void AddDefaultExtraGenerators();
void AddExtraGenerator(const char* name, CreateExtraGeneratorFunctionType newFunction);
cmGlobalGenerator *GlobalGenerator; cmGlobalGenerator *GlobalGenerator;
cmCacheManager *CacheManager; cmCacheManager *CacheManager;