ENH: move most of the to global generator

This commit is contained in:
Bill Hoffman 2005-02-09 23:22:06 -05:00
parent b7b501bbe8
commit c840bbcaaf
4 changed files with 419 additions and 430 deletions

View File

@ -20,6 +20,8 @@
#include "cmLocalKdevelopGenerator.h" #include "cmLocalKdevelopGenerator.h"
#include "cmMakefile.h" #include "cmMakefile.h"
#include "cmake.h" #include "cmake.h"
#include "cmSourceFile.h"
#include "cmGeneratedFileStream.h"
cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator() cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
{ {
@ -50,3 +52,364 @@ void cmGlobalKdevelopGenerator::GetDocumentation(cmDocumentationEntry& entry) co
"standard UNIX-style make program can build the project through the " "standard UNIX-style make program can build the project through the "
"default make target. A \"make install\" target is also provided."; "default make target. A \"make install\" target is also provided.";
} }
void cmGlobalKdevelopGenerator::Generate()
{
this->cmGlobalGenerator::Generate();
// for each sub project in the project create
// a kdevelop project
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
for(it = m_ProjectMap.begin(); it!= m_ProjectMap.end(); ++it)
{
cmMakefile* mf = it->second[0]->GetMakefile();
std::string outputDir=mf->GetStartOutputDirectory();
std::string projectDir=mf->GetHomeDirectory();
std::string projectName=mf->GetProjectName();
std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
// create the project.kdevelop.filelist file
if(!this->CreateFilelistFile(it->second[0], it->second,
outputDir, projectDir,
projectName, cmakeFilePattern))
{
cmSystemTools::Error("Can not create filelist file");
return;
}
//try to find the name of an executable so we have something to
//run from kdevelop for now just pick the first executable found
std::string executable;
cmTargets& targets=mf->GetTargets();
for (cmTargets::const_iterator ti = targets.begin();
ti != targets.end(); ti++)
{
if (ti->second.GetType()==cmTarget::EXECUTABLE)
{
executable=ti->first;
break;
}
}
// now create a project file
this->CreateProjectFile(outputDir, projectDir, projectName,
executable, cmakeFilePattern);
}
}
bool cmGlobalKdevelopGenerator
::CreateFilelistFile(cmLocalGenerator* lg,
std::vector<cmLocalGenerator*>& lgs,
const std::string& outputDir,
const std::string& projectDirIn,
const std::string& projectname,
std::string& cmakeFilePattern)
{
cmMakefile* mf =lg->GetMakefile();
std::string projectDir = projectDirIn + "/";
std::string filename = outputDir+"/" + std::string(mf->GetProjectName())
+".kdevelop.filelist";
std::set<cmStdString> files;
std::string tmp;
for (std::vector<cmLocalGenerator*>::const_iterator it=lgs.begin();
it!=lgs.end(); it++)
{
cmMakefile* makefile=(*it)->GetMakefile();
const std::vector<std::string>& listFiles=makefile->GetListFiles();
for (std::vector<std::string>::const_iterator lt=listFiles.begin();
lt!=listFiles.end(); lt++)
{
tmp=*lt;
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
// make sure the file is part of this source tree
if (tmp[0]!='/')
{
files.insert(tmp);
tmp=cmSystemTools::GetFilenameName(tmp);
//add all files which dont match the default
// */CMakeLists.txt;*cmake; to the file pattern
if ((tmp!="CMakeLists.txt")
&& (strstr(tmp.c_str(), ".cmake")==0))
{
cmakeFilePattern+=tmp+";";
}
}
}
//get all sources
cmTargets& targets=makefile->GetTargets();
for (cmTargets::const_iterator ti = targets.begin();
ti != targets.end(); ti++)
{
const std::vector<cmSourceFile*>& sources=ti->second.GetSourceFiles();
for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
si!=sources.end(); si++)
{
tmp=(*si)->GetFullPath();
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
if (tmp[0]!='/')
{
files.insert(tmp);
}
}
for (std::vector<std::string>::const_iterator lt=listFiles.begin();
lt!=listFiles.end(); lt++)
{
tmp=*lt;
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
if (tmp[0]!='/')
{
files.insert(tmp.c_str());
}
}
}
}
//check if the output file already exists and read it
//insert all files which exist into the set of files
std::ifstream oldFilelist(filename.c_str());
if (oldFilelist)
{
while (cmSystemTools::GetLineFromStream(oldFilelist, tmp))
{
if (tmp[0]=='/')
{
continue;
}
std::string completePath=projectDir+tmp;
if (cmSystemTools::FileExists(completePath.c_str()))
{
files.insert(tmp);
}
}
oldFilelist.close();
}
//now write the new filename
cmGeneratedFileStream fout(filename.c_str());
if(!fout)
{
return false;
}
for (std::set<cmStdString>::const_iterator it=files.begin();
it!=files.end(); it++)
{
// get the full path to the file
tmp=cmSystemTools::CollapseFullPath(it->c_str(), projectDir.c_str());
// make it relative to the project dir
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
// only put relative paths
if (tmp.size() && tmp[0] != '/')
{
fout << tmp.c_str() <<"\n";
}
}
return true;
}
/* create the project file, if it already exists, merge it with the
existing one, otherwise create a new one */
void
cmGlobalKdevelopGenerator::CreateProjectFile(const std::string& outputDir,
const std::string& projectDir,
const std::string& projectname,
const std::string& executable,
const std::string& cmakeFilePattern)
{
std::string filename=outputDir+"/";
filename+=projectname+".kdevelop";
if (cmSystemTools::FileExists(filename.c_str()))
{
this->MergeProjectFiles(outputDir, projectDir, filename,
executable, cmakeFilePattern);
}
else
{
this->CreateNewProjectFile(outputDir, projectDir, filename,
executable, cmakeFilePattern);
}
}
void
cmGlobalKdevelopGenerator::MergeProjectFiles(const std::string& outputDir,
const std::string& projectDir,
const std::string& filename,
const std::string& executable,
const std::string& cmakeFilePattern)
{
std::ifstream oldProjectFile(filename.c_str());
if (!oldProjectFile)
{
this->CreateNewProjectFile(outputDir, projectDir, filename, executable, cmakeFilePattern);
return;
}
/* Read the existing project file (line by line), copy all lines
into the new project file, except the ones which can be reliably
set from contents of the CMakeLists.txt */
std::string tmp;
std::vector<std::string> lines;
while (cmSystemTools::GetLineFromStream(oldProjectFile, tmp))
{
lines.push_back(tmp);
}
oldProjectFile.close();
cmGeneratedFileStream fout(filename.c_str());
if(!fout)
{
return;
}
for (std::vector<std::string>::const_iterator it=lines.begin();
it!=lines.end(); it++)
{
const char* line=(*it).c_str();
// skip these tags as they are always replaced
if ((strstr(line, "<projectdirectory>")!=0)
|| (strstr(line, "<projectmanagement>")!=0)
|| (strstr(line, "<absoluteprojectpath>")!=0)
|| (strstr(line, "<filelistdirectory>")!=0)
|| (strstr(line, "<buildtool>")!=0)
|| (strstr(line, "<builddir>")!=0))
{
continue;
}
// output the line from the file if it is not one of the above tags
fout<<*it<<"\n";
// if this is the <general> tag output the stuff that goes in the general tag
if (strstr(line, "<general>"))
{
fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n";
fout<<" <projectdirectory>"<<projectDir.c_str()<<"</projectdirectory>\n"; //this one is important
fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
}
// inside kdevcustomproject the <filelistdirectory> must be put
if (strstr(line, "<kdevcustomproject>"))
{
fout<<" <filelistdirectory>"<<outputDir.c_str()
<<"</filelistdirectory>\n";
}
// buildtool and builddir go inside <build>
if (strstr(line, "<build>"))
{
fout<<" <buildtool>make</buildtool>\n";
fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n";
}
}
}
void
cmGlobalKdevelopGenerator::CreateNewProjectFile(const std::string& outputDir,
const std::string& projectDir,
const std::string& filename,
const std::string& executable,
const std::string& cmakeFilePattern)
{
cmGeneratedFileStream fout(filename.c_str());
if(!fout)
{
return;
}
fout<<"<?xml version = '1.0'?>\n";
fout<<"<kdevelop>\n";
fout<<" <general>\n";
fout<<" <author></author>\n";
fout<<" <email></email>\n";
fout<<" <version>$VERSION$</version>\n";
fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n";
fout<<" <primarylanguage>C++</primarylanguage>\n";
fout<<" <ignoreparts/>\n";
fout<<" <projectdirectory>"<<projectDir.c_str()<<"</projectdirectory>\n"; //this one is important
fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
fout<<" <secondaryLanguages>\n";
fout<<" <language>C</language>\n";
fout<<" </secondaryLanguages>\n";
fout<<" </general>\n";
fout<<" <kdevcustomproject>\n";
fout<<" <filelistdirectory>"<<outputDir.c_str()<<"</filelistdirectory>\n";
fout<<" <run>\n";
fout<<" <mainprogram>"<<outputDir.c_str()<<"/"<<executable.c_str()<<"</mainprogram>\n";
fout<<" <directoryradio>custom</directoryradio>\n";
fout<<" <customdirectory>/</customdirectory>\n";
fout<<" <programargs></programargs>\n";
fout<<" <terminal>false</terminal>\n";
fout<<" <autocompile>true</autocompile>\n";
fout<<" <envvars/>\n";
fout<<" </run>\n";
fout<<" <build>\n";
fout<<" <buildtool>make</buildtool>\n"; //this one is important
fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n"; //and this one
fout<<" </build>\n";
fout<<" <make>\n";
fout<<" <abortonerror>false</abortonerror>\n";
fout<<" <numberofjobs>1</numberofjobs>\n";
fout<<" <dontact>false</dontact>\n";
fout<<" <makebin></makebin>\n";
fout<<" <selectedenvironment>default</selectedenvironment>\n";
fout<<" <environments>\n";
fout<<" <default/>\n";
fout<<" </environments>\n";
fout<<" </make>\n";
fout<<" </kdevcustomproject>\n";
fout<<" <kdevfilecreate>\n";
fout<<" <filetypes/>\n";
fout<<" <useglobaltypes>\n";
fout<<" <type ext=\"ui\" />\n";
fout<<" <type ext=\"cpp\" />\n";
fout<<" <type ext=\"h\" />\n";
fout<<" </useglobaltypes>\n";
fout<<" </kdevfilecreate>\n";
fout<<" <kdevdoctreeview>\n";
fout<<" <projectdoc>\n";
fout<<" <userdocDir>html/</userdocDir>\n";
fout<<" <apidocDir>html/</apidocDir>\n";
fout<<" </projectdoc>\n";
fout<<" <ignoreqt_xml/>\n";
fout<<" <ignoredoxygen/>\n";
fout<<" <ignorekdocs/>\n";
fout<<" <ignoretocs/>\n";
fout<<" <ignoredevhelp/>\n";
fout<<" </kdevdoctreeview>\n";
fout<<" <cppsupportpart>\n";
fout<<" <filetemplates>\n";
fout<<" <interfacesuffix>.h</interfacesuffix>\n";
fout<<" <implementationsuffix>.cpp</implementationsuffix>\n";
fout<<" </filetemplates>\n";
fout<<" </cppsupportpart>\n";
fout<<" <kdevcppsupport>\n";
fout<<" <codecompletion>\n";
fout<<" <includeGlobalFunctions>true</includeGlobalFunctions>\n";
fout<<" <includeTypes>true</includeTypes>\n";
fout<<" <includeEnums>true</includeEnums>\n";
fout<<" <includeTypedefs>false</includeTypedefs>\n";
fout<<" <automaticCodeCompletion>true</automaticCodeCompletion>\n";
fout<<" <automaticArgumentsHint>true</automaticArgumentsHint>\n";
fout<<" <automaticHeaderCompletion>true</automaticHeaderCompletion>\n";
fout<<" <codeCompletionDelay>250</codeCompletionDelay>\n";
fout<<" <argumentsHintDelay>400</argumentsHintDelay>\n";
fout<<" <headerCompletionDelay>250</headerCompletionDelay>\n";
fout<<" </codecompletion>\n";
fout<<" <references/>\n";
fout<<" </kdevcppsupport>\n";
fout<<" <kdevfileview>\n";
fout<<" <groups>\n";
fout<<" <group pattern=\""<<cmakeFilePattern.c_str()<<"\" name=\"CMake\" />\n";
fout<<" <group pattern=\"*.h;*.hxx\" name=\"Header\" />\n";
fout<<" <group pattern=\"*.cpp;*.c;*.C;*.cxx\" name=\"Sources\" />\n";
fout<<" <group pattern=\"*.ui\" name=\"Qt Designer files\" />\n";
fout<<" <hidenonprojectfiles>true</hidenonprojectfiles>\n";
fout<<" </groups>\n";
fout<<" <tree>\n";
fout<<" <hidepatterns>*.o,*.lo,CVS,*~,cmake*</hidepatterns>\n";
fout<<" <hidenonprojectfiles>true</hidenonprojectfiles>\n";
fout<<" </tree>\n";
fout<<" </kdevfileview>\n";
fout<<"</kdevelop>\n";
}

