Creating Portable Version of Code::Blocks

April 5th, 2009

Recently I was irritated by the fact that Code::Blocks is not truly portable on Windows. Usually I keep two versions of Code::Blocks in my PC. One is the last released nightly and the other one is the one that I build from trunk. I use last released nightly to write code. However as Code::Blocks is not truly portable, these two versions of Code::Blocks share same configuration file.  Sometimes I run my newly built Code::Blocks from trunk, it crashes and corrupts my customised configuration file. And this irritates me a lot.

Other than this, you really can’t copy your configuration folder in a portable drive and expect entire Code::Blocks installation to behave as a truly portable software. There is one way; using personality feature of Code::Blocks. but that solves only one half of the problem. Yes, this makes your Code::Blocks portable. But your plugins are not! They still read their own settings from the default folder which is %APPDATA%\CodeBlocks folder.

So I started to investigate it. To give you a peek of Code::Blocks internals, ConfigManager uses wxStandardPathsBase::Get().GetUserConfigDir() to determine it’s configuration directory. wxWidgets internally uses SHGetFolderPath() function to resolve this call. This function call has higher precedence over environment variables. Thus if you try to set APPDATA before launching Code::Blocks it has no effects.

Now coming to a solution (you may call it a hack, too!), following patch fixes this issue. It reads APPDATA Environment variable first. If it fails to do so, it falls back to wxWidgets based implementation. In this way you can temporarily set APPDATA variable before launching Code::Blocks. You can point to any directory using APPDATA variable and Code::Blocks will use it to save settings.

Index: src/sdk/configmanager.cpp
===================================================================
--- src/sdk/configmanager.cpp	(revision 5519)
+++ src/sdk/configmanager.cpp	(working copy)
@@ -60,6 +60,23 @@
 wxString ConfigManager::temp_folder;
 bool ConfigManager::relo = 0;
 
+#ifdef __WINDOWS__
+wxString GetPortableConfigDir()
+{
+    DWORD bufLen = 32780;
+    TCHAR buffer[32780];
+    int ret = GetEnvironmentVariable(_T("APPDATA"), buffer, bufLen);
+    if (ret == 0)
+    {
+        return wxStandardPathsBase::Get().GetUserDataDir();
+    }
+    else
+    {
+        return wxString::Format(_T("%s\\codeblocks"), buffer);
+    }
+}
+#endif
+
 namespace CfgMgrConsts
 {
     const wxString app_path(_T("app_path"));
@@ -172,7 +189,11 @@
 
     if(cfg.IsEmpty())
     {
+        #ifdef __WINDOWS__
+        cfg = GetPortableConfigDir() + wxFILE_SEP_PATH + personality + _T(".conf");
+        #else
         cfg = wxStandardPathsBase::Get().GetUserDataDir() + wxFILE_SEP_PATH + personality + _T(".conf");
+        #endif
         doc = new TiXmlDocument();
         doc->InsertEndChild(TiXmlDeclaration("1.0", "UTF-8", "yes"));
         doc->InsertEndChild(TiXmlElement("CodeBlocksConfig"));
@@ -187,7 +208,11 @@
 {
     wxPathList searchPaths;
 
+#ifdef __WINDOWS__
+    wxString u(GetPortableConfigDir() + wxFILE_SEP_PATH + filename);
+#else
     wxString u(wxStandardPathsBase::Get().GetUserDataDir() + wxFILE_SEP_PATH + filename);
+#endif
     wxString e(::DetermineExecutablePath() + wxFILE_SEP_PATH +filename);
 
     if(::wxFileExists(u))
@@ -1369,7 +1394,11 @@
 
 void ConfigManager::InitPaths()
 {
+#ifdef __WINDOWS__
+    ConfigManager::config_folder = GetPortableConfigDir();
+#else
     ConfigManager::config_folder = wxStandardPathsBase::Get().GetUserDataDir();
+#endif
     ConfigManager::home_folder = wxStandardPathsBase::Get().GetUserConfigDir();
     ConfigManager::app_path = ::DetermineExecutablePath();
     wxString res_path = ::DetermineResourcesPath();

So far the result is good enough. Core code::Blocks is portable. I’ve checked few plugins. They are now portable too. I’ve written a small launcher. This launcher will run Code::Blocks from the local directory. An AppData folder will be created which Code::Blocks will use to save it’s settings.

Please note following points.

  1. Patch is meant for Windows only.
  2. Patch is made against latest svn revision. Patch may not work with 8.02 release.
  3. A launcher is made available to launch Code::Blocks in a portable way.

Portable Code::Blocks Launcher Source & Binary Download link: cblauncher-v0_1

Have fun!

2 Responses to “Creating Portable Version of Code::Blocks”

  1. codeMesh84on 27 Aug 2009 at 10:01 pm

    Hi!

    I’m a newbie to linux packages. I’m just trying to learn how to install codeblock by compiling it on my toshiba notebook(cor2duo processor).

    i downloaded the source package, extracted and issued follwing commands…(from the source root dir)

    mkdir mybld
    cd mybld
    ../configure –enable-contrib
    make

    it compiles the code for some time and bangs with the follwoing error…

    In file included from ../../../src/sdk/configmanager-revision.cpp:22:
    ../../src/include/autorevision.h:15: error: expected primary-expression before ‘;’ token
    make[3]: *** [configmanager-revision.lo] Error 1
    make[3]: Leaving directory `/home/mesh/codeblocks-8.02/mybld/src/sdk’
    make[2]: *** [all-recursive] Error 1
    make[2]: Leaving directory `/home/mesh/codeblocks-8.02/mybld/src/sdk’
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/home/mesh/codeblocks-8.02/mybld/src’
    make: *** [all-recursive] Error 1

    did i miss anything?? need ur help…

  2. adminon 28 Aug 2009 at 5:33 am

    You missed wxGTK-devel packages. Install them and then start compiling C::B. Note that naming of wxGTK-devel package may vary depending upon your distro.

Trackback URI | Comments RSS

Leave a Reply