Просмотр исходного кода

ENH: add a simple CodeBlocks extra generator, early alpha stage, there seems
to be interest in it

Alex

Alexander Neundorf 18 лет назад
Родитель
Сommit
378a8e99f9
4 измененных файлов с 337 добавлено и 1 удалено
  1. 2 1
      Source/CMakeLists.txt
  2. 269 0
      Source/cmExtraCodeBlocksGenerator.cxx
  3. 63 0
      Source/cmExtraCodeBlocksGenerator.h
  4. 3 0
      Source/cmake.cxx

+ 2 - 1
Source/CMakeLists.txt

@@ -174,7 +174,8 @@ SET(SRCS
 # Kdevelop only works on UNIX and not windows
 # Kdevelop only works on UNIX and not windows
 IF(UNIX)
 IF(UNIX)
   SET(SRCS ${SRCS}
   SET(SRCS ${SRCS}
-    cmGlobalKdevelopGenerator.cxx)
+    cmGlobalKdevelopGenerator.cxx
+    cmExtraCodeBlocksGenerator.cxx)
 ENDIF(UNIX)
 ENDIF(UNIX)
 # XCode only works on apple
 # XCode only works on apple
 IF(APPLE)
 IF(APPLE)

+ 269 - 0
Source/cmExtraCodeBlocksGenerator.cxx

@@ -0,0 +1,269 @@
+/*=========================================================================
+
+  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 [email protected], 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 "cmExtraCodeBlocksGenerator.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+#include "cmSourceFile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmTarget.h"
+
+#include <cmsys/SystemTools.hxx>
+
+//----------------------------------------------------------------------------
+void cmExtraCodeBlocksGenerator
+::GetDocumentation(cmDocumentationEntry& entry, const char*) const
+{
+  entry.name = this->GetName();
+  entry.brief = "Generates CodeBlocks project files.";
+  entry.full =
+    "Project files for CodeBlocks will be created in the top directory "
+    "and in every subdirectory which features a CMakeLists.txt file "
+    "containing a PROJECT() call. "
+    "Additionally 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.";
+}
+
+cmExtraCodeBlocksGenerator::cmExtraCodeBlocksGenerator()
+:cmExternalMakefileProjectGenerator()
+{
+  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+}
+
+
+void cmExtraCodeBlocksGenerator::SetGlobalGenerator(
+                                                  cmGlobalGenerator* generator)
+{
+  cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator);
+  cmGlobalUnixMakefileGenerator3* mf = (cmGlobalUnixMakefileGenerator3*)
+                                                                     generator;
+  mf->SetToolSupportsColor(false);
+  mf->SetForceVerboseMakefiles(true);
+}
+
+void cmExtraCodeBlocksGenerator::Generate()
+{
+
+  const cmMakefile* topLevelMakefile = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+
+  std::string workspaceName = topLevelMakefile->GetProjectName();
+  std::string outputDir=topLevelMakefile->GetStartOutputDirectory();
+  std::string workspaceFilename = outputDir;
+  workspaceFilename += "/";
+  workspaceFilename += workspaceName;
+  workspaceFilename += ".workspace";
+
+  cmGeneratedFileStream fout(workspaceFilename.c_str());
+  if(!fout)
+  {
+    return;
+  }
+
+  fout<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n"
+        "<CodeBlocks_workspace_file>\n"
+        "   <Workspace title=\""<<workspaceName<<"\">\n";
+
+  bool firstProject = true;
+  // for each sub project in the project create
+  // a kdevelop project
+  for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+       it = this->GlobalGenerator->GetProjectMap().begin();
+      it!= this->GlobalGenerator->GetProjectMap().end();
+      ++it)
+    {
+    const cmMakefile* mf=it->second[0]->GetMakefile();
+    std::string filename=mf->GetStartOutputDirectory();
+    filename+="/";
+    filename+=mf->GetProjectName();
+    filename+=".cbp";
+
+    if (firstProject)
+    {
+      fout<<"      <Project filename=\""<< filename<<"\" active=\"1\"/>\n";
+    }
+    else
+    {
+      fout<<"      <Project filename=\""<< filename<<"\" />\n";
+    }
+    // create a project file
+    this->CreateProjectFile(it->second);
+    }
+
+  fout<<"   </Workspace>\n"
+        "</CodeBlocks_workspace_file>\n";
+}
+
+
+/* create the project file, if it already exists, merge it with the
+existing one, otherwise create a new one */
+void cmExtraCodeBlocksGenerator::CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs)
+{
+  const cmMakefile* mf=lgs[0]->GetMakefile();
+  std::string outputDir=mf->GetStartOutputDirectory();
+  std::string projectDir=mf->GetHomeDirectory();
+  std::string projectName=mf->GetProjectName();
+
+  std::string filename=outputDir+"/";
+  filename+=projectName+".cbp";
+  std::string sessionFilename=outputDir+"/";
+  sessionFilename+=projectName+".layout";
+
+/*  if (cmSystemTools::FileExists(filename.c_str()))
+    {
+    this->MergeProjectFiles(outputDir, projectDir, filename,
+                            cmakeFilePattern, sessionFilename);
+    }
+  else */
+    {
+    this->CreateNewProjectFile(lgs, filename);
+    }
+
+}
+
+
+void cmExtraCodeBlocksGenerator
+  ::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
+                         const std::string& filename)
+{
+  const cmMakefile* mf=lgs[0]->GetMakefile();
+  cmGeneratedFileStream fout(filename.c_str());
+  if(!fout)
+    {
+    return;
+    }
+
+  std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+
+  fout<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n"
+        "<CodeBlocks_project_file>\n"
+        "   <FileVersion major=\"1\" minor=\"6\" />\n"
+        "   <Project>\n";
+
+  fout<<"      <Option title=\"" << mf->GetProjectName()<<"\" />\n"
+        "      <Option makefile_is_custom=\"1\" />\n"
+        "      <Option compiler=\"gcc\" />\n"
+        "      <Build>\n";
+
+  bool installTargetCreated = false;
+  bool testTargetCreated = false;
+  bool packageTargetCreated = false;
+  
+  for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
+       lg!=lgs.end(); lg++)
+    {
+    cmMakefile* makefile=(*lg)->GetMakefile();
+    cmTargets& targets=makefile->GetTargets();
+    for (cmTargets::iterator ti = targets.begin();
+         ti != targets.end(); ti++)
+      {
+        switch(ti->second.GetType())
+        {
+          case cmTarget::GLOBAL_TARGET:
+            if ((ti->first=="install") && (installTargetCreated==false)) 
+            {
+              installTargetCreated=true;
+            }
+            else if ((ti->first=="package") && (packageTargetCreated==false)) 
+            {
+              packageTargetCreated=true;
+            }
+            else if ((ti->first=="test") && (testTargetCreated==false)) 
+            {
+              testTargetCreated=true;
+            }
+            else
+            {
+              break;
+            }
+          case cmTarget::EXECUTABLE:
+          case cmTarget::STATIC_LIBRARY:
+          case cmTarget::SHARED_LIBRARY:
+          case cmTarget::MODULE_LIBRARY:
+//          case cmTarget::UTILITY:
+  fout<<"      <Target title=\""<<ti->first<<"\">\n"
+        "         <Option output=\""<<ti->second.GetLocation(0)<<"\" prefix_auto=\"0\" extension_auto=\"0\" />\n"
+        "         <Option working_dir=\""<<makefile->GetStartOutputDirectory()<<"\" />\n"
+        "         <Option type=\"0\" />\n"
+        "         <Option compiler=\"gcc\" />\n"
+        "         <MakeCommands>\n";
+
+  fout<<"            <Build command=\""<<make<<" -f "<<makefile->GetStartOutputDirectory()<<"/Makefile "<<ti->first<<"\" />\n";
+  fout<<"            <CompileFile command=\""<<make<<" -f "<<makefile->GetStartOutputDirectory()<<"/Makefile "<<ti->first<<"\" />\n";
+  fout<<"            <Clean command=\""<<make<<" -f "<<makefile->GetStartOutputDirectory()<<"/Makefile clean\" />\n";
+  fout<<"            <DistClean command=\""<<make<<" -f "<<makefile->GetStartOutputDirectory()<<"/Makefile clean\" />\n";
+
+  fout<<"         </MakeCommands>\n"
+        "      </Target>\n";
+//  if (ti->second.GetType()==cmTarget::UTILITY) fout<<"****** UTILITY \n";
+//  if (ti->second.GetType()==cmTarget::GLOBAL_TARGET) fout<<"****** GLOBAL_YESTERDAY \n";
+            break;
+          default:
+            break;
+        }
+      }
+    }
+
+  fout<<"      </Build>\n";
+
+  
+  std::map<std::string, std::string> sourceFiles;
+  for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
+       lg!=lgs.end(); lg++)
+  {
+    cmMakefile* makefile=(*lg)->GetMakefile();
+    cmTargets& targets=makefile->GetTargets();
+    for (cmTargets::iterator ti = targets.begin();
+         ti != targets.end(); ti++)
+    {
+      switch(ti->second.GetType())
+      {
+        case cmTarget::EXECUTABLE:
+        case cmTarget::STATIC_LIBRARY:
+        case cmTarget::SHARED_LIBRARY:
+        case cmTarget::MODULE_LIBRARY:
+        {
+          const std::vector<cmSourceFile*>& sources=ti->second.GetSourceFiles();
+          for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
+               si!=sources.end(); si++)
+          {
+            sourceFiles[(*si)->GetFullPath()] = ti->first;
+          }
+        }
+        default:
+          break;
+      }
+    }
+  }
+  
+  for (std::map<std::string, std::string>::const_iterator sit=sourceFiles.begin();
+       sit!=sourceFiles.end();
+       ++sit)
+  {
+  fout<<"      <Unit filename=\""<<sit->first <<"\">\n";
+  fout<<"      </Unit>\n";
+  }
+  
+  fout<<"   </Project>\n"
+        "</CodeBlocks_project_file>\n";
+
+}
+