View File

@ -20,10 +20,16 @@
#include "cmGlobalUnixMakefileGenerator.h" #include "cmGlobalUnixMakefileGenerator.h"
/** \class cmGlobalUnixMakefileGenerator /** \class cmGlobalKdevelopGenerator
* \brief Write a Unix makefiles. * \brief Write Unix Makefiles accompanied by KDevelop3 project files.
* *
* cmGlobalUnixMakefileGenerator manages UNIX build process for a tree * cmGlobalKdevelopGenerator produces a project file for KDevelop 3 (KDevelop > 3.1.1).
* The project is based on the "Custom Makefile based C/C++" project of KDevelop.
* Such a project consists of Unix Makefiles in the build directory together
* with a <your_project>.kdevelop project file, which contains the project settings
* and a <your_project>.kdevelop.filelist file, which lists the source files relative
* to the kdevelop project directory. The kdevelop project directory is the base
* source directory.
*/ */
class cmGlobalKdevelopGenerator : public cmGlobalUnixMakefileGenerator class cmGlobalKdevelopGenerator : public cmGlobalUnixMakefileGenerator
{ {
@ -42,6 +48,50 @@ public:
///! Create a local generator appropriate to this Global Generator ///! Create a local generator appropriate to this Global Generator
virtual cmLocalGenerator *CreateLocalGenerator(); virtual cmLocalGenerator *CreateLocalGenerator();
/**
* 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();
/*** Create the foo.kdevelop.filelist file, return false if it doesn't
succeed. If the file already exists the contents will be merged.
*/
bool CreateFilelistFile(cmLocalGenerator* lg,
std::vector<cmLocalGenerator*>& lgs,
const std::string& outputDir,
const std::string& projectDirIn,
const std::string& projectname,
std::string& cmakeFilePattern);
/** Create the foo.kdevelop file. This one calls MergeProjectFiles()
if it already exists, otherwise createNewProjectFile() The project
files will be created in \a outputDir (in the build tree), the
kdevelop project dir will be set to \a projectDir (in the source
tree). \a cmakeFilePattern consists of a lists of all cmake
listfiles used by this CMakeLists.txt */
void CreateProjectFile(const std::string& outputDir,
const std::string& projectDir,
const std::string& projectname,
const std::string& executable,
const std::string& cmakeFilePattern);
/*** Reads the old foo.kdevelop line by line and only replaces the
"important" lines
*/
void MergeProjectFiles(const std::string& outputDir,
const std::string& projectDir,
const std::string& filename,
const std::string& executable,
const std::string& cmakeFilePattern);
///! Creates a new foo.kdevelop file
void CreateNewProjectFile(const std::string& outputDir,
const std::string& projectDir,
const std::string& filename,
const std::string& executable,
const std::string& cmakeFilePattern);
}; };
#endif #endif

