Dear CMake developers,

I wanted to know if it is possible to let CMake generate a project that uses 
the internal build system of the Code::Blocks IDE.
My motivation for this was that a friend of mine, who works together with me 
on different projects that use CMake, uses Code::Blocks for years. He tried 
CMake's Code::Blocks generator with Makefiles several times and has never been 
satisfied (parallel builds not working, stopping of build not working, slow 
make on Windows etc.). He ended up creating a Code::Blocks project manually.
I have written a number of hacks that modify the existing Code::Blocks 
generator to generate a project that does not use the generated Makefile, but 
the build system of Code::Blocks instead. I do not intend to push these 
patches, they were only ment as a proof-of-concept implementation. With these 
patches applied I am able to build several of our projects (shared libraries, 
dependencies on external libraries, applications using them) with the 
generated Code::Blocks project.
My questions to you are:
1. Is the CMake community interested in a project generator for CMake that 
generates native Code::Blocks projects? If you say that this is something that 
you do not want to have, I will stop my work and give my friend a custom CMake 
build containing my hacks. If you are nothing loath to have such generator, I 
want to try to find a way to do it right and prepare a topic branch.
2. What would be the right way to write such a generator? I think modifying 
the cmExtraCodeBlocksGenerator class is not the right way. Maybe one would 
have to write a new subclass of cmGlobalGenerator?

Kind regards
Benjamin
From 38a1e84b3719192f4f28f4c72da5ae39430812ca Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Sun, 2 Sep 2012 16:31:55 +0200
Subject: [PATCH 1/9] Dirty hack to use Code::Blocks internal builder without
 a need for a Makefile

---
 Source/cmExtraCodeBlocksGenerator.cxx |   35 ++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index ad4ab76..419e9b7 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -315,7 +315,7 @@ void cmExtraCodeBlocksGenerator
         "   <FileVersion major=\"1\" minor=\"6\" />\n"
         "   <Project>\n"
         "      <Option title=\"" << mf->GetProjectName()<<"\" />\n"
-        "      <Option makefile_is_custom=\"1\" />\n"
+        "      <Option makefile_is_custom=\"0\" />\n"
         "      <Option compiler=\"" << compiler << "\" />\n"
         "      "<<virtualFolders<<"\n"
         "      <Build>\n";
@@ -632,6 +632,39 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
         fout <<"            <Add option=\"-D" << safedef.str() << "\" />\n";
         }
       }
+    const char* cflags = target->GetProperty("COMPILE_FLAGS");
+    if(cflags)
+      {
+          // Expand the list.
+      std::vector<std::string> flags;
+      cmSystemTools::ExpandListArgument(cflags, flags);
+      for(std::vector<std::string>::const_iterator fi = flags.begin();
+          fi != flags.end(); ++fi)
+        {
+        cmXMLSafe safeflag(fi->c_str());
+        fout <<"            <Add option=\"" << safeflag.str() << "\" />\n";
+        }
+      }
+
+    std::string sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_CXX_FLAGS";
+    if (this->GlobalGenerator->GetLanguageEnabled("CXX") == false)
+      {
+        sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_C_FLAGS";
+      }
+    const char* sldefs = target->GetMakefile()->GetSafeDefinition(
+                                             "CMAKE_SHARED_LIBRARY_CXX_FLAGS");
+    if(sldefs)
+      {
+      // Expand the list.
+      std::vector<std::string> defs;
+      cmSystemTools::ExpandListArgument(sldefs, defs);
+      for(std::vector<std::string>::const_iterator di = defs.begin();
+          di != defs.end(); ++di)
+        {
+        cmXMLSafe safedef(di->c_str());
+        fout <<"            <Add option=\"" << safedef.str() << "\" />\n";
+        }
+      }
 
       // the include directories for this target
       std::set<std::string> uniqIncludeDirs;
-- 
1.7.10.4

From 54def9141a6477d65e49ed81fb20b7ce930dc467 Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Tue, 4 Sep 2012 18:23:06 +0200
Subject: [PATCH 2/9] Build a virtual target "All" referencing all other
 targets built

---
 Source/cmExtraCodeBlocksGenerator.cxx |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 419e9b7..d4ecae5 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -322,6 +322,7 @@ void cmExtraCodeBlocksGenerator
 
   this->AppendTarget(fout, "all", 0, make.c_str(), mf, compiler.c_str());
 