+ 63 - 0
Source/cmExtraCodeBlocksGenerator.h

@@ -0,0 +1,63 @@
+/*=========================================================================
+
+  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, [email protected]. 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 cmExtraCodeBlocksGenerator_h
+#define cmExtraCodeBlocksGenerator_h
+
+#include "cmExternalMakefileProjectGenerator.h"
+
+class cmLocalGenerator;
+class cmMakefile;
+
+/** \class cmExtraCodeBlocksGenerator
+ * \brief Write CodeBlocks project files for Makefile based projects
+ *
+ * This generator is in early alpha stage.
+ */
+class cmExtraCodeBlocksGenerator : public cmExternalMakefileProjectGenerator
+{
+public:
+  cmExtraCodeBlocksGenerator();
+  virtual void SetGlobalGenerator(cmGlobalGenerator* generator);
+
+  virtual const char* GetName() const
+                          { return cmExtraCodeBlocksGenerator::GetActualName();}
+  static const char* GetActualName()                     { return "CodeBlocks";}
+  static cmExternalMakefileProjectGenerator* New() 
+                                      { return new cmExtraCodeBlocksGenerator; }
+  /** Get the documentation entry for this generator.  */
+  virtual void GetDocumentation(cmDocumentationEntry& entry, 
+                                const char* fullName) const;
+
+  virtual void Generate();
+private:
+
+  /** 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::vector<cmLocalGenerator*>& lgs);
+
+  ///! Creates a new foo.kdevelop and a new foo.kdevses file
+  void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
+                                const std::string& filename);
+
+};
+
+#endif

+ 3 - 0
Source/cmake.cxx

@@ -72,6 +72,7 @@
 
 
 #ifdef CMAKE_USE_KDEVELOP
 #ifdef CMAKE_USE_KDEVELOP
 # include "cmGlobalKdevelopGenerator.h"
 # include "cmGlobalKdevelopGenerator.h"
+# include "cmExtraCodeBlocksGenerator.h"
 #endif
 #endif
 
 
 #include <stdlib.h> // required for atoi
 #include <stdlib.h> // required for atoi
@@ -1447,6 +1448,8 @@ void cmake::AddDefaultExtraGenerators()
 #endif
 #endif
 // e.g. eclipse ?
 // e.g. eclipse ?
 #ifdef CMAKE_USE_KDEVELOP
 #ifdef CMAKE_USE_KDEVELOP
+  this->AddExtraGenerator(cmExtraCodeBlocksGenerator::GetActualName(), 
+                          &cmExtraCodeBlocksGenerator::New);
   this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(), 
   this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(), 
                           &cmGlobalKdevelopGenerator::New);
                           &cmGlobalKdevelopGenerator::New);
   // for kdevelop also add the generator with just the name of the 
   // for kdevelop also add the generator with just the name of the