View File

@ -27,41 +27,6 @@
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
// Ideas for moving this stuff into the global generator
// Right now in your local generator you read and write a file to build
// up a list of all files in the project.
// Basically, there does not need to be a local kdevlop generator at all,
// it can just use the unix makefile one. Then in the global generators
// Generate method you do something like this:
// unsigned int i;
// for(i = 0; i < m_LocalGenerators.size(); ++i)
// {
// // Get list of targets and sources from local generator i
// // add them to a file map like you do now in the local generator
// }
// // now write out the Project.filelist file and Project.kdevlop files
// It should most likely do the same thing as the visual studio generators and
// write out all the sub-projects as well. And also honor the exclude from above
// option.
// I guess at the end of the day it should do something like this:
// TopProject.kdevelop
// TopProject.kdevelop.filelist
// SubProject/SubProject.kdevelop
// SubProject/SubProject.kdevelop.filelist
// if SubProject was in a SUBDIR(EXCLUDE_FROM_ALL SubProject)
// then its files should not be in TopProject.filelist.
// If you look at these functions you can see how the visual studio
// cmGlobalVisualStudio7Generator::Generate() // generate the project
// void cmGlobalVisualStudio7Generator::CollectSubprojects() // create a map of project names to local
// // generators
// void cmGlobalVisualStudio7Generator::OutputSLNFile(cmLocalGenerator* root,
// std::vector<cmLocalGenerator*>& generators)
// // output a project for each project and sub project
cmLocalKdevelopGenerator::cmLocalKdevelopGenerator() cmLocalKdevelopGenerator::cmLocalKdevelopGenerator()
:cmLocalUnixMakefileGenerator() :cmLocalUnixMakefileGenerator()
{ {
@ -74,354 +39,6 @@ cmLocalKdevelopGenerator::~cmLocalKdevelopGenerator()
void cmLocalKdevelopGenerator::Generate(bool fromTheTop) void cmLocalKdevelopGenerator::Generate(bool fromTheTop)
{ {
cmLocalUnixMakefileGenerator::Generate(fromTheTop); cmLocalUnixMakefileGenerator::Generate(fromTheTop);
if ( m_GlobalGenerator->GetCMakeInstance()->GetLocal() ) return;
{
return;
}
// Does this local generator contain a PROJECT command
// if so, then generate a kdevelop project for it
if (strcmp(m_Makefile->GetDefinition("PROJECT_BINARY_DIR"), m_Makefile->GetStartOutputDirectory())==0)
{
std::string outputDir=m_Makefile->GetStartOutputDirectory();
std::string projectDir=m_Makefile->GetHomeDirectory();
std::string projectName=m_Makefile->GetProjectName();
std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
if (!this->CreateFilelistFile(outputDir, projectDir, projectName, cmakeFilePattern))
{
return;
}
//try to find the name of an executable so we have something to run from kdevelop
// for now just pick the first executable found
std::string executable;
cmTargets& targets=m_Makefile->GetTargets();
for (cmTargets::const_iterator ti = targets.begin(); ti != targets.end(); ti++)
{
if (ti->second.GetType()==cmTarget::EXECUTABLE)
{
executable=ti->first;
break;
}
}
this->CreateProjectFile(outputDir, projectDir, projectName, executable, cmakeFilePattern);
}
}
/* create the project file, if it already exists, merge it with the existing one,
otherwise create a new one */
void cmLocalKdevelopGenerator::CreateProjectFile(const std::string& outputDir,
const std::string& projectDir,
const std::string& projectname,
const std::string& executable,
const std::string& cmakeFilePattern)
{
std::string filename=outputDir+"/";
filename+=projectname+".kdevelop";
if (cmSystemTools::FileExists(filename.c_str()))
{
this->MergeProjectFiles(outputDir, projectDir, filename, executable, cmakeFilePattern);
}
else
{
this->CreateNewProjectFile(outputDir, projectDir, filename, executable, cmakeFilePattern);
}
}
void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& outputDir,
const std::string& projectDir,
const std::string& filename,
const std::string& executable,
const std::string& cmakeFilePattern)
{
std::ifstream oldProjectFile(filename.c_str());
if (!oldProjectFile)
{
this->CreateNewProjectFile(outputDir, projectDir, filename, executable, cmakeFilePattern);
return;
}
/* Read the existing project file (line by line), copy all lines into the
new project file, except the ones which can be reliably set from contents
of the CMakeLists.txt */
std::string tmp;
std::vector<std::string> lines;
while (cmSystemTools::GetLineFromStream(oldProjectFile, tmp))
{
lines.push_back(tmp);
}
oldProjectFile.close();
cmGeneratedFileStream fout(filename.c_str());
if(!fout)
{
return;
}
for (std::vector<std::string>::const_iterator it=lines.begin();
it!=lines.end(); it++)
{
const char* line=(*it).c_str();
// skip these tags as they are always replaced
if ((strstr(line, "<projectdirectory>")!=0)
|| (strstr(line, "<projectmanagement>")!=0)
|| (strstr(line, "<absoluteprojectpath>")!=0)
|| (strstr(line, "<filelistdirectory>")!=0)
|| (strstr(line, "<buildtool>")!=0)
|| (strstr(line, "<builddir>")!=0))
{
continue;
}
// output the line from the file if it is not one of the above tags
fout<<*it<<"\n";
// if this is the <general> tag output the stuff that goes in the general tag
if (strstr(line, "<general>"))
{
fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n";
fout<<" <projectdirectory>"<<projectDir.c_str()<<"</projectdirectory>\n"; //this one is important
fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
}
// inside kdevcustomproject the <filelistdirectory> must be put
if (strstr(line, "<kdevcustomproject>"))
{
fout<<" <filelistdirectory>"<<outputDir.c_str()<<"</filelistdirectory>\n";
}
// buildtool and builddir go inside <build>
if (strstr(line, "<build>"))
{
fout<<" <buildtool>make</buildtool>\n"; //this one is important
fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n"; //and this one
}
}
}
void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& outputDir,
const std::string& projectDir,
const std::string& filename,
const std::string& executable,
const std::string& cmakeFilePattern)
{
cmGeneratedFileStream fout(filename.c_str());
if(!fout)
{
return;
}
fout<<"<?xml version = '1.0'?>\n";
fout<<"<kdevelop>\n";
fout<<" <general>\n";
fout<<" <author></author>\n";
fout<<" <email></email>\n";
fout<<" <version>$VERSION$</version>\n";
fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n";
fout<<" <primarylanguage>C++</primarylanguage>\n";
fout<<" <ignoreparts/>\n";
fout<<" <projectdirectory>"<<projectDir.c_str()<<"</projectdirectory>\n"; //this one is important
fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
fout<<" <secondaryLanguages>\n";
fout<<" <language>C</language>\n";
fout<<" </secondaryLanguages>\n";
fout<<" </general>\n";
fout<<" <kdevcustomproject>\n";
fout<<" <filelistdirectory>"<<outputDir.c_str()<<"</filelistdirectory>\n";
fout<<" <run>\n";
fout<<" <mainprogram>"<<outputDir.c_str()<<"/"<<executable.c_str()<<"</mainprogram>\n";
fout<<" <directoryradio>custom</directoryradio>\n";
fout<<" <customdirectory>/</customdirectory>\n";
fout<<" <programargs></programargs>\n";
fout<<" <terminal>false</terminal>\n";
fout<<" <autocompile>true</autocompile>\n";
fout<<" <envvars/>\n";
fout<<" </run>\n";
fout<<" <build>\n";
fout<<" <buildtool>make</buildtool>\n"; //this one is important
fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n"; //and this one
fout<<" </build>\n";
fout<<" <make>\n";
fout<<" <abortonerror>false</abortonerror>\n";
fout<<" <numberofjobs>1</numberofjobs>\n";
fout<<" <dontact>false</dontact>\n";
fout<<" <makebin></makebin>\n";
fout<<" <selectedenvironment>default</selectedenvironment>\n";
fout<<" <environments>\n";
fout<<" <default/>\n";
fout<<" </environments>\n";
fout<<" </make>\n";
fout<<" </kdevcustomproject>\n";
fout<<" <kdevfilecreate>\n";
fout<<" <filetypes/>\n";
fout<<" <useglobaltypes>\n";
fout<<" <type ext=\"ui\" />\n";
fout<<" <type ext=\"cpp\" />\n";
fout<<" <type ext=\"h\" />\n";
fout<<" </useglobaltypes>\n";
fout<<" </kdevfilecreate>\n";
fout<<" <kdevdoctreeview>\n";
fout<<" <projectdoc>\n";
fout<<" <userdocDir>html/</userdocDir>\n";
fout<<" <apidocDir>html/</apidocDir>\n";
fout<<" </projectdoc>\n";
fout<<" <ignoreqt_xml/>\n";
fout<<" <ignoredoxygen/>\n";
fout<<" <ignorekdocs/>\n";
fout<<" <ignoretocs/>\n";
fout<<" <ignoredevhelp/>\n";
fout<<" </kdevdoctreeview>\n";
fout<<" <cppsupportpart>\n";
fout<<" <filetemplates>\n";
fout<<" <interfacesuffix>.h</interfacesuffix>\n";
fout<<" <implementationsuffix>.cpp</implementationsuffix>\n";
fout<<" </filetemplates>\n";
fout<<" </cppsupportpart>\n";
fout<<" <kdevcppsupport>\n";
fout<<" <codecompletion>\n";
fout<<" <includeGlobalFunctions>true</includeGlobalFunctions>\n";
fout<<" <includeTypes>true</includeTypes>\n";
fout<<" <includeEnums>true</includeEnums>\n";
fout<<" <includeTypedefs>false</includeTypedefs>\n";
fout<<" <automaticCodeCompletion>true</automaticCodeCompletion>\n";
fout<<" <automaticArgumentsHint>true</automaticArgumentsHint>\n";
fout<<" <automaticHeaderCompletion>true</automaticHeaderCompletion>\n";
fout<<" <codeCompletionDelay>250</codeCompletionDelay>\n";
fout<<" <argumentsHintDelay>400</argumentsHintDelay>\n";
fout<<" <headerCompletionDelay>250</headerCompletionDelay>\n";
fout<<" </codecompletion>\n";
fout<<" <references/>\n";
fout<<" </kdevcppsupport>\n";
fout<<" <kdevfileview>\n";
fout<<" <groups>\n";
fout<<" <group pattern=\""<<cmakeFilePattern.c_str()<<"\" name=\"CMake\" />\n";
fout<<" <group pattern=\"*.h;*.hxx\" name=\"Header\" />\n";
fout<<" <group pattern=\"*.cpp;*.c;*.C;*.cxx\" name=\"Sources\" />\n";
fout<<" <group pattern=\"*.ui\" name=\"Qt Designer files\" />\n";
fout<<" <hidenonprojectfiles>true</hidenonprojectfiles>\n";
fout<<" </groups>\n";
fout<<" <tree>\n";
fout<<" <hidepatterns>*.o,*.lo,CVS,*~,cmake*</hidepatterns>\n";
fout<<" <hidenonprojectfiles>true</hidenonprojectfiles>\n";
fout<<" </tree>\n";
fout<<" </kdevfileview>\n";
fout<<"</kdevelop>\n";
}
bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& outputDir, const std::string& _projectDir,
const std::string& projectname,
std::string& cmakeFilePattern)
{
std::string projectDir=_projectDir+"/";
std::string filename=outputDir+"/"+projectname+".kdevelop.filelist";
std::set<cmStdString> files;
std::string tmp;
// loop over all local generators in the entire project
// This should be moved into the global generator
// FIXME
std::vector<cmLocalGenerator *> lgs;
m_GlobalGenerator->GetLocalGenerators(lgs);
for (std::vector<cmLocalGenerator*>::const_iterator it=lgs.begin(); it!=lgs.end(); it++)
{
cmMakefile* makefile=(*it)->GetMakefile();
// if the makefile GetStartOutputDirectory is not a substring of the outputDir
// then skip it
if (strstr(makefile->GetStartOutputDirectory(), outputDir.c_str())==0)
{
continue;
}
// This means the makefile is a sub-makefile of the current project
//get all cmake files
const std::vector<std::string>& listFiles=makefile->GetListFiles();
for (std::vector<std::string>::const_iterator lt=listFiles.begin(); lt!=listFiles.end(); lt++)
{
tmp=*lt;
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
// make sure the file is part of this source tree
if (tmp[0]!='/')
{
files.insert(tmp);
tmp=cmSystemTools::GetFilenameName(tmp);
//add all files which dont match the default */CMakeLists.txt;*cmake; to the file pattern
if ((tmp!="CMakeLists.txt")
&& (strstr(tmp.c_str(), ".cmake")==0))
{
cmakeFilePattern+=tmp+";";
}
}
}
//get all sources
cmTargets& targets=makefile->GetTargets();
for (cmTargets::const_iterator ti = targets.begin(); ti != targets.end(); ti++)
{
const std::vector<cmSourceFile*>& sources=ti->second.GetSourceFiles();
for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
si!=sources.end(); si++)
{
tmp=(*si)->GetFullPath();
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
if (tmp[0]!='/')
{
files.insert(tmp);
}
}
for (std::vector<std::string>::const_iterator lt=listFiles.begin();
lt!=listFiles.end(); lt++)
{
tmp=*lt;
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
if (tmp[0]!='/')
{
files.insert(tmp.c_str());
}
}
}
}
//check if the output file already exists and read it
//insert all files which exist into the set of files
std::ifstream oldFilelist(filename.c_str());
if (oldFilelist)
{
while (cmSystemTools::GetLineFromStream(oldFilelist, tmp))
{
if (tmp[0]=='/')
{
continue;
}
std::string completePath=projectDir+tmp;
if (cmSystemTools::FileExists(completePath.c_str()))
{
files.insert(tmp);
}
}
oldFilelist.close();
}
//now write the new filename
cmGeneratedFileStream fout(filename.c_str());
if(!fout)
{
return false;
}
for (std::set<cmStdString>::const_iterator it=files.begin(); it!=files.end(); it++)
{
// get the full path to the file
tmp=cmSystemTools::CollapseFullPath(it->c_str(), projectDir.c_str());
// make it relative to the project dir
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
// only put relative paths
if (tmp.size() && tmp[0] != '/')
{
fout << tmp.c_str() <<"\n";
}
}
return true;
} }