+  std::vector<std::string> virtualTargetDeps;
   // add all executable and library targets and some of the GLOBAL
   // and UTILITY targets
   for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
@@ -388,6 +389,7 @@ void cmExtraCodeBlocksGenerator
           {
           this->AppendTarget(fout, ti->first.c_str(), &ti->second,
                              make.c_str(), makefile, compiler.c_str());
+          virtualTargetDeps.push_back(ti->first);
           std::string fastTarget = ti->first;
           fastTarget += "/fast";
           this->AppendTarget(fout, fastTarget.c_str(), &ti->second,
@@ -402,6 +404,15 @@ void cmExtraCodeBlocksGenerator
 
   fout<<"      </Build>\n";
 
+  fout<<"      <VirtualTargets>\n";
+  fout<<"         <Add alias=\"All\" targets=\"";
+  for (std::vector<std::string>::const_iterator dep=virtualTargetDeps.begin();
+       dep!=virtualTargetDeps.end(); ++dep)
+    {
+    fout<< *dep <<';';
+    }
+  fout<<"\" />\n";
+  fout<<"      </VirtualTargets>\n";
 
   // Collect all used source files in the project
   // Sort them into two containers, one for C/C++ implementation files
-- 
1.7.10.4

From 2b4a1d3fe0fdc2ecf330849c342728c48fce50bb Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Sun, 2 Sep 2012 17:21:55 +0200
Subject: [PATCH 3/9] Always run CMake as pre-build step

---
 Source/cmExtraCodeBlocksGenerator.cxx |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index d4ecae5..fa50797 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -413,6 +413,16 @@ void cmExtraCodeBlocksGenerator
     }
   fout<<"\" />\n";
   fout<<"      </VirtualTargets>\n";
+  // Make sure CMake is run as pre-build step.
+  const char* cmakeCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
+  fout<<"      <ExtraCommands>\n"
+        "         <Add before=\""
+      << cmakeCommand << " chdir " << mf->GetHomeOutputDirectory()
+      <<" &amp;&amp; "
+      << cmakeCommand << ' ' << mf->GetHomeDirectory() << "\" />\n"
+        "         <Mode after=\"always\" />\n"
+        "      </ExtraCommands>\n";
+
 
   // Collect all used source files in the project
   // Sort them into two containers, one for C/C++ implementation files
-- 
1.7.10.4

From 60fa46fda404a6194331c591f9fd6d19206072ea Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Tue, 4 Sep 2012 18:51:26 +0200
Subject: [PATCH 4/9] Do not generate "all", global and "/fast" targets

---
 Source/cmExtraCodeBlocksGenerator.cxx |   38 ---------------------------------
 1 file changed, 38 deletions(-)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index fa50797..e7f8d79 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -320,8 +320,6 @@ void cmExtraCodeBlocksGenerator
         "      "<<virtualFolders<<"\n"
         "      <Build>\n";
 
-  this->AppendTarget(fout, "all", 0, make.c_str(), mf, compiler.c_str());
-
   std::vector<std::string> virtualTargetDeps;
   // add all executable and library targets and some of the GLOBAL
   // and UTILITY targets
@@ -335,38 +333,6 @@ void cmExtraCodeBlocksGenerator
       {
       switch(ti->second.GetType())
         {
-        case cmTarget::GLOBAL_TARGET:
-          {
-          bool insertTarget = false;
-          // Only add the global targets from CMAKE_BINARY_DIR,
-          // not from the subdirs
-          if (strcmp(makefile->GetStartOutputDirectory(),
-                     makefile->GetHomeOutputDirectory())==0)
-            {
-            insertTarget = true;
-            // only add the "edit_cache" target if it's not ccmake, because
-            // this will not work within the IDE
-            if (ti->first == "edit_cache")
-              {
-              const char* editCommand = makefile->GetDefinition
-                                                        ("CMAKE_EDIT_COMMAND");
-              if (editCommand == 0)
-                {
-                insertTarget = false;
-                }
-              else if (strstr(editCommand, "ccmake")!=NULL)
-                {
-                insertTarget = false;
-                }
-              }
-            }
-          if (insertTarget)
-            {
-            this->AppendTarget(fout, ti->first.c_str(), 0,
-                               make.c_str(), makefile, compiler.c_str());
-            }
-          }
-          break;
         case cmTarget::UTILITY:
           // Add all utility targets, except the Nightly/Continuous/
           // Experimental-"sub"targets as e.g. NightlyStart
@@ -390,10 +356,6 @@ void cmExtraCodeBlocksGenerator
           this->AppendTarget(fout, ti->first.c_str(), &ti->second,
                              make.c_str(), makefile, compiler.c_str());
           virtualTargetDeps.push_back(ti->first);
-          std::string fastTarget = ti->first;
-          fastTarget += "/fast";
-          this->AppendTarget(fout, fastTarget.c_str(), &ti->second,
-                             make.c_str(), makefile, compiler.c_str());
           }
           break;
         default:
-- 
1.7.10.4

From dfde44208318340722e4065bf32b2a9f57af8871 Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Tue, 4 Sep 2012 18:56:56 +0200
Subject: [PATCH 5/9] Do not create "<MakeCommands>"

---
 Source/cmExtraCodeBlocksGenerator.cxx |   16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index e7f8d79..1ce688a 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -706,21 +706,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
         <<"         <Option type=\"" << 4 << "\" />\n";
     }
 
-  fout<<"         <MakeCommands>\n"
-        "            <Build command=\""
-      << this->BuildMakeCommand(make, makefileName.c_str(), targetName)
-      << "\" />\n"
-        "            <CompileFile command=\""
-      << this->BuildMakeCommand(make, makefileName.c_str(),"&quot;$file&quot;")
-      << "\" />\n"
-        "            <Clean command=\""
-      << this->BuildMakeCommand(make, makefileName.c_str(), "clean")
-      << "\" />\n"
-        "            <DistClean command=\""
-      << this->BuildMakeCommand(make, makefileName.c_str(), "clean")
-      << "\" />\n"
-        "         </MakeCommands>\n"
-        "      </Target>\n";
+  fout<<"      </Target>\n";
 
 }
 
