CodeBlock速配wxWidgets
- Markdown 版起稿时间 2/1/2016 4:15:45 AM by Jimbowhy
- 优快云发布地址:http://blog.youkuaiyun.com/WinsenJiansbomber/article/details/50616754
- 本文更新版本:http://blog.youkuaiyun.com/winsenjiansbomber/article/details/50629635
使用软件版本:
- CodeBlocks 10.05 自带 mingw32-g++.exe (TDM-2 mingw32) 4.4.1
- CodeBlocks 12.13 自带 mingw32-g++.exe (TDM-2 mingw32) 4.8.1
- wxPack_v2.8.7.exe GCC编译版本未知,此包安装后占用空间明显比2.8.12要大(3.10G>1.45G)
- wxPack_v2.8.12.01.exe 由GCC 4.4.1 编译
- wxMSW-3.0.2_gcc471TDM_Dev.7z + wxWidgets-3.0.2_headers.7z
- tdm-gcc 各个实测版本
- Windows 7 x64 on AMD CPU
动态编译
下载好各版本的 wx 或者是 wxPack_v2.8.7.03,wxPack 包含的库文件较全,要正确编译工程,就需要设置定义以下编译选项,否则配置不正确,就算编译通过也无法运行:
<Add option="-DWXUSINGDLL" />
<Add option="-DwxUSE_UNICODE" />
这两个选项是对应工程向导中的 Use wxWidgets DLL 和 Enabled Unicode 两个选项。
静态编译和合集库
wxPack安装包含动态链接和静态链接两个版本的文件,lib目录下gcc_dll对应动态链接,gcc_lib对应静态连接,这个文件夹也是没有DLL文件的,需要在编译选项中设置好路径指向。gcc_lib目录下就有这四个文件,分別是Unicode和非U版的,特别大的文件:
libwxmswu.a 98MB
libwxmswud.a 99MB
libwxmsw.a 17MB
libwxmswd.a 17MB
编译wx时生成合集库文件,即 Monolithic Library,这也就是要求编译wx时必需指定MONOLITHIC=1,需要静态编译时要指定SHARED=0,这样才能进行静态链接的程序开发,例如:
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=0 UNICODE=1 BUILD=debug
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=0 UNICODE=1 BUILD=release
新建wx工程时,在向导界面设置 wxWidgets Library Setting 时,去掉 Use wxWidgets DLL 选项,而选择 Monolithic Library 选项。这样,工程才会以上面列出的链接库来生产程序。
实操测试
测试中发现 Codeblock 10.05 + wxPack_v2.8.12 搭配运行是较稳定的,亦即 g++ 4.4.1 及 g++ 4.5.0 和 wxPack v2.8的组合较好。CodeBlocks 12.13 则和 wxMSM 3.0 搭配使用较好。尽管如此,通过下面的两组测试数据,发现 wxWidgets 的源代码移植问题应该是比较多的,工程质量可能会大受影响。
以下是一组搭配动态链接测试数据:
组合 | g++ 4.4.1 | g++ 4.6.2 | g++ 4.7.1 | g++ 4.8.1 | g++ 4.9.2 | g++ 5.1.0 |
---|---|---|---|---|---|---|
wxMSW 3.0.2 | 1 | 1 | OK | 2 | OK #i | 3 |
wxMSW 3.0 | 8 | 7 | OK #ii | OK | 3 | 3 |
wxPack2.8.12 | OK | OK | 4 | 5 | 4 | 6 |
以下是一组搭配静态链接测试数据:
组合 | g++ 4.4.1 | g++ 4.6.2 | g++ 4.7.1 | g++ 4.8.1 | g++ 4.9.2 | g++ 5.1.0 |
---|---|---|---|---|---|---|
wxPack 2.8.7 | OK | 10 | 11 | 5 | 11 | 6 |
wxPack2.8.12 | 10 | OK i3 | 10 | 10 | 10 | 6 #10 |
#1 Error wxbase30u_gcc471TDM.dll 模块问题
#2 Error pthreadGC2.dll 模块的错误
#3 Error 编译错误过多
#4 Error wxbase28ud_gcc.dll模块异常;或 StackHash 模块错误。
#5 Error 正常编译,可以运行,但是进程为僵尸状态,不显示界面不提示错误。
#6 Error 编译错误,提示语法问题。
#7 Error wxbase30u_gcc481TDM.dll、wxbase30ud_gcc481TDM.dll 模块问题。
#8 Error wxbase30u_gcc481TDM.dll 或 程序自身模块问题不能运行,但编译通过无出错。
#9 Error 错误过多,基本是符号引用错误。
#10 Error 符号_Unwind_Resume引用问题,涉及异常处理,包含 libgcc_s.a 亦未解决。
#11 Error 程序自身模块问题不能运行,但编译通过无出错。
#i Info 使用 ISO C++ 2011 ,添加编译参数 -std=c++11 or -std=gnu++11。
#ii Info 编译通过,可以运行,但程序加载有明显延时。
#i3 Info 编译通过,按链接程序提示,添加了一系列系统库文件引用。但静态链接程序带调试文件巨大 30MB+,发行版则为可接受的2.38MB。
可能需要用到的系统库文件引用:
<Add library="libcomctl32.a" />
<Add library="libuuid.a" />
<Add library="libole32.a" />
<Add library="liboleaut32.a" />
<Add library="libwinspool.a" />
<Add library="libkernel32.a" />
<Add library="libuser32.a" />
<Add library="libgdi32.a" />
<Add library="libcomdlg32.a" />
<Add library="libadvapi32.a" />
<Add library="libshell32.a" />
<Add library="libwsock32.a" />
<Add library="libodbc32.a" />
而wx的库文件则有以下这些,其中 wxmswu 则为合集库文件:
<Add library="wxmswu" />
<Add library="wxbaseu" />
<Add library="wxmswu_core" />
<Add library="wxmswu_xrc" />
<Add library="wxmswu_richtext" />
<Add library="wxmswu_html" />
<Add library="wxmswu_aui" />
<Add library="wxbaseu_net" />
<Add library="wxmswu_media" />
<Add library="wxmswu_qa" />
<Add library="wxbaseu_odbc" />
<Add library="wxbaseu_xml" />
<Add library="wxmswu_dbgrid" />
<Add library="wxmswu_gl" />
<Add library="wxpng" />
<Add library="wxtiff" />
<Add library="wxjpeg" />
<Add library="wxexpat" />
<Add library="wxregex" />
<Add library="wxzlib" />
注意,静态编译时,一定要去掉编译参数 WXUSINGDLL。对于 g++ 4.7.1 以上版本没有成功进行静态编译的现象十分怪异,因为原因基本都是同样的符号引用问题:_Unwind_Resume
、__gxx_personality_v0
。推断它和g++升级后引入的功能有关,通常符号引用问题是可以通过引入正确的库文件解决的,这里引用以下库文件后,并未能解决问题。反而单独引入libgcc_s
时,会出现重复定义_Unwind_SjLj_Register
问题:
<Add library="libgcc_s.a" />
<Add library="libstdc++.a" />
<Add library="libgcc.a" />
这个问题是乎不修改原始代码就永远解决的的死胡同,还是用可用的编译器吧。另外,库文件夹下还有一个setup.h头文件,专门用在Win32平台下的,因此需要在编译器选项中添加上msw**
这个路径。这样,一个正常的静态编译工程配置文件看起来应该是这样的:
<Build>
<Target title="Debug">
<Option output="bin/overload" prefix_auto="1" extension_auto="1" />
<Option object_output="Debug/" />
<Option type="0" />
<Option compiler="gcc" />
<Option projectLinkerOptionsRelation="2" />
<Compiler>
<Add option="-g" />
<Add option="-D__WXDEBUG__" />
<Add directory="$(#wx281.libs)/mswud" />
</Compiler>
<Linker>
<Add library="wxmswud" />
<Add library="wxpngd" />
<Add library="wxtiffd" />
<Add library="wxjpegd" />
<Add library="wxexpatd" />
<Add library="wxregexd" />
<Add library="wxzlibd" />
</Linker>
</Target>
<Target title="Release">
<Option output="bin/overload" prefix_auto="1" extension_auto="1" />
<Option object_output="Release/" />
<Option type="0" />
<Option compiler="gcc" />
<Option projectLinkerOptionsRelation="2" />
<Compiler>
<Add option="-O2" />
<Add directory="$(#wx281.libs)/mswu" />
</Compiler>
<Linker>
<Add option="-s" />
<Add library="wxmswu" />
<Add library="wxpng" />
<Add library="wxtiff" />
<Add library="wxjpeg" />
<Add library="wxexpat" />
<Add library="wxregex" />
<Add library="wxzlib" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-pipe" />
<Add option="-mthreads" />
<Add option='[[if (GetCompilerFactory().GetCompilerVersionString(_T("gcc")) \
>= _T("4.8.0")) print(_T("-Wno-unused-local-typedefs"));]]' />
<Add option="-D__GNUWIN32__" />
<Add option="-D__WXMSW__" />
<Add option="-DwxUSE_UNICODE" />
<Add directory="$(#wx281.include)" />
</Compiler>
<ResourceCompiler>
<Add directory="$(#wx281.include)" />
</ResourceCompiler>
<Linker>
<Add option="-mthreads" />
<Add library="libcomctl32.a" />
<Add library="libuuid.a" />
<Add library="libole32.a" />
<Add library="liboleaut32.a" />
<Add library="libwinspool.a" />
<Add directory="$(#wx281.libs)" />
</Linker>
便利提示
使用CB的全局变量来保存wx的目录会更方便配置wx工程,打开 settings -> global variables,在界面中 current variable 指定一个变量对象,可以为它设置从属一系列变量。CB已经定义了常用的如 lib、include等等。例如设置一套 wxWidgets 3.0 对应的变量,先克隆当前的变量设置,在提示框中输出新的变量名wx30,然后在lib、include中输入对应的目录,设置好现有的wx,在配置工程时,可以这样调用:
$(#wx30.lib)
对于 wxWidgets 2.8 也同法炮制,这样在新建工程时,只需要替换一下变量名就可以更新wx的版本选择。接下来要对编译器进行设置,首先到 TDM-GCC安装包 下载到 4.4.1 和 4.7.1 两个安装包并安装到两个对应的目录下。也可以去下载带 mingw 的 CodeBlocks 安装包,安装好两者后,打开 setting -> compiler 设置编译器。 将 GNU GCC Compiler 拷贝一份,改名为 GNU GCC 4.7.1,先将 Toolchain executables 的目录改为 TDM-GCC-4.7.1 的安装目录,工具名称设置不用改。再将 Linker settings 和 Search directories 两个选项卡内的目录全部改过来,再以同样操作建立 TDM-GCC-4.4.1 的配置,最好TDM-GCC-4.6.2这个版本也安装好,方便使用。做这些工作后,今后开发 wxWidgets 程序就方便了,动态链接静态链接随便选,在向导界面中选好配套的 wx和g++版本就可以了。
另外,wx所有发行包中的库文件都是含有版本号的,如果工程向导配不能自动配置库文件时,手动置起来好凄难搞。官方 Using wxWidgets (MSW) 3.0 给出的解决方法是设置工程的自定义变量,再在程的编译链接选项中搭配这个信息来对应各版本,这种做法十分费力。如下,WX_COMPILER 和 WX_COMPILER_VERSION 就是两个自定义变量。
$(#wx30.lib)\$(WX_COMPILER)$(WX_COMPILER_VERSION)_dll
我的做法是直接将库文件改名,将版本号部分去掉,为了保留版本信息,只需要在目录名上添加上wx版本号,然后通过全局变量来引用目录,这样配置不同的wx版本就只需要修改一个全局目录就好了。需要还原文件名反过来执行就可以了,如下就是一组wx2.8的库文件更名脚本:
| 去版本号命名 | 回复原文件名 |
|:----------------------------------------------------|:--------------------------------------------------|
| ren libwxbase28.a libwxbase.a | ren libwxbase.a libwxbase28.a |
| ren libwxbase28d.a libwxbased.a | ren libwxbased.a libwxbase28d.a |
| ren libwxbase28d_net.a libwxbased_net.a | ren libwxbased_net.a libwxbase28d_net.a |
| ren libwxbase28d_odbc.a libwxbased_odbc.a | ren libwxbased_odbc.a libwxbase28d_odbc.a |
| ren libwxbase28d_xml.a libwxbased_xml.a | ren libwxbased_xml.a libwxbase28d_xml.a |
| ren libwxbase28u.a libwxbaseu.a | ren libwxbaseu.a libwxbase28u.a |
| ren libwxbase28ud.a libwxbaseud.a | ren libwxbaseud.a libwxbase28ud.a |
| ren libwxbase28ud_net.a libwxbaseud_net.a | ren libwxbaseud_net.a libwxbase28ud_net.a |
| ren libwxbase28ud_odbc.a libwxbaseud_odbc.a | ren libwxbaseud_odbc.a libwxbase28ud_odbc.a |
| ren libwxbase28ud_xml.a libwxbaseud_xml.a | ren libwxbaseud_xml.a libwxbase28ud_xml.a |
| ren libwxbase28u_net.a libwxbaseu_net.a | ren libwxbaseu_net.a libwxbase28u_net.a |
| ren libwxbase28u_odbc.a libwxbaseu_odbc.a | ren libwxbaseu_odbc.a libwxbase28u_odbc.a |
| ren libwxbase28u_xml.a libwxbaseu_xml.a | ren libwxbaseu_xml.a libwxbase28u_xml.a |
| ren libwxbase28_net.a libwxbase_net.a | ren libwxbase_net.a libwxbase28_net.a |
| ren libwxbase28_odbc.a libwxbase_odbc.a | ren libwxbase_odbc.a libwxbase28_odbc.a |
| ren libwxbase28_xml.a libwxbase_xml.a | ren libwxbase_xml.a libwxbase28_xml.a |
| ren libwxmsw28.a libwxmsw.a | ren libwxmsw.a libwxmsw28.a |
| ren libwxmsw28d.a libwxmswd.a | ren libwxmswd.a libwxmsw28d.a |
| ren libwxmsw28d_adv.a libwxmswd_adv.a | ren libwxmswd_adv.a libwxmsw28d_adv.a |
| ren libwxmsw28d_aui.a libwxmswd_aui.a | ren libwxmswd_aui.a libwxmsw28d_aui.a |
| ren libwxmsw28d_core.a libwxmswd_core.a | ren libwxmswd_core.a libwxmsw28d_core.a |
| ren libwxmsw28d_dbgrid.a libwxmswd_dbgrid.a | ren libwxmswd_dbgrid.a libwxmsw28d_dbgrid.a |
| ren libwxmsw28d_gl.a libwxmswd_gl.a | ren libwxmswd_gl.a libwxmsw28d_gl.a |
| ren libwxmsw28d_html.a libwxmswd_html.a | ren libwxmswd_html.a libwxmsw28d_html.a |
| ren libwxmsw28d_media.a libwxmswd_media.a | ren libwxmswd_media.a libwxmsw28d_media.a |
| ren libwxmsw28d_qa.a libwxmswd_qa.a | ren libwxmswd_qa.a libwxmsw28d_qa.a |
| ren libwxmsw28d_richtext.a libwxmswd_richtext.a | ren libwxmswd_richtext.a libwxmsw28d_richtext.a |
| ren libwxmsw28d_xrc.a libwxmswd_xrc.a | ren libwxmswd_xrc.a libwxmsw28d_xrc.a |
| ren libwxmsw28u.a libwxmswu.a | ren libwxmswu.a libwxmsw28u.a |
| ren libwxmsw28ud.a libwxmswud.a | ren libwxmswud.a libwxmsw28ud.a |
| ren libwxmsw28ud_adv.a libwxmswud_adv.a | ren libwxmswud_adv.a libwxmsw28ud_adv.a |
| ren libwxmsw28ud_aui.a libwxmswud_aui.a | ren libwxmswud_aui.a libwxmsw28ud_aui.a |
| ren libwxmsw28ud_core.a libwxmswud_core.a | ren libwxmswud_core.a libwxmsw28ud_core.a |
| ren libwxmsw28ud_dbgrid.a libwxmswud_dbgrid.a | ren libwxmswud_dbgrid.a libwxmsw28ud_dbgrid.a |
| ren libwxmsw28ud_gl.a libwxmswud_gl.a | ren libwxmswud_gl.a libwxmsw28ud_gl.a |
| ren libwxmsw28ud_html.a libwxmswud_html.a | ren libwxmswud_html.a libwxmsw28ud_html.a |
| ren libwxmsw28ud_media.a libwxmswud_media.a | ren libwxmswud_media.a libwxmsw28ud_media.a |
| ren libwxmsw28ud_qa.a libwxmswud_qa.a | ren libwxmswud_qa.a libwxmsw28ud_qa.a |
| ren libwxmsw28ud_richtext.a libwxmswud_richtext.a | ren libwxmswud_richtext.a libwxmsw28ud_richtext.a |
| ren libwxmsw28ud_xrc.a libwxmswud_xrc.a | ren libwxmswud_xrc.a libwxmsw28ud_xrc.a |
| ren libwxmsw28u_adv.a libwxmswu_adv.a | ren libwxmswu_adv.a libwxmsw28u_adv.a |
| ren libwxmsw28u_aui.a libwxmswu_aui.a | ren libwxmswu_aui.a libwxmsw28u_aui.a |
| ren libwxmsw28u_core.a libwxmswu_core.a | ren libwxmswu_core.a libwxmsw28u_core.a |
| ren libwxmsw28u_dbgrid.a libwxmswu_dbgrid.a | ren libwxmswu_dbgrid.a libwxmsw28u_dbgrid.a |
| ren libwxmsw28u_gl.a libwxmswu_gl.a | ren libwxmswu_gl.a libwxmsw28u_gl.a |
| ren libwxmsw28u_html.a libwxmswu_html.a | ren libwxmswu_html.a libwxmsw28u_html.a |
| ren libwxmsw28u_media.a libwxmswu_media.a | ren libwxmswu_media.a libwxmsw28u_media.a |
| ren libwxmsw28u_qa.a libwxmswu_qa.a | ren libwxmswu_qa.a libwxmsw28u_qa.a |
| ren libwxmsw28u_richtext.a libwxmswu_richtext.a | ren libwxmswu_richtext.a libwxmsw28u_richtext.a |
| ren libwxmsw28u_xrc.a libwxmswu_xrc.a | ren libwxmswu_xrc.a libwxmsw28u_xrc.a |
| ren libwxmsw28_adv.a libwxmsw_adv.a | ren libwxmsw_adv.a libwxmsw28_adv.a |
| ren libwxmsw28_aui.a libwxmsw_aui.a | ren libwxmsw_aui.a libwxmsw28_aui.a |
| ren libwxmsw28_core.a libwxmsw_core.a | ren libwxmsw_core.a libwxmsw28_core.a |
| ren libwxmsw28_dbgrid.a libwxmsw_dbgrid.a | ren libwxmsw_dbgrid.a libwxmsw28_dbgrid.a |
| ren libwxmsw28_gl.a libwxmsw_gl.a | ren libwxmsw_gl.a libwxmsw28_gl.a |
| ren libwxmsw28_html.a libwxmsw_html.a | ren libwxmsw_html.a libwxmsw28_html.a |
| ren libwxmsw28_media.a libwxmsw_media.a | ren libwxmsw_media.a libwxmsw28_media.a |
| ren libwxmsw28_qa.a libwxmsw_qa.a | ren libwxmsw_qa.a libwxmsw28_qa.a |
| ren libwxmsw28_richtext.a libwxmsw_richtext.a | ren libwxmsw_richtext.a libwxmsw28_richtext.a |
| ren libwxmsw28_xrc.a libwxmsw_xrc.a | ren libwxmsw_xrc.a libwxmsw28_xrc.a |