View File

@ -26,15 +26,6 @@ class cmTarget;
class cmSourceFile; class cmSourceFile;
/** \class cmLocalKdevelopGenerator /** \class cmLocalKdevelopGenerator
* \brief Write Unix Makefiles accompanied by KDevelop3 project files.
*
* cmLocalKdevelopGenerator produces a project file for KDevelop 3 (KDevelop > 3.1.1).
* The project is based on the "Custom Makefile based C/C++" project of KDevelop.
* Such a project consists of Unix Makefiles in the build directory together
* with a <your_project>.kdevelop project file, which contains the project settings
* and a <your_project>.kdevelop.filelist file, which lists the source files relative
* to the kdevelop project directory. The kdevelop project directory is the base
* source directory.
*/ */
class cmLocalKdevelopGenerator : public cmLocalUnixMakefileGenerator class cmLocalKdevelopGenerator : public cmLocalUnixMakefileGenerator
{ {
@ -43,40 +34,8 @@ public:
cmLocalKdevelopGenerator(); cmLocalKdevelopGenerator();
virtual ~cmLocalKdevelopGenerator(); virtual ~cmLocalKdevelopGenerator();
/**
* Generate the makefile for this directory. fromTheTop indicates if this
* is being invoked as part of a global Generate or specific to this
* directory. The difference is that when done from the Top we might skip
* some steps to save time, such as dependency generation for the
* makefiles. This is done by a direct invocation from make.
*/
virtual void Generate(bool fromTheTop);
protected:
/**
Create the foo.kdevelop file. This one calls MergeProjectFiles()
if it already exists, otherwise createNewProjectFile()
The project files will be created in \a outputDir (in the build tree), the kdevelop project
dir will be set to \a projectDir (in the source tree). \a cmakeFilePattern consists of a lists
of all cmake listfiles used by this CMakeLists.txt
*/
void CreateProjectFile(const std::string& outputDir, const std::string& projectDir,
const std::string& projectname, const std::string& executable,
const std::string& cmakeFilePattern);
/** Create the foo.kdevelop.filelist file, return false if it doesn't succeed.
If the file already exists the contents will be merged.
*/
bool CreateFilelistFile(const std::string& outputDir, const std::string& projectDir,
const std::string& projectname, std::string& cmakeFilePattern);
///! Reads the old foo.kdevelop line by line and only replaces the "important" lines
void MergeProjectFiles(const std::string& outputDir, const std::string& projectDir,
const std::string& filename, const std::string& executable,
const std::string& cmakeFilePattern);
///! Creates a new foo.kdevelop file
void CreateNewProjectFile(const std::string& outputDir, const std::string& projectDir,
const std::string& filename, const std::string& executable,
const std::string& cmakeFilePattern);
virtual void Generate(bool fromTheTop);
}; };
#endif #endif