wxWidgets的安装编译、相关配置、问题分析处理
一、介绍部分 (win7 下的 GUI 效果图见 本篇文章的最后部分截图2张)
wxWidgets是一个开源的跨平台的C++构架库(framework),它可以提供GUI(图形用户界面)和其它工具。目前的2.x版本支持所有版本的Windows、带GTK+或Motif的Unix和MacOS。相当于大家熟悉的 VC++。
参考介绍:
http://www.cnblogs.com/nokiaguy/archive/2009/01/27/1381071.html
二、wxWidgets的安装与编译:
二.1 基础部分
编译是少不了的操作,即使你下载的是安装包,因为这个安装包只是相当于自解压包,我们还需要将其进行编译,才能得到wxWidgets在Windows可用的库。
如果你在参考了许多编译文档或教程之后发现还是没有编译出某些库文件,如
wxbase28u_gcc_custom.dll
libwxmsw28ud_gl
libwxmsw28u_gl
libwxmsw28u_dbgrid
libwxmsw28ud_dbgrid
wxbase28ud_gcc_custom.dll
wxbase28u_gcc_custom.dll
(部分文件可能会有扩展名的缺少而不同)
这里使用的版本是wxWidgets 2.8.12(上面文件名中的28也是指这前两位版本号2.8,版本2.9的同理)
在本文发表之时,wxWidgets 2.8.12是当前的稳定版。如下,
Latest Development Release: 2.9.5
Current Stable Release: 2.8.12
Previous Stable Release: 2.6.4
下载地址:http://www.wxwidgets.org/downloads/
http://prdownloads.sourceforge.net/wxwindows/wxMSW-2.8.12.zip (MSW=MS Windows)
先检查一下系统的环境变量中有无Mingw32(32位)的bin目录的值,集成安装的大致安装位置是 C:CodeBlocksMinGWin ,要用到的是其中的mingw32-make.exe 。
环境变量的设置,此外设置用户变量(系统变量要重启才行,并且对所有用户都有效),只要简单注销一下当前用户即可生效(而用path 命令设置有时不生效)。
在这里说一下,一般会用到的与本IDE设置有关的环境变量,
1 是编译环境用到的bin 目录,即大致类似于 C:CodeBlocksMinGWin
2 调用库文件时用到的编译完成后,放置生成的库文件的目录。这个目录下面会说到。
解压下载的压缩包,并进入 wxMSW-2.8.12uildmsw子目录,打开命令行切换到这一目录(或在这个文件夹空白处按住Shift,并右键,选择“在此处打开命令窗口”,直接进入)。因为前面设置好了环境变量(不论是用户级的,还是系统级的,最后,再打开cmd.exe,执行 path 检查一下是否添加成功)
编译时用到的命令,如果用它,就按下文件相关,修改 config.gcc 文件后,执行
mingw32-make.exe -f makefile.gcc (无参数,参数写在config.gcc中)其中的 -f 是 file,为mingw32-make.exe指定要编译的文件 makefile.gcc。
如果不写在配置文件中,则可以写成如下示例(只是动态库SHARED=1)
mingw32-make -f makefile.gcc BUILD=release SHARED=1 UNICODE=1 (release 版本)
mingw32-make -f makefile.gcc BUILD=debug SHARED=1 UNICODE=1 (debug 版本)
下面是完整的config.gcc文件内容,在看之前,请先略看,并跳到下面的内容,但在正式编译时,请细看下面内容,即使你用的是加了参数的编译方法,如上面2条命令,可能会无法编译出某些文件。图形界面开发,要考虑的地方很多,入门后,自然更加熟练:
# ========================================================================= # This configuration file was generated by # Bakefile 0.2.9 (http://www.bakefile.org) # Beware that all changes made to this file will be overwritten next # time you run Bakefile! # ========================================================================= # ------------------------------------------------------------------------- # These are configurable options: # ------------------------------------------------------------------------- #设置是否共享生成的库文件(先默认如下) # Compiler flags to link shared library LINK_DLL_FLAGS ?= -shared # Compiler flags to link loadable module LINK_MODULE_FLAGS ?= -shared #编译器(这个不能动,其它的编译器也有对应的 config.***文件) # C compiler CC = gcc # C++ compiler CXX = g++ #下面的几条,与编译时占用的CPU等系统资源有关,可能。 # Standard flags for CC CFLAGS ?= # Standard flags for C++ CXXFLAGS ?= # Standard preprocessor flags (common for CC and CXX) CPPFLAGS ?= # Standard linker flags LDFLAGS ?= # The C preprocessor CPP ?= $(CC) -E #静态库 0 、动态库 1 # What type of library to build? [0,1] SHARED ?= 0 #没了解(默认) # Build wxUniversal instead of native port? [0,1] WXUNIV ?= 0 #支持宽字符集,必须是1 # Compile Unicode build of wxWidgets? [0,1] UNICODE ?= 1 # Use MSLU library when building Unicode version. [0,1] MSLU ?= 0 #编译的二进制的类型:Debug、Release(这两个都要编译,方便以后用到) # Type of compiled binaries [debug,release] BUILD ?= release #这里说一下,下面的参数,能开的基本上都开了,但个别的会说明一下作用。 # Should debugging info be included in the executables? The default value # "default" means that debug info will be included if BUILD=debug # and not included if BUILD=release. [0,1,default] DEBUG_INFO ?= default # Should __WXDEBUG__ be defined? The default value "default" means that it will # be defined if BUILD=debug and not defined if BUILD=release. [0,1,default] DEBUG_FLAG ?= default #是编译分开的多个库,还是一个大的整体(如果选择1,会无法得到目标库,生成的库是以monolithic 为前缀的,而且很大) # Multiple libraries or single huge monolithic one? [0,1] MONOLITHIC ?= 0 #图形界面,少不了 # Build GUI libraries? [0,1] USE_GUI ?= 1 # Build wxHTML library (USE_GUI must be 1)? [0,1] USE_HTML ?= 1 # Build multimedia library (USE_GUI must be 1)? [0,1] USE_MEDIA ?= 1 # Build wxXRC library (USE_GUI must be 1)? [0,1] USE_XRC ?= 1 # Build wxAUI library (USE_GUI must be 1)? [0,1] USE_AUI ?= 1 # Build wxRichTextCtrl library (USE_GUI must be 1)? [0,1] USE_RICHTEXT ?= 1 # Build OpenGL canvas library (USE_GUI must be 1)? [0,1] USE_OPENGL ?= 1 # Build ODBC database classes (USE_GUI must be 1)? [0,1] USE_ODBC ?= 1 # Build quality assurance classes library (USE_GUI must be 1)? [0,1] USE_QA ?= 1 # Enable exceptions in compiled code. [0,1] USE_EXCEPTIONS ?= 1 # Enable run-time type information (RTTI) in compiled code. [0,1] USE_RTTI ?= 1 # Enable threading in compiled code. [0,1] USE_THREADS ?= 1 #下面这个参数在前面如果设置了编译类型是Relesse是设置为1,Debug时为0(我在编译时,后者Debug为1时中断了) # Enable wxCairoContext for platforms other than Linux/GTK. [0,1] USE_CAIRO ?= 1 # Link with gdiplus.lib? (Needed for wxGraphicsContext, will also set wxUSE_GRAPHICS_CONTEXT) [0,1] USE_GDIPLUS ?= 1 # Is this official build by wxWidgets developers? [0,1] OFFICIAL_BUILD ?= 0 # Use this to name your customized DLLs differently VENDOR ?= custom # WX_FLAVOUR ?= # WX_LIB_FLAVOUR ?= #下面的大概是特殊设置 # Name of your custom configuration. This affects directory # where object files are stored as well as the location of # compiled .lib files and setup.h under the lib/ toplevel directory. CFG ?= # Compiler flags needed to compile test suite in tests directory. If you want # to run the tests, set it so that the compiler can find CppUnit headers. CPPUNIT_CFLAGS ?= # Linker flags needed to link test suite in tests directory. If you want # to run the tests, include CppUnit library here. CPPUNIT_LIBS ?= # Version of C runtime library to use. You can change this to # static if SHARED=0, but it is highly recommended to not do # it if SHARED=1 unless you know what you are doing. [dynamic,static] RUNTIME_LIBS ?= dynamic # Set the version of your Mingw installation here. # "3" ...... this is for Mingw 2.0 or newer (comes with gcc3) # "2.95" ... for Mingw 1.1 or any of the older versions [3,2.95] GCC_VERSION ?= 3
config.gcc 配置文件结束!!
相关知识:节选自 http://wenku.baidu.com/view/69b0272216fc700abb68fcae.html 本文不作过多修改。
动态库dll vs. 静态库lib
从编译结果上看,C++库可以被编译成“静态”链接库,也可以被编译成“动态”链接库。所谓“链接库”的意思就是,库自身并不可以被执行。应用程序才是可执行的,为了写一个应用程序,可能需要用到很多功能,其中一些功能,应用程序的作者并不用自己实现,而是直接使用链接库即可。把应用程序与库在功能上进行合并的过程,就叫做过“链接”。如前所有述,有两种链接方法:静态或动态。
所谓“静态链接”,就是直接把库文件和可执行文件合二为一,形成一个文件。这种情况下,发布可执行文件时,就不必另外附加那个功能库了;因为事实上那个功能库已经“嵌入”在可执行文件中(可执行文件的体积,变大了)。静态链接方法,适用于功能简单应用程序。
所谓“动态链接”,是指程序在运行时,才会去寻找动态库中所需要的功能,然后在内存中加载入动态库。这种情况下,可执行文件与动态库独立存在,没有合成一体,在发布程序时,你必须两个文件一起安装到用户的电脑上。动态链接方法,适用于相对复杂的应程序,通常这种情况下,为了方便用户安装,我们会提供一个安装程序。 另外,在Linux系统中,“动态链接库”通常被称为“共享库”(文件扩展名也改为.so);这也说出了“动态链接”这项技术带来的另一个好处:多个应用程序可以共用一个独立的动态库。
如果把盖房子想像成写程序的话,当我们需要建造其中的自来水系统时,可以把水库当成是一种功能链接库。那么,当我们是在乡下自建一座独门独户的小楼,那么可以采用“静态链接”的方法,即在自家楼里砌个水库,自个儿使用,当然这个自建的水库往往增加了小楼的体积。来到城里,城里的一座高楼住着千家万户,这时,“动态链接”技术派上用上,所有住户共享一个水库,当你需要水时,打开水龙头,水就从外部“动态”而来。
为了方便以后使用,今天wxWidgets将我们编译成至少两个版本,即动态库和静态库 ,debug 和 release ,2x2=4,其它参数不变。而在CodeBlocks的工具栏中“build target”可以选择你当前的编译类型,并且相关的信息,可能也与这有关,具体去分析,我们一个也不能少。
DEBUG vs. RELEASE
DEBUG 指“调试”版。表示编译出所库含有调试信息,这自然会让库变得很大,但有利于我们写程序时跟踪也发现错误。
RELEASE 指 “发行”版。表示我们认定程序写得差不多了(能解决的问题都解决了,错误相对比较少),这时调试信息就不需要了,库恢复它原来的大小。
为了方便调试与发而程序,DEBUG和RELEASE,同样的,我们一个也不能少。
UNICODE vs. 非 UNICODE
传统C++程序中,对普通的1个英文字符采用1个字节表示,而对1个汉字采用两个字节表示。比如有这样一句话:
“文件c:abcefg我的文档奥运知识ABC乒乓球基础知识.txt无法打开!”
假设计数以0开始,那么例子中那句话,第0个字符是“文”字的前半个字符,第1个字符则是“文”字的后半个字符。事实上半个汉字是没意义的,它只会为字符串处理上带来困难。比如,假设我们要把上述那句话显示在显示在某个窗口上,但由于窗口太小,显示不下这时我们希望将那句话的截掉一点,结果类似:
“文件c:abcefg我的文档奥运知识ABC乒乓球基...”
这个过程看似简单,但其实复杂,如果不进行特殊的处理,程序很要可能会在某个汉字的半个字符处截断那句话,而1个汉字一旦被“腰斩”了,剩下的那个半个汉字,无论是上半身还是下半身,就会在屏幕上显示乱码。
解决这个问题,方法有很多种,其中采用“UNICODE”是个相对通行而简单的办法,并且解决得比较彻底。“UNICODE”的方案说起来也简单,就是用两个字节甚至四个字节去表达一个字符(无论是英文字符还是中文、日语等)。
相关知识 结束!
二.2 目录知识
要处理汉字,所以在编译过程,我们只选择UNICODE的方案,故会编译 4 次。每次30分钟左右,计算机配置高的话,可以同时进行两次。由于只是需最终编译的库,推荐的方法是,将目录 wxMSW-2.8.12/ 复制4份,每一份均作相应的编译。 然后将目录进行合并,我们最终需要的不是build目录下的文件,而是程序根目录 lib 中的库文件。参考下面的表格,就能得出库文件的命名机制,见表格中的【注】,所以4次编译不会出现库文件重名,只是相似。
编译完成后,在msw目录下生成的目录如表格,返回到 wxMSW-2.8.12lib 目录,我们发现多了 gcc_lib(静态)或gcc_dll()动态
库类型 静态=0 动态=1 |
编译时下面目录下会生成子目录 wxMSW-2.8.12uildmsw |
编译时下面目录下 会生成子目录 wxMSW-2.8.12lib |
||
Unicode | debug | 动态 | gcc_mswuddll | gcc_dll |
静态 | gcc_mswud | gcc_lib | ||
release | 动态 | gcc_mswudll | gcc_dll | |
静态 | gcc_mswu | gcc_lib | ||
上面3项知识详见下文 | 【注】:gcc_msw(gcc编译的windows库), u=unicode,d=debug,dll=动态, lib=静态(略写),r=release(略写) |
gcc_dll的目录下有 mswu 或 mswud gcc_lib的目录下有 mswu 或 mswud |
相关目录及操作 的截图参考:
1 编译过程,刚刚开始,即被我无情 Ctrl + C 终止。提示,编译前要先考虑是否如上面示例修改 config.gcc 文件。时间:30分钟左右。
2 msw 目录下的两个主要文件 :配置 - config.gcc、及 makefile.gcc 。目录 gcc_mswu 在编译之前不存在(显然这是编译的 Unicode + 静态库 + Release)
3 lib 目录下编译后的文件目录结构,目录“_sc”及下面的3个文件在不同的编译条件下不会变化。这里要提到的是前面在环境变量部分没有讲完的第2个环境变量,虽然不是必须,但是这种解决问题或排除程序报错的方法是很重要的。参考下面的图片,一一说来。
4 进入上图的 gcc_lib ,里面的目录结构如下图,包括各种 (Unicode + 静态库 + Release),其中的 mswu 目录下的文件有时也会因为缺少而报错,比如其子子目录中的 setup.h 。
5 如果大家采用我的方法,将静态库、动态库分别合并到 gcc_lib 及 gcc_dll ,下图就是相应结果:
关于此处涉及到的环境变量问题在这里细说一下,按照下图的库文件放置方法在编译时会报错,大多是找不到某某文件,而你到这个目录下查找,却发现文件在那呀!
CodeBlocks 创建 Project 时会的步骤要求你选择 wxWidgets 的存放目录,编译时编译器就会从这个目录下找 lib 下的库文件,但不会找子目录下的文件。因而,如下图放置库文件,会提示缺少相关文件。那么,怎么办?有两种办法。
1 将 gcc_lib 及 gcc_dll 加到环境变量中
2 直接把 gcc_lib 及 gcc_dll 里面的文件及目录全部移动到 lib 根目录下。不上图了,移动时不用担心文件或目录重名。
这种方法是重点:前提是你编译出了这个文件,编译时提示找不到某文件,就将其放置在环境变量中。其实初期使用时担心的都是缺少文件的报错,这你真心没办法。So,花点时间在编译工作上吧,没有坏处的!!
三、供参考的相关资料:
http://blog.sina.com.cn/s/blog_5dbdcfc701013kiw.html
http://wiki.codeblocks.org/index.php?title=WxSmith_tutorial:_Hello_world (图形界面重点入门参考,全英文。虽然,与本篇版本不同,但不出错。用 wxFormBuilder,就不如用集成的wxSmith,知其一,则知它们)
四、相关问题罗列:
1 编译器版本与库文件的关系,前面也有提到,如果使用了别人编译的库,最好就要用编译这个库使用的编译器版本,即使只是版本号不同。这里也发现为什么linux下提供的程序多为源码,使用时需要编译,有编译器版本与库文件不对应的原因,就像一台组装机,必需要考虑硬件不兼容问题。而这个问题在windows及MacOS下很少,因为这些平台下的程序所需调用的库大多内置在了程序中。虽然体积会大点,却得到了体验。回想一下,桌面版本linux 六个月一次升级,大多数程序都要同时重新编译,拿播放器 VLC 来说,在Fedora 上就要为是Fedora 18 及 Fedora 19 而分别编译发行版本(这个可能会不用在本机编译了);而服务器版Linux很少升级,是为避开这个问题,服务器上的各种服务器软件,怎么能够奔命于编译、编译、再编译的过程,而连基本服务都没做好。导致原因,不能与它的自由,开源脱开关系。所以,Linux会有那么一个阶段,分久必合,大家坐下来 制定一个ISO标准,这为的是长远发展,但不能失去了它的根本:自由、开源。我曾经与朋友打了这么一个比喻,linux像组装机,各种配件,自由搭配,只要没有兼容性问题;Windows 则是品牌机,办公、影音、游戏,应有尽有。物尽其用,最终提供服务的是应用程序,而它们跑在系统的大车之上。
2 64位 或 32位 系统的影响,虽说,用的是32位的编译器,可编译出来的程序在我64拉win7上部分效果不能实现,而拷贝到32位win7上,运行良好(如果缺少文件,就在本机上复制它到目标电脑system32目录,这个目录是系统默认加入到环境变量中的)。不过可能只是一面之词,毕竟只是我一台机子上的现象,而我的电脑用运行着HIPS (Comodo防火墙内置)
3 网上有一种 wxpack 是库文件编译好的,但现在新版本的没有编译了,vc++、gcc编译都有,安装后数个G的体积,但问题是还是会出现这里列出的第 1 条问题,而且那个版本的编译器不容易配置。
4 这一条不是什么问题,而是在 wxMSW-2.8.12 根目录,有一个 samples 子目录,里面存放的是图形界面的若干个源码示例,没错,需要编译。在 samples 目录下也有一个 makefile.gcc,编译就像编译库文件一样 ,命令行下切换到这下目录,使用命令 mingw32-make.exe -f makefile.gcc 只是这个 makefile.gcc 是全部编译 samples 目录下的所有工程示例(一个子目录就是一个工程)。
而单个编译时,要进入相应工程目录,同样有 makefile.gcc 文件,操作同上,可能并不是每个都能编译成功。编译成功的对应目录下会有 gcc_mswu 其中有对应的 exe 可执行文件,并拷贝到其它电脑运行一下。
示例 calendar
示例 aui
wxWidgets 工程的具体创建过程本文不作叙述。
CodeBlocks 安装相关参见:http://www.cnblogs.com/hslog/p/hslog0003.html
文中部分内容可能会有所不同,请以操作为准,如果希望本文更加完善,请告知相关内容,并在此对文中引用的文章的作者表示感谢;
本文可能还会更新...