-- 
1.7.10.4

From 48c9f062b720fcbdee5ff4b9748ceca6a43aa312 Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Tue, 4 Sep 2012 22:02:01 +0200
Subject: [PATCH 6/9] Add link dependencies (targets or external libs)

---
 Source/cmExtraCodeBlocksGenerator.cxx |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 1ce688a..073ae5c 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -706,6 +706,29 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
         <<"         <Option type=\"" << 4 << "\" />\n";
     }
 
+  // Add link dependencies
+  const std::vector<std::string> & linkDeps =
+                                  target->GetLinkImplementation("")->Libraries;
+  if (!linkDeps.empty())
+    {
+    fout<<"         <Linker>\n";
+    for (std::vector<std::string>::const_iterator dep = linkDeps.begin();
+         dep != linkDeps.end(); ++dep)
+      {
+      cmTarget * depTarget =
+             const_cast<cmMakefile *>(makefile)->FindTargetToUse(dep->c_str());
+      if (depTarget)
+        {
+        const std::string fullPath = depTarget->GetFullPath();
+        const std::size_t lastSlash = fullPath.find_last_of('/');
+        fout<<"            <Add directory=\""
+            << fullPath.substr(0, lastSlash) <<"\" />\n";
+        }
+      fout<<"            <Add library=\""<< *dep <<"\" />\n";
+      }
+    fout<<"         </Linker>\n";
+    }
+
   fout<<"      </Target>\n";
 
 }
-- 
1.7.10.4

From ff990798f1fd7bb5841979b195515360ec8b3896 Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Wed, 5 Sep 2012 13:34:44 +0200
Subject: [PATCH 7/9] Assign units to targets

---
 Source/cmExtraCodeBlocksGenerator.cxx |   30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 073ae5c..6b215e2 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -389,7 +389,7 @@ void cmExtraCodeBlocksGenerator
   // Collect all used source files in the project
   // Sort them into two containers, one for C/C++ implementation files
   // which may have an acompanying header, one for all other files
-  std::map<std::string, cmSourceFile*> cFiles;
+  std::map<std::string, std::deque<std::string> > cFiles;
   std::set<std::string> otherFiles;
   for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
        lg!=lgs.end(); lg++)
