/*========================================================================= Program: CMake - Cross-Platform Makefile Generator Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. Copyright (c) 2004 Alexander Neundorf, neundorf@kde.org. 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 "cmGlobalGenerator.h" #include "cmLocalKdevelopGenerator.h" #include "cmMakefile.h" #include "cmSystemTools.h" #include "cmSourceFile.h" #include "cmMakeDepend.h" #include "cmCacheManager.h" #include "cmGeneratedFileStream.h" #include #include cmLocalKdevelopGenerator::cmLocalKdevelopGenerator() :cmLocalUnixMakefileGenerator() { } cmLocalKdevelopGenerator::~cmLocalKdevelopGenerator() { } #include #include #include void cmLocalKdevelopGenerator::Generate(bool fromTheTop) { cmLocalUnixMakefileGenerator::Generate(fromTheTop); bool containsTargets=false; std::string executable; cmTargets& targets=m_Makefile->GetTargets(); for (cmTargets::const_iterator ti = targets.begin(); ti != targets.end(); ti++) { 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 projectFileDir=m_Makefile->GetStartOutputDirectory(); std::string filelistDir=m_Makefile->GetDefinition("PROJECT_SOURCE_DIR"); //build the project name by taking the subdir std::string projectName=m_Makefile->GetProjectName(); projectName+=m_Makefile->GetStartOutputDirectory(); cmSystemTools::ReplaceString(projectName, filelistDir.c_str(), ""); cmSystemTools::ReplaceString(projectName, "/", "_"); std::string cmakeFilePattern("*/CMakeLists.txt;*.cmake;"); if (!this->CreateFilelistFile(filelistDir, projectName, cmakeFilePattern)) { return; } this->CreateProjectFile(filelistDir, projectName, executable, cmakeFilePattern); } } void cmLocalKdevelopGenerator::CreateProjectFile(const std::string& dir, const std::string& projectname, const std::string& executable, const std::string& cmakeFilePattern) { std::string filename=m_Makefile->GetStartOutputDirectory(); filename+="/"; filename+=projectname+".kdevelop"; if (cmSystemTools::FileExists(filename.c_str())) { this->MergeProjectFiles(dir, filename, executable, cmakeFilePattern); } else { this->CreateNewProjectFile(dir, filename, executable, cmakeFilePattern); } } void cmLocalKdevelopGenerator::MergeProjectFiles(const std::string& dir, const std::string& filename, const std::string& executable, const std::string& cmakeFilePattern) { std::ifstream oldProjectFile(filename.c_str()); if (!oldProjectFile) { this->CreateNewProjectFile(dir, filename, executable, cmakeFilePattern); return; } std::string tmp; std::vector lines; while (cmSystemTools::GetLineFromStream(oldProjectFile, tmp)) { lines.push_back(tmp); } oldProjectFile.close(); cmGeneratedFileStream tempFile(filename.c_str()); tempFile.SetAlwaysCopy(true); std::ostream& fout = tempFile.GetStream(); if(!fout) { cmSystemTools::Error("Error can not open for write: ", filename.c_str()); return; } for (std::vector::const_iterator it=lines.begin(); it!=lines.end(); it++) { const char* line=(*it).c_str(); if ((strstr(line, "")!=0) || (strstr(line, "")!=0) || (strstr(line, "")!=0) || (strstr(line, "")!=0) || (strstr(line, "")!=0)) { continue; } fout<<*it<<"\n"; if (strstr(line, "")) { fout<<" KDevCustomProject\n"; fout<<" "<\n"; //this one is important fout<<" true\n"; //and this one } if (strstr(line, "")) { fout<<" make\n"; //this one is important fout<<" "<GetStartOutputDirectory()<<"\n"; //and this one } } } void cmLocalKdevelopGenerator::CreateNewProjectFile(const std::string& dir, const std::string& filename, const std::string& executable, const std::string& cmakeFilePattern) { cmGeneratedFileStream tempFile(filename.c_str()); tempFile.SetAlwaysCopy(true); std::ostream& fout = tempFile.GetStream(); if(!fout) { cmSystemTools::Error("Error can not open for write: ", filename.c_str()); return; } fout<<"\n"; fout<<"\n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" $VERSION$\n"; fout<<" KDevCustomProject\n"; fout<<" C++\n"; fout<<" \n"; 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<<" "<GetStartOutputDirectory()<<"/"<\n"; fout<<" custom\n"; fout<<" /\n"; fout<<" \n"; fout<<" false\n"; fout<<" true\n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" make\n"; //this one is important fout<<" "<GetStartOutputDirectory()<<"\n"; //and this one fout<<" \n"; fout<<" \n"; fout<<" false\n"; fout<<" 1\n"; fout<<" false\n"; fout<<" \n"; fout<<" default\n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" html/\n"; fout<<" html/\n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" .h\n"; fout<<" .cpp\n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" true\n"; fout<<" true\n"; fout<<" true\n"; fout<<" false\n"; fout<<" true\n"; fout<<" true\n"; fout<<" true\n"; fout<<" 250\n"; fout<<" 400\n"; fout<<" 250\n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" \n"; fout<<" true\n"; fout<<" \n"; fout<<" \n"; fout<<" *.o,*.lo,CVS,*~,cmake*\n"; fout<<" true\n"; fout<<" \n"; fout<<" \n"; fout<<"\n"; } bool cmLocalKdevelopGenerator::CreateFilelistFile(const std::string& _dir, const std::string& projectname, std::string& cmakeFilePattern) { std::string filelistDir=_dir+"/"; std::string filename=filelistDir+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++) { tmp=*it; cmSystemTools::ReplaceString(tmp, filelistDir.c_str(), ""); 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=m_Makefile->GetTargets(); for (cmTargets::const_iterator ti = targets.begin(); ti != targets.end(); ti++) { const std::vector& sources=ti->second.GetSourceLists(); for (std::vector::const_iterator it=sources.begin(); it!=sources.end(); it++) { tmp=*it; if (tmp[0]!='/') //no absolute path { tmp=std::string(m_Makefile->GetDefinition("CMAKE_CURRENT_SOURCE_DIR"))+"/"+tmp; } tmp=cmSystemTools::CollapseFullPath(tmp.c_str()); cmSystemTools::ReplaceString(tmp, filelistDir.c_str(), ""); if (tmp[0]=='/') { std::string errorMessage("In order to get working KDevelop project files, you have to call " "PROJECT() in a directory which is a parent directory of all source files. The source file "); errorMessage+=tmp+" is not located beneath your current project directory "+filelistDir+" ."; cmSystemTools::Error(errorMessage.c_str()); return false; } files.insert(tmp); } } //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=filelistDir+tmp; if (cmSystemTools::FileExists(completePath.c_str())) { files.insert(tmp); } } oldFilelist.close(); } cmGeneratedFileStream tempFile(filename.c_str()); tempFile.SetAlwaysCopy(true); std::ostream& fout = tempFile.GetStream(); if(!fout) { cmSystemTools::Error("Error can not open for write: ", filename.c_str()); return false; } for (std::set::const_iterator it=files.begin(); it!=files.end(); it++) { fout<<*it<<"\n"; } return true; }