Hi,
I thought I would do a small update on the way Code::Blocks can be configured to build the same software using different operating systems and compilers, and also different versions of wxWidgets, without changing anything in the project setup.
In the examples below, I am able to build using MSVC 2010 (express of full version) on Windows and GCC on Linux, using the same project files. One can also switch between wxWidgets 2.8.12 and wxWidgets 3.0.0 easily.
To achieve this, I use the 'backticks' facility that is supported in Code::Blocks, and use two different versions of wx-config to provide compiler settings and wx libraries. On Linux, it is the standard wx-config that comes with wxWidgets, and on Windows I use a modified version of a Windows-port of wx-config. The wx-config programs serve the same purpose, but they take different parameters.
The second feature that is important is Code::Blocks global variables. On both Windows and Linux I use a global variable 'wx' with a BASE member that points to the wxWidgets installation. As I build wxWidgets (as static libraries) myself, this means that, on Linux, the 'wx' global variable points to /usr/local. On Windows this is a bit different, as the 'wx' variable points to the root of the wxWidgets 2.8.12 installation or wxWidgets 3.0.0, depending on what I am using at the moment. Since I am using the MSVC compiler on Windows, I get
vc_lib\mswd and
vc_lib\msw subfolders under 'lib' for debug and release (ANSI) under 2.8.12. Under 3.0.0 I am using unicode builds, so in that case the subfolders become
vc_lib\mswud and
vc_lib\msuw instead.
I found it convenient to define two user defined fields ('debug' and 'release') for the 'wx' global variable under Windows, and assign the subfolder paths as mentioned above.
Windows (MSVC)For wxWidgets 2.8.12, my Windows 'wx' global variable is defined as shown in msw28.gif.
For wxWidgets 3.0.0, my Windows 'wx' global variable is defined as shown in msw30.gif, notice the base path and unicode options.
Given these settings, I can define a Windows msvc debug target as follows
<Target title="MSVC_Debug">
<Option output=".cmp/msvc/bin/Debug/myprogd" prefix_auto="0" extension_auto="1" />
<Option object_output=".cmp/msvc/obj/Debug/" />
<Option type="0" />
<Option compiler="msvc" />
<Option projectLinkerOptionsRelation="2" />
<Compiler>
<Add option="/MDd" />
<Add option="/Od" />
<Add option="/RTCsu" />
<Add option="/GF" />
<Add option="/EHsc" />
<Add option="/W3" />
<Add option="`wx-config.exe --prefix=$(#wx) --wxcfg=$(#wx.debug) --cxxflags`" />
<Add option="/Fd$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).pdb" />
<Add option="/D_CRT_SECURE_NO_WARNINGS" />
<Add option="/D_CRT_NONSTDC_NO_DEPRECATE" />
<Add option="/D_CRT_SECURE_DEPRECATE" />
</Compiler>
<ResourceCompiler>
<Add directory="$(#wx)/include" />
</ResourceCompiler>
<Linker>
<Add option="`wx-config.exe --prefix=$(#wx) --wxcfg=$(#wx.debug) --libs`" />
<Add option="/SUBSYSTEM:WINDOWS" />
<Add option="/NODEFAULTLIB:libcmt.lib" />
<Add option="/NODEFAULTLIB:msvcrt.lib" />
<Add option="/INCREMENTAL:NO" />
<Add library="msvcrtd.lib" />
</Linker>
</Target>
Similarly, a release target for Windows msvc
<Target title="MSVC_Release">
<Option output=".cmp/msvc/bin/Release/myprog" prefix_auto="0" extension_auto="1" />
<Option object_output=".cmp/msvc/obj/Release/" />
<Option type="0" />
<Option compiler="msvc" />
<Option projectLinkerOptionsRelation="2" />
<Compiler>
<Add option="/MD" />
<Add option="/GF" />
<Add option="/Ox" />
<Add option="/W3" />
<Add option="/EHsc" />
<Add option="`wx-config.exe --prefix=$(#wx) --wxcfg=$(#wx.release) --cxxflags`" />
<Add option="/D_CRT_SECURE_NO_WARNINGS" />
<Add option="/D_CRT_NONSTDC_NO_DEPRECATE" />
<Add option="/D_CRT_SECURE_DEPRECATE" />
</Compiler>
<ResourceCompiler>
<Add directory="$(#wx)/include" />
</ResourceCompiler>
<Linker>
<Add option="`wx-config.exe --prefix=$(#wx) --wxcfg=$(#wx.release) --libs`" />
<Add option="/SUBSYSTEM:WINDOWS" />
<Add option="/NODEFAULTLIB:libcmtd.lib" />
<Add option="/NODEFAULTLIB:msvcrtd.lib" />
<Add option="/INCREMENTAL:NO" />
<Add library="msvcrt.lib" />
</Linker>
<ExtraCommands>
<Add after="mt.exe /nologo /manifest $(TARGET_OUTPUT_FILE).manifest /outputresource:$(TARGET_OUTPUT_FILE);1" />
<Add after="$(CPDE_USR)\bin\cpde_usr -bin -xi -project=$(PROJECT_NAME) -root=$(PROJECT_DIR) -build=$(TARGET_NAME) -target=$(TARGET_OUTPUT_FILE) -usr=$(CPDE_USR)" />
</ExtraCommands>
</Target>
LinuxOn Linux the wx-config program is a bit different from the Windows port, so the definition of the 'wx' variable is also a bit different from Windows. Instead of 'debug' and 'release' user defined fields, I define just a single 'config' field wich has a definition that ensures the proper wx-config is run, plus it sets the option for using wx2.8 or wx3.0 (since thebase path is the same for both in this case). Debug or release options are instead 'hard-coded' in their respective targets as shown below. Notice I build unicode for both 2.8.12 and 3.0.0 under Linux.
For wxWidgets 2.8.12, my Linux 'wx' global variable is defined as shown in gtk28.gif (see next post)
For wxWidgets 2.8.12, my Linux 'wx' global variable is defined as shown in gtk30.gif (see next post)
Given these settings, I can define a Linux gcc debug target as follows
<Target title="GCC_Debug">
<Option output=".cmp/gcc/bin/Debug/myprog" prefix_auto="0" extension_auto="1" />
<Option object_output=".cmp/gcc/obj/Debug/" />
<Option type="0" />
<Option compiler="gcc" />
<Option projectLinkerOptionsRelation="2" />
<Compiler>
<Add option="-std=c++0x" />
<Add option="-g" />
<Add option="-W" />
<Add option="-fPIC" />
<Add option="-fexceptions" />
<Add option="`$(#wx.config) --cxxflags --debug`" />
<Add option="-DNOPCH" />
<Add option="-D_DEBUG" />
</Compiler>
<Linker>
<Add option="`$(#wx.config) --libs std,aui --static --debug`" />
</Linker>
</Target>
Similarly, a release target for Linux gcc
<Target title="GCC_Release">
<Option output=".cmp/gcc/bin/Release/myprog" prefix_auto="0" extension_auto="1" />
<Option object_output=".cmp/gcc/obj/Release/" />
<Option type="0" />
<Option compiler="gcc" />
<Option projectLinkerOptionsRelation="2" />
<Compiler>
<Add option="-Os" />
<Add option="-std=c++0x" />
<Add option="-W" />
<Add option="-fPIC" />
<Add option="-fexceptions" />
<Add option="`$(#wx.config) --cxxflags`" />
<Add option="-DNOPCH" />
</Compiler>
<Linker>
<Add option="-s" />
<Add option="`$(#wx.config) --libs std,aui --static`" />
</Linker>
<ExtraCommands>
<Add before="rm -f $(TARGET_OUTPUT_FILE)" />
<Add after="upx $(TARGET_OUTPUT_FILE)" />
<Add after="$(CPDE_USR)/bin/cpde_usr -bin -xi -project=$(PROJECT_NAME) -root=$(PROJECT_DIR) -build=$(TARGET_NAME) -target=$(TARGET_OUTPUT_FILE) -usr=$(CPDE_USR)" />
<Mode after="always" />
</ExtraCommands>
</Target>
In the above, I have removed some other (private) libraries that I am using, these examples are meant as illustration of settings relevant for the configuration of wxWidgets. It is worth observing that it is very nice that global variables may be evaluated within the backtics area, the last time I tried it (some years ago) it wasn't available.
Finally, it should be noted that the different values for the global variables are stored in different Sets in the global variable editor. To switch between wxWidgets 2.8 and 3.0, all I have to do is switch the current global variable set. It is easy to get confused here, so perhaps the name of the global variable set could be prominently visible somewhere (in the main windows header or status bar perhaps?).
In experimenting with these things, I experienced quite a few code::block crashes, and I learned that project settings are never saved until you exit Code::Bloks, so you lose the settings if you suffer a crash. It would be nice to have some feature wich actually did save everything without requiring a complete exit/restart of Code::Blocks.
Another thing I noticed (on a relatively slow XP computer running nightly build 9455), was that when you load a workspace with several projects after switching the global variable current set, a 'massive' reparsing of the files takes place and the IDE spends 15-20 seconds processing heavily. If you don't lay off the mouse in this period, but try a 'rebuild all' for example, you are almost certain to suffer either an immediate crash or an infinite hang (thread race condition?) that must be killed in Task Manager.
Still, whith these minor issues, Code::Blocks is extremely configurable and nice to work with-