From 03be131c063f7d0b1ed566ddbc35e84d3b1d342f Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Thu, 21 Oct 2004 11:58:07 -0400 Subject: [PATCH] ENH: better support for kdevelop3 --- Source/cmLocalKdevelopGenerator.cxx | 212 ++++++++++++++++------------ Source/cmLocalKdevelopGenerator.h | 26 ++-- 2 files changed, 137 insertions(+), 101 deletions(-) diff --git a/Source/cmLocalKdevelopGenerator.cxx b/Source/cmLocalKdevelopGenerator.cxx index 6632d6249..9ad85db87 100644 --- a/Source/cmLocalKdevelopGenerator.cxx +++ b/Source/cmLocalKdevelopGenerator.cxx @@ -26,7 +26,6 @@ #include "cmake.h" #include - cmLocalKdevelopGenerator::cmLocalKdevelopGenerator() :cmLocalUnixMakefileGenerator() { @@ -44,69 +43,59 @@ void cmLocalKdevelopGenerator::Generate(bool fromTheTop) { return; } - - bool containsTargets=false; - std::string executable; - cmTargets& targets=m_Makefile->GetTargets(); - for (cmTargets::const_iterator ti = targets.begin(); ti != targets.end(); ti++) + // 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) { - switch (ti->second.GetType()) - { - case cmTarget::EXECUTABLE: - 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 lgs; - m_GlobalGenerator->GetLocalGenerators(lgs); - std::string projectName=lgs[0]->GetMakefile()->GetProjectName(); - + 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(filelistDir, projectName, cmakeFilePattern)) + + if (!this->CreateFilelistFile(outputDir, projectDir, projectName, cmakeFilePattern)) { 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& executable, const std::string& cmakeFilePattern) { - std::string filename=m_Makefile->GetStartOutputDirectory(); - filename+="/"; + std::string filename=outputDir+"/"; filename+=projectname+".kdevelop"; if (cmSystemTools::FileExists(filename.c_str())) { - this->MergeProjectFiles(dir, filename, executable, cmakeFilePattern); + this->MergeProjectFiles(outputDir, projectDir, filename, executable, cmakeFilePattern); } 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& executable, const std::string& cmakeFilePattern) @@ -114,7 +103,7 @@ void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& dir, std::ifstream oldProjectFile(filename.c_str()); if (!oldProjectFile) { - this->CreateNewProjectFile(dir, filename, executable, cmakeFilePattern); + this->CreateNewProjectFile(outputDir, projectDir, filename, executable, cmakeFilePattern); return; } @@ -139,36 +128,45 @@ void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& dir, it!=lines.end(); it++) { const char* line=(*it).c_str(); - + // skip these tags as they are always replaced if ((strstr(line, "")!=0) || (strstr(line, "")!=0) || (strstr(line, "")!=0) + || (strstr(line, "")!=0) || (strstr(line, "")!=0) || (strstr(line, "")!=0)) { continue; } + // output the line from the file if it is not one of the above tags fout<<*it<<"\n"; - + // if this is the tag output the stuff that goes in the general tag if (strstr(line, "")) { fout<<" KDevCustomProject\n"; - fout<<" "<\n"; //this one is important - fout<<" true\n"; //and this one + fout<<" "<\n"; //this one is important + fout<<" true\n"; //and this one } - + // inside kdevcustomproject the must be put + if (strstr(line, "")) + { + fout<<" "<\n"; + } + // buildtool and builddir go inside if (strstr(line, "")) { - fout<<" make\n"; //this one is important - fout<<" "<GetStartOutputDirectory()<<"\n"; //and this one - + fout<<" make\n"; //this one is important + fout<<" "<\n"; //and this one } } } -void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, const std::string& filename, - const std::string& executable, const std::string& cmakeFilePattern) +void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& outputDir, + const std::string& projectDir, + const std::string& filename, + const std::string& executable, + const std::string& cmakeFilePattern) { cmGeneratedFileStream tempFile(filename.c_str()); @@ -190,15 +188,16 @@ void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, cons fout<<" KDevCustomProject\n"; fout<<" C++\n"; fout<<" \n"; - fout<<" "<\n"; //this one is important + fout<<" "<\n"; //this one is important fout<<" true\n"; //and this one fout<<" \n"; fout<<" C\n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; + fout<<" "<\n"; fout<<" \n"; - fout<<" "<GetStartOutputDirectory()<<"/"<\n"; + fout<<" "<\n"; fout<<" custom\n"; fout<<" /\n"; fout<<" \n"; @@ -208,7 +207,7 @@ void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, cons fout<<" \n"; fout<<" \n"; fout<<" make\n"; //this one is important - fout<<" "<GetStartOutputDirectory()<<"\n"; //and this one + fout<<" "<\n"; //and this one fout<<" \n"; fout<<" \n"; fout<<" false\n"; @@ -275,54 +274,76 @@ void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, cons fout<<" \n"; fout<<" \n"; fout<<"\n"; + } -bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir, +bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& outputDir, const std::string& _projectDir, const std::string& projectname, std::string& cmakeFilePattern) { - std::string filelistDir=_dir+"/"; - std::string filename=filelistDir+projectname+".kdevelop.filelist"; + std::string projectDir=_projectDir+"/"; + std::string filename=outputDir+"/"+projectname+".kdevelop.filelist"; std::set files; - - //get all cmake files std::string tmp; - const std::vector& listFiles=m_Makefile->GetListFiles(); - for (std::vector::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 lgs; + m_GlobalGenerator->GetLocalGenerators(lgs); + for (std::vector::const_iterator it=lgs.begin(); it!=lgs.end(); it++) { - tmp=*it; - cmSystemTools::ReplaceString(tmp, filelistDir.c_str(), ""); - if (tmp[0]!='/') + 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) { - 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)) + continue; + } + // This means the makefile is a sub-makefile of the current project + //get all cmake files + const std::vector& listFiles=makefile->GetListFiles(); + for (std::vector::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& sources=ti->second.GetSourceFiles(); + for (std::vector::const_iterator it=sources.begin(); + it!=sources.end(); it++) + { + files.insert((*it)->GetFullPath()); + } + for (std::vector::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& sources=ti->second.GetSourceFiles(); - for (std::vector::const_iterator it=sources.begin(); - it!=sources.end(); it++) - { - files.insert((*it)->GetFullPath()); - } - for (std::vector::const_iterator it=listFiles.begin(); - it!=listFiles.end(); it++) - { - files.insert(it->c_str()); - } - } - //check if the output file already exists and read it //insert all files which exist into the set of files @@ -335,7 +356,7 @@ bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir, { continue; } - std::string completePath=filelistDir+tmp; + std::string completePath=projectDir+tmp; if (cmSystemTools::FileExists(completePath.c_str())) { files.insert(tmp); @@ -343,7 +364,6 @@ bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir, } oldFilelist.close(); } - cmGeneratedFileStream tempFile(filename.c_str()); tempFile.SetAlwaysCopy(true); @@ -356,9 +376,15 @@ bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir, for (std::set::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; } - - diff --git a/Source/cmLocalKdevelopGenerator.h b/Source/cmLocalKdevelopGenerator.h index e6d59e26c..03eaeee5c 100644 --- a/Source/cmLocalKdevelopGenerator.h +++ b/Source/cmLocalKdevelopGenerator.h @@ -48,14 +48,24 @@ public: */ virtual void Generate(bool fromTheTop); 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.filelist file, return false if it doesn't succeed - 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 MergeProjectFiles(const std::string& dir, const std::string& filename, const std::string& executable, const std::string& cmakeFilePattern); - ///Creates a new foo.kdevelop file - void CreateNewProjectFile(const std::string& dir, const std::string& filename, const std::string& executable, const std::string& cmakeFilePattern); + /** + Create the foo.kdevelop file. This one calls MergeProjectFiles() + if it already exists, otherwise createNewProjectFile() + */ + 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 + 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); };