ENH: better support for kdevelop3

This commit is contained in:
Bill Hoffman 2004-10-21 11:58:07 -04:00
parent fc459731db
commit 03be131c06
2 changed files with 137 additions and 101 deletions

View File

@ -26,7 +26,6 @@
#include "cmake.h" #include "cmake.h"
#include <cmsys/RegularExpression.hxx> #include <cmsys/RegularExpression.hxx>
cmLocalKdevelopGenerator::cmLocalKdevelopGenerator() cmLocalKdevelopGenerator::cmLocalKdevelopGenerator()
:cmLocalUnixMakefileGenerator() :cmLocalUnixMakefileGenerator()
{ {
@ -44,69 +43,59 @@ void cmLocalKdevelopGenerator::Generate(bool fromTheTop)
{ {
return; return;
} }
// Does this local generator contain a PROJECT command
bool containsTargets=false; // if so, then generate a kdevelop project for it
std::string executable; if (strcmp(m_Makefile->GetDefinition("PROJECT_BINARY_DIR"), m_Makefile->GetStartOutputDirectory())==0)
cmTargets& targets=m_Makefile->GetTargets();
for (cmTargets::const_iterator ti = targets.begin(); ti != targets.end(); ti++)
{ {
switch (ti->second.GetType()) std::string outputDir=m_Makefile->GetStartOutputDirectory();
{ std::string projectDir=m_Makefile->GetHomeDirectory();
case cmTarget::EXECUTABLE: std::string projectName=m_Makefile->GetProjectName();
executable=ti->first;
case cmTarget::STATIC_LIBRARY:
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
case cmTarget::UTILITY:
containsTargets=true;
break;
case cmTarget::INSTALL_FILES:
case cmTarget::INSTALL_PROGRAMS:
default:
break;
}
}
if (containsTargets)
{
std::string filelistDir=m_Makefile->GetHomeOutputDirectory();
//build the project name by taking the subdir
std::vector<cmLocalGenerator *> lgs;
m_GlobalGenerator->GetLocalGenerators(lgs);
std::string projectName=lgs[0]->GetMakefile()->GetProjectName();
std::string cmakeFilePattern("CMakeLists.txt;*.cmake;"); std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
if (!this->CreateFilelistFile(filelistDir, projectName, cmakeFilePattern)) if (!this->CreateFilelistFile(outputDir, projectDir, projectName, cmakeFilePattern))
{ {
return; return;
} }
this->CreateProjectFile(filelistDir, projectName, executable, cmakeFilePattern); //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);
} }
} }
void cmLocalKdevelopGenerator::CreateProjectFile(const std::string& dir, void cmLocalKdevelopGenerator::CreateProjectFile(const std::string& outputDir,
const std::string& projectDir,
const std::string& projectname, const std::string& projectname,
const std::string& executable, const std::string& executable,
const std::string& cmakeFilePattern) const std::string& cmakeFilePattern)
{ {
std::string filename=m_Makefile->GetStartOutputDirectory(); std::string filename=outputDir+"/";
filename+="/";
filename+=projectname+".kdevelop"; filename+=projectname+".kdevelop";
if (cmSystemTools::FileExists(filename.c_str())) if (cmSystemTools::FileExists(filename.c_str()))
{ {
this->MergeProjectFiles(dir, filename, executable, cmakeFilePattern); this->MergeProjectFiles(outputDir, projectDir, filename, executable, cmakeFilePattern);
} }
else else
{ {
this->CreateNewProjectFile(dir, filename, executable, cmakeFilePattern); this->CreateNewProjectFile(outputDir, projectDir, filename, executable, cmakeFilePattern);
} }
} }
void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& dir, void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& outputDir,
const std::string& projectDir,
const std::string& filename, const std::string& filename,
const std::string& executable, const std::string& executable,
const std::string& cmakeFilePattern) const std::string& cmakeFilePattern)
@ -114,7 +103,7 @@ void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& dir,
std::ifstream oldProjectFile(filename.c_str()); std::ifstream oldProjectFile(filename.c_str());
if (!oldProjectFile) if (!oldProjectFile)
{ {
this->CreateNewProjectFile(dir, filename, executable, cmakeFilePattern); this->CreateNewProjectFile(outputDir, projectDir, filename, executable, cmakeFilePattern);
return; return;
} }
@ -139,36 +128,45 @@ void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& dir,
it!=lines.end(); it++) it!=lines.end(); it++)
{ {
const char* line=(*it).c_str(); const char* line=(*it).c_str();
// skip these tags as they are always replaced
if ((strstr(line, "<projectdirectory>")!=0) if ((strstr(line, "<projectdirectory>")!=0)
|| (strstr(line, "<projectmanagement>")!=0) || (strstr(line, "<projectmanagement>")!=0)
|| (strstr(line, "<absoluteprojectpath>")!=0) || (strstr(line, "<absoluteprojectpath>")!=0)
|| (strstr(line, "<filelistdirectory>")!=0)
|| (strstr(line, "<buildtool>")!=0) || (strstr(line, "<buildtool>")!=0)
|| (strstr(line, "<builddir>")!=0)) || (strstr(line, "<builddir>")!=0))
{ {
continue; continue;
} }
// output the line from the file if it is not one of the above tags
fout<<*it<<"\n"; fout<<*it<<"\n";
// if this is the <general> tag output the stuff that goes in the general tag
if (strstr(line, "<general>")) if (strstr(line, "<general>"))
{ {
fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n"; fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n";
fout<<" <projectdirectory>"<<dir.c_str()<<"</projectdirectory>\n"; //this one is important fout<<" <projectdirectory>"<<projectDir.c_str()<<"</projectdirectory>\n"; //this one is important
fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one 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>")) if (strstr(line, "<build>"))
{ {
fout<<" <buildtool>make</buildtool>\n"; //this one is important fout<<" <buildtool>make</buildtool>\n"; //this one is important
fout<<" <builddir>"<<m_Makefile->GetStartOutputDirectory()<<"</builddir>\n"; //and this one fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n"; //and this one
} }
} }
} }
void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, const std::string& filename, void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& outputDir,
const std::string& executable, const std::string& cmakeFilePattern) const std::string& projectDir,
const std::string& filename,
const std::string& executable,
const std::string& cmakeFilePattern)
{ {
cmGeneratedFileStream tempFile(filename.c_str()); cmGeneratedFileStream tempFile(filename.c_str());
@ -190,15 +188,16 @@ void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, cons
fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n"; fout<<" <projectmanagement>KDevCustomProject</projectmanagement>\n";
fout<<" <primarylanguage>C++</primarylanguage>\n"; fout<<" <primarylanguage>C++</primarylanguage>\n";
fout<<" <ignoreparts/>\n"; fout<<" <ignoreparts/>\n";
fout<<" <projectdirectory>"<<dir.c_str()<<"</projectdirectory>\n"; //this one is important fout<<" <projectdirectory>"<<projectDir.c_str()<<"</projectdirectory>\n"; //this one is important
fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
fout<<" <secondaryLanguages>\n"; fout<<" <secondaryLanguages>\n";
fout<<" <language>C</language>\n"; fout<<" <language>C</language>\n";
fout<<" </secondaryLanguages>\n"; fout<<" </secondaryLanguages>\n";
fout<<" </general>\n"; fout<<" </general>\n";
fout<<" <kdevcustomproject>\n"; fout<<" <kdevcustomproject>\n";
fout<<" <filelistdirectory>"<<outputDir.c_str()<<"</filelistdirectory>\n";
fout<<" <run>\n"; fout<<" <run>\n";
fout<<" <mainprogram>"<<m_Makefile->GetStartOutputDirectory()<<"/"<<executable.c_str()<<"</mainprogram>\n"; fout<<" <mainprogram>"<<outputDir.c_str()<<"/"<<executable.c_str()<<"</mainprogram>\n";
fout<<" <directoryradio>custom</directoryradio>\n"; fout<<" <directoryradio>custom</directoryradio>\n";
fout<<" <customdirectory>/</customdirectory>\n"; fout<<" <customdirectory>/</customdirectory>\n";
fout<<" <programargs></programargs>\n"; fout<<" <programargs></programargs>\n";
@ -208,7 +207,7 @@ void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, cons
fout<<" </run>\n"; fout<<" </run>\n";
fout<<" <build>\n"; fout<<" <build>\n";
fout<<" <buildtool>make</buildtool>\n"; //this one is important fout<<" <buildtool>make</buildtool>\n"; //this one is important
fout<<" <builddir>"<<m_Makefile->GetStartOutputDirectory()<<"</builddir>\n"; //and this one fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n"; //and this one
fout<<" </build>\n"; fout<<" </build>\n";
fout<<" <make>\n"; fout<<" <make>\n";
fout<<" <abortonerror>false</abortonerror>\n"; fout<<" <abortonerror>false</abortonerror>\n";
@ -275,54 +274,76 @@ void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, cons
fout<<" </tree>\n"; fout<<" </tree>\n";
fout<<" </kdevfileview>\n"; fout<<" </kdevfileview>\n";
fout<<"</kdevelop>\n"; fout<<"</kdevelop>\n";
} }
bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir, bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& outputDir, const std::string& _projectDir,
const std::string& projectname, const std::string& projectname,
std::string& cmakeFilePattern) std::string& cmakeFilePattern)
{ {
std::string filelistDir=_dir+"/"; std::string projectDir=_projectDir+"/";
std::string filename=filelistDir+projectname+".kdevelop.filelist"; std::string filename=outputDir+"/"+projectname+".kdevelop.filelist";
std::set<cmStdString> files; std::set<cmStdString> files;
//get all cmake files
std::string tmp; std::string tmp;
const std::vector<std::string>& listFiles=m_Makefile->GetListFiles();
for (std::vector<std::string>::const_iterator it=listFiles.begin(); it!=listFiles.end(); it++) // 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++)
{ {
tmp=*it; cmMakefile* makefile=(*it)->GetMakefile();
cmSystemTools::ReplaceString(tmp, filelistDir.c_str(), ""); // if the makefile GetStartOutputDirectory is not a substring of the outputDir
if (tmp[0]!='/') // then skip it
if (strstr(makefile->GetStartOutputDirectory(), outputDir.c_str())==0)
{ {
files.insert(tmp); continue;
tmp=cmSystemTools::GetFilenameName(tmp); }
//add all files which dont match the default */CMakeLists.txt;*cmake; to the file pattern // This means the makefile is a sub-makefile of the current project
if ((tmp!="CMakeLists.txt") //get all cmake files
&& (strstr(tmp.c_str(), ".cmake")==0)) const std::vector<std::string>& listFiles=makefile->GetListFiles();
for (std::vector<std::string>::const_iterator it=listFiles.begin(); it!=listFiles.end(); it++)
{
tmp=*it;
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
// make sure the file is part of this source tree
if (tmp[0]!='/')
{ {
cmakeFilePattern+=tmp+";"; 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 it=sources.begin();
it!=sources.end(); it++)
{
files.insert((*it)->GetFullPath());
}
for (std::vector<std::string>::const_iterator it=listFiles.begin();
it!=listFiles.end(); it++)
{
tmp=*it;
cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
if (tmp[0]!='/')
{
files.insert(tmp.c_str());
}
} }
} }
} }
//get all sources
cmTargets& targets=m_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 it=sources.begin();
it!=sources.end(); it++)
{
files.insert((*it)->GetFullPath());
}
for (std::vector<std::string>::const_iterator it=listFiles.begin();
it!=listFiles.end(); it++)
{
files.insert(it->c_str());
}
}
//check if the output file already exists and read it //check if the output file already exists and read it
//insert all files which exist into the set of files //insert all files which exist into the set of files
@ -335,7 +356,7 @@ bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir,
{ {
continue; continue;
} }
std::string completePath=filelistDir+tmp; std::string completePath=projectDir+tmp;
if (cmSystemTools::FileExists(completePath.c_str())) if (cmSystemTools::FileExists(completePath.c_str()))
{ {
files.insert(tmp); files.insert(tmp);
@ -343,7 +364,6 @@ bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir,
} }
oldFilelist.close(); oldFilelist.close();
} }
cmGeneratedFileStream tempFile(filename.c_str()); cmGeneratedFileStream tempFile(filename.c_str());
tempFile.SetAlwaysCopy(true); tempFile.SetAlwaysCopy(true);
@ -356,9 +376,15 @@ bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir,
for (std::set<cmStdString>::const_iterator it=files.begin(); it!=files.end(); it++) for (std::set<cmStdString>::const_iterator it=files.begin(); it!=files.end(); it++)
{ {
fout<< cmSystemTools::RelativePath(_dir.c_str(), it->c_str())<<"\n"; // get the full path to the file
tmp=cmSystemTools::CollapseFullPath(it->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; return true;
} }

View File

@ -48,14 +48,24 @@ public:
*/ */
virtual void Generate(bool fromTheTop); virtual void Generate(bool fromTheTop);
protected: protected:
///Create the foo.kdevelop file. This one calls MergeProjectFiles() if it already exists, otherwise createNewProjectFile() /**
void CreateProjectFile(const std::string& dir, const std::string& projectname, const std::string& executable, const std::string& cmakeFilePattern); Create the foo.kdevelop file. This one calls MergeProjectFiles()
/// Create the foo.kdevelop.filelist file, return false if it doesn't succeed if it already exists, otherwise createNewProjectFile()
bool CreateFilelistFile(const std::string& dir, const std::string& projectname, std::string& cmakeFilePattern); */
///Reads the old foo.kdevelop line by line and only replaces the "important" lines void CreateProjectFile(const std::string& outputDir, const std::string& projectDir,
void MergeProjectFiles(const std::string& dir, const std::string& filename, const std::string& executable, const std::string& cmakeFilePattern); const std::string& projectname, const std::string& executable,
///Creates a new foo.kdevelop file const std::string& cmakeFilePattern);
void CreateNewProjectFile(const std::string& dir, const std::string& filename, const std::string& executable, const std::string& cmakeFilePattern); ///! Create the foo.kdevelop.filelist file, return false if it doesn't succeed
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);
}; };