From 766c093d69d24200e54d4c7eb22ebeae221ece06 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Mon, 11 Oct 2004 11:32:14 -0400 Subject: [PATCH] NEW: add kdevelop patch from Alexander Neundorf --- Source/CMakeLists.txt | 9 + Source/cmGlobalKdevelopGenerator.cxx | 52 ++++ Source/cmGlobalKdevelopGenerator.h | 47 ++++ Source/cmLocalKdevelopGenerator.cxx | 378 +++++++++++++++++++++++++++ Source/cmLocalKdevelopGenerator.h | 62 +++++ Source/cmake.cxx | 38 +-- 6 files changed, 569 insertions(+), 17 deletions(-) create mode 100644 Source/cmGlobalKdevelopGenerator.cxx create mode 100644 Source/cmGlobalKdevelopGenerator.h create mode 100644 Source/cmLocalKdevelopGenerator.cxx create mode 100644 Source/cmLocalKdevelopGenerator.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index fef89de31..5d9b1098e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -42,6 +42,7 @@ cmLocalUnixMakefileGenerator.h cmVariableWatch.h ) + # configure the .h file CONFIGURE_FILE( ${CMake_SOURCE_DIR}/Source/cmConfigure.cmake.h.in @@ -63,6 +64,14 @@ IF (APPLE) ) ENDIF (APPLE) +# Kdevelop only works on UNIX and not windows +IF(UNIX AND NOT WIN32) + SET(SRCS ${SRCS} + cmGlobalKdevelopGenerator.cxx + cmLocalKdevelopGenerator.cxx) +ENDIF(UNIX AND NOT WIN32) + + IF (WIN32) IF(NOT UNIX) SET(SRCS ${SRCS} diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx new file mode 100644 index 000000000..bbf3c5be2 --- /dev/null +++ b/Source/cmGlobalKdevelopGenerator.cxx @@ -0,0 +1,52 @@ +/*========================================================================= + + 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 "cmGlobalKdevelopGenerator.h" +#include "cmLocalKdevelopGenerator.h" +#include "cmMakefile.h" +#include "cmake.h" + +cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator() +{ + // This type of makefile always requires unix style paths + m_ForceUnixPaths = true; + m_FindMakeProgramFile = "CMakeUnixFindMake.cmake"; +} + +///! Create a local generator appropriate to this Global Generator +cmLocalGenerator *cmGlobalKdevelopGenerator::CreateLocalGenerator() +{ + cmLocalGenerator *lg = new cmLocalKdevelopGenerator; + lg->SetGlobalGenerator(this); + return lg; +} + +//---------------------------------------------------------------------------- +void cmGlobalKdevelopGenerator::GetDocumentation(cmDocumentationEntry& entry) const +{ + entry.name = this->GetName(); + entry.brief = "Generates KDevelop 3 project files."; + entry.full = + "A hierarchy of UNIX makefiles is generated into the build tree. Any " + "standard UNIX-style make program can build the project through the " + "default make target. A \"make install\" target is also provided." + "Additionally in each directory which features executable or library" + " targets a KDevelop 3 project file is generated.\n" + "If you change the settings using KDevelop your cmake will try its best" + "to keep your changes when regenerating the project files."; +} diff --git a/Source/cmGlobalKdevelopGenerator.h b/Source/cmGlobalKdevelopGenerator.h new file mode 100644 index 000000000..31a35a857 --- /dev/null +++ b/Source/cmGlobalKdevelopGenerator.h @@ -0,0 +1,47 @@ +/*========================================================================= + + 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. + +=========================================================================*/ +#ifndef cmGlobalKdevelopGenerator_h +#define cmGlobalKdevelopGenerator_h + +#include "cmGlobalUnixMakefileGenerator.h" + +/** \class cmGlobalUnixMakefileGenerator + * \brief Write a Unix makefiles. + * + * cmGlobalUnixMakefileGenerator manages UNIX build process for a tree + */ +class cmGlobalKdevelopGenerator : public cmGlobalUnixMakefileGenerator +{ +public: + cmGlobalKdevelopGenerator(); + static cmGlobalGenerator* New() { return new cmGlobalKdevelopGenerator; } + + ///! Get the name for the generator. + virtual const char* GetName() const { + return cmGlobalKdevelopGenerator::GetActualName();} + static const char* GetActualName() {return "KDevelop3";} + + /** Get the documentation entry for this generator. */ + virtual void GetDocumentation(cmDocumentationEntry& entry) const; + + ///! Create a local generator appropriate to this Global Generator + virtual cmLocalGenerator *CreateLocalGenerator(); + +}; + +#endif diff --git a/Source/cmLocalKdevelopGenerator.cxx b/Source/cmLocalKdevelopGenerator.cxx new file mode 100644 index 000000000..7b87d83b7 --- /dev/null +++ b/Source/cmLocalKdevelopGenerator.cxx @@ -0,0 +1,378 @@ +/*========================================================================= + + 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; +} + + diff --git a/Source/cmLocalKdevelopGenerator.h b/Source/cmLocalKdevelopGenerator.h new file mode 100644 index 000000000..e6d59e26c --- /dev/null +++ b/Source/cmLocalKdevelopGenerator.h @@ -0,0 +1,62 @@ +/*========================================================================= + + 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. + +=========================================================================*/ +#ifndef cmLocalKdevelopGenerator_h +#define cmLocalKdevelopGenerator_h + +#include "cmLocalUnixMakefileGenerator.h" + +class cmDependInformation; +class cmMakeDepend; +class cmTarget; +class cmSourceFile; + +/** \class cmLocalKdevelopGenerator + * \brief Write a LocalUnix makefiles. + * + * cmLocalKdevelopGenerator produces a LocalUnix makefile from its + * member m_Makefile. + */ +class cmLocalKdevelopGenerator : public cmLocalUnixMakefileGenerator +{ +public: + ///! Set cache only and recurse to false by default. + 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() + 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); + +}; + +#endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 340766e22..b365353e5 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -25,29 +25,29 @@ // include the generator #if defined(_WIN32) && !defined(__CYGWIN__) -#include "cmGlobalVisualStudio6Generator.h" -#if !defined(__MINGW32__) -#include "cmGlobalVisualStudio7Generator.h" -#include "cmGlobalVisualStudio71Generator.h" -#include "cmGlobalVisualStudio8Generator.h" -#endif -#include "cmGlobalBorlandMakefileGenerator.h" -#include "cmGlobalNMakeMakefileGenerator.h" -#include "cmGlobalUnixMakefileGenerator.h" -#include "cmWin32ProcessExecution.h" +# include "cmGlobalVisualStudio6Generator.h" +# if !defined(__MINGW32__) +# include "cmGlobalVisualStudio7Generator.h" +# include "cmGlobalVisualStudio71Generator.h" +# include "cmGlobalVisualStudio8Generator.h" +# endif +# include "cmGlobalBorlandMakefileGenerator.h" +# include "cmGlobalNMakeMakefileGenerator.h" +# include "cmWin32ProcessExecution.h" #else -#include "cmGlobalUnixMakefileGenerator.h" #endif +#include "cmGlobalUnixMakefileGenerator.h" +#include "cmGlobalKdevelopGenerator.h" #include // required for atoi #ifdef __APPLE__ -#include -#include -#include -#if defined(CMAKE_BUILD_WITH_CMAKE) -#include "cmGlobalCodeWarriorGenerator.h" -#endif +# include +# include +# include +# if defined(CMAKE_BUILD_WITH_CMAKE) +# include "cmGlobalCodeWarriorGenerator.h" +# endif #endif #include // auto_ptr @@ -1415,6 +1415,10 @@ void cmake::AddDefaultGenerators() #endif m_Generators[cmGlobalUnixMakefileGenerator::GetActualName()] = &cmGlobalUnixMakefileGenerator::New; +#if !defined(_WIN32) + m_Generators[cmGlobalKdevelopGenerator::GetActualName()] = + &cmGlobalKdevelopGenerator::New; +#endif } int cmake::LoadCache()