@@ -438,7 +438,19 @@ void cmExtraCodeBlocksGenerator
             // then put it accordingly into one of the two containers
             if (isCFile)
               {
-              cFiles[(*si)->GetFullPath()] = *si ;
+                const std::string fullPath = (*si)->GetFullPath();
+                std::map<std::string, std::deque<std::string> >::iterator cfe =
+                                              cFiles.find(fullPath);
+                if (cfe != cFiles.end())
+                  {
+                  cfe->second.push_back(ti->first);
+                  }
+                else
+                  {
+                  std::deque<std::string> newTargets;
+                  newTargets.push_back(ti->first);
+                  cFiles.insert(std::make_pair(fullPath, newTargets));
+                  }
               }
             else
               {
@@ -458,7 +470,7 @@ void cmExtraCodeBlocksGenerator
   // file exists. If it does, it is inserted into the map of files.
   // A very similar version of that code exists also in the kdevelop
   // project generator.
-  for (std::map<std::string, cmSourceFile*>::const_iterator
+  for (std::map<std::string, std::deque<std::string> >::const_iterator
        sit=cFiles.begin();
        sit!=cFiles.end();
        ++sit)
@@ -493,13 +505,19 @@ void cmExtraCodeBlocksGenerator
 
   // insert all source files in the CodeBlocks project
   // first the C/C++ implementation files, then all others
-  for (std::map<std::string, cmSourceFile*>::const_iterator
+  for (std::map<std::string, std::deque<std::string> >::const_iterator
        sit=cFiles.begin();
        sit!=cFiles.end();
        ++sit)
     {
-    fout<<"      <Unit filename=\""<< sit->first <<"\">\n"
-          "      </Unit>\n";
+    fout<<"      <Unit filename=\""<< sit->first <<"\">\n";
+    for (std::deque<std::string>::const_iterator taIt = sit->second.begin();
+         taIt != sit->second.end();
+         ++taIt)
+      {
+      fout<<"         <Option target=\""<< *taIt <<"\" />\n";
+      }
+    fout<<"      </Unit>\n";
     }
   for (std::set<std::string>::const_iterator
        sit=otherFiles.begin();
-- 
1.7.10.4

From b335da1850607c7ff50a84f0f696ce6efdb489b2 Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Wed, 5 Sep 2012 13:59:57 +0200
Subject: [PATCH 8/9] Add COMPILE_DEFINITIONS for the target

---
 Source/cmExtraCodeBlocksGenerator.cxx |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 6b215e2..fb0a2e8 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -633,6 +633,20 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
         fout <<"            <Add option=\"-D" << safedef.str() << "\" />\n";
         }
       }
+    // the compilerdefines for this target
+    const char* cdefs2 = target->GetProperty("COMPILE_DEFINITIONS");
+    if(cdefs2)
+      {
+      // Expand the list.
+      std::vector<std::string> defs;
+      cmSystemTools::ExpandListArgument(cdefs2, defs);
+      for(std::vector<std::string>::const_iterator di = defs.begin();
+          di != defs.end(); ++di)
+        {
+        cmXMLSafe safedef(di->c_str());
+        fout <<"            <Add option=\"-D" << safedef.str() << "\" />\n";
+        }
+      }
     const char* cflags = target->GetProperty("COMPILE_FLAGS");
     if(cflags)
       {
-- 
1.7.10.4

From 094126809f6e53b3d18d94fca968995821abcc45 Mon Sep 17 00:00:00 2001
From: Benjamin Eikel <cm...@eikel.org>
Date: Wed, 5 Sep 2012 16:53:18 +0200
Subject: [PATCH 9/9] Remove "-l" at beginning of link dependencies

---
 Source/cmExtraCodeBlocksGenerator.cxx |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index fb0a2e8..4f37e49 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -747,6 +747,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
     for (std::vector<std::string>::const_iterator dep = linkDeps.begin();
          dep != linkDeps.end(); ++dep)
       {
+      std::string depName = *dep;
       cmTarget * depTarget =
              const_cast<cmMakefile *>(makefile)->FindTargetToUse(dep->c_str());
       if (depTarget)
@@ -756,7 +757,11 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
         fout<<"            <Add directory=\""
             << fullPath.substr(0, lastSlash) <<"\" />\n";
         }
-      fout<<"            <Add library=\""<< *dep <<"\" />\n";
+      if (depName.substr(0, 2) == "-l")
+        {
+          depName = depName.substr(2);
+        }
+      fout<<"            <Add library=\""<< depName <<"\" />\n";
       }
     fout<<"         </Linker>\n";
     }
-- 
1.7.10.4

--

Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers

Reply via email to