gcc-3.4
g++-3.4
build-essential
wxwidgets-dev
glib-dev
libgtk2-dev
qt-dev
cairo-dev
patch
cvs
automake
autoconf
doxygen
cmake
bison
flex
xulrunner-dev
libxml2-dev
tcl
tk
vim
java
language-support-fonts-zh
language-support-input-zh
scim-bridge
flash
apache
libapr
libaprutil
ruby
php5
python
Apache Modules 学习笔记(1)
最近看了这本<<The Apache Modules Book>>: http://www.amazon.com/gp/product/B000SEGRM8/, 记录一下.
每次我们学一个新的东西的时候, 似乎都会写一个程序叫做”hello world”, 今天的目的也在于此. 看这本书的目的主要是为了了解Apache 的扩展性到底是如何做到的. Apache 主要提供了hook, filter, provider 等机制. 其次, 就是Apache 的跨平台和平台相关的优化. 本人对这些东西的了解还比较粗浅, 本书感觉也只是在大量的贴Apache 的源码, 所以还是要看Apache 的manual. 最后, Apache 的源码确实写的非常有参考价值, 很多东西我都不知道原来能那么用的.
好了, 进正题, 我们要写的是一个”hello world” 的generator module. 运行的结果如图:
然后是代码, 有点长:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#include <httpd.h> #include <http_protocol.h> #include <http_config.h> static int print_item(void* rec, const char* key, const char* value) { /* rec is a user data pointer */ request_rec* r = rec; ap_rprintf(r, "<tr><th>%s</th><td>%s</td></tr>", ap_escape_html(r->pool, key), ap_escape_html(r->pool, value)); /* 0 would stop iterating, any other return value continues */ return 1; } static void print_table(request_rec* r, apr_table_t* t, const char* keyhead, const char* valhead) { /* table header */ ap_rputs("<table>", r) ; ap_rprintf(r, "<thead><tr><th>%s</th><th>%s</th></tr></thead>", keyhead, valhead); /* table data */ ap_rputs("<tbody>", r); apr_table_do(print_item, r, t, NULL); ap_rputs("</tbody>", r); /* table footer */ ap_rputs("</table>", r); } static int helloworld_handler(request_rec* r) { /* r->handler is specified in configure file */ if (!r->handler || strcmp(r->handler, "helloworld")) { return DECLINED; } if (r->method_number != M_GET) { return HTTP_METHOD_NOT_ALLOWED; } /* generate html header */ ap_set_content_type(r, "text/html; charset=ascii"); ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">", r); ap_rputs("<html>", r); ap_rputs("<head><title>Apache HelloWorld Module</title></head>", r); ap_rputs("<body>", r); ap_rputs("<h1>Hello World!</h1>", r); ap_rputs("<p>This is the Apache HelloWorld module!</p>", r) ; /* print the request headers */ print_table(r, r->headers_in, "Header", "Value") ; ap_rputs("</body>", r); ap_rputs("</html>", r); return OK; } static void helloworld_hooks(apr_pool_t* pool) { ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE) ; } module AP_MODULE_DECLARE_DATA helloworld_module = { STANDARD20_MODULE_STUFF, NULL, NULL, NULL, NULL, NULL, helloworld_hooks }; |
这个module 的用途是打印接受到的request 的header 信息. 需要知道的有两部分: module 的声明, module 的hook 函数. Apache 模块的都是通过”module” 这个struct 来声明导出的, 在这个struct 中会初始化这个模块的各个函数指针. 在我们的代码中, 中间5 个值都是NULL, 它们是用来安装配置文件相关的hook 的, 暂时不用. 最后一个hook 则指向一个相当于运行时的hook 函数, 在这个函数, 即”helloworld_hooks” 中, 我们指定Apache 的那些处理过程会被我们hook 到. 这里我们使用了ap_hook_handler 这个函数, 它表明我们的模块是一个generator handler. 它的参数helloworld_handler 依然是一个函数指针, 表示具体的处理过程. 其它的代码都是html 的生成, 先随便看看吧.
接下来是编译的问题. 如果用VC 的话, 那么就是简单的把apache, apr, apr-util 的include 和lib 的路径加进去, 基本就通过编译了. 不过有的module 可能会依赖其它module, 个么这个也自己加. 我写了一个简单的Makefile 来编译, 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
APACHE=httpd-2.2.13 CC = cl DEFINESD = /DWIN32 /D_DEBUG DEFINES = /DWIN32 CFLAGSD = /nologo /ZI /Od /MDd /LDd CFLAGS = /nologo /Zi /O2 /MD /LD INCPATH = -I$(APACHE)\include \ -I$(APACHE)\srclib\apr\include \ -I$(APACHE)\srclib\apr-util\include LINK = link LFLAGSD = /DLL LFLAGS = /DLL LIBSD = $(APACHE)\Debug\libhttpd.lib \ $(APACHE)\srclib\apr\Debug\libapr-1.lib \ $(APACHE)\srclib\apr-util\Debug\libaprutil-1.lib LIBS = $(APACHE)\Release\libhttpd.lib \ $(APACHE)\srclib\apr\Release\libapr-1.lib \ $(APACHE)\srclib\apr-util\Release\libaprutil-1.lib debug: $(CC) $(DEFINESD) $(CFLAGSD) $(INCPATH) mod_helloworld.c /link $(LFLAGSD) $(LIBSD) /OUT:mod_helloworldd.so release: $(CC) $(DEFINES) $(CFLAGS) $(INCPATH) mod_helloworld.c /link $(LFLAGS) $(LIBSD) /OUT:mod_helloworld.so |
vs2005, vs2008 皆可通过编译. vs 的-I 选项似乎不支持绝对路径, 所以编译之前请修改$(APACHE) 变量. 另外, 发现一个问题就是, debug 编译的Apache 不能加载release 编译的module. 后来发现是vs2005/2008 的CRT dll的SxS 的问题. 所以, Apache 和module 的编译器最好是同一版本和配置, 这样CRT 才能被正确加载进来. 或者就是静态链接到CRT.
把编译出来的*.so 文件拷贝到Apache 的modules 文件夹下. 最后来修改配置文件. 打开httpd.conf, 添加如下代码:
1 2 3 4 |
LoadModule helloworld_module modules/mod_helloworld.so <Location /helloworld> SetHandler helloworld </Location> |
LoadModule 指令用来加载模块, 第一个参数是在代码中导出(export) 的模块名, 第二个参数是模块的路径. 然后来设置映射关系, 凡是URL 是/helloworld 开头的, 都用helloworld 这个handle 来处理, 而helloworld 这个handle, 实际上只是我们在代码中字符串比较用的, 参见helloworld_handler 这个函数.
以上.
Building Apache Web Server with Visual Studio 2005
1. Source
a) apache 2.2.13: http://www.apache.org/dist/httpd/httpd-2.2.13-win32-src.zip
b) zlib 1.2.3 (for mod_deflate): http://www.zlib.net/zlib-1.2.3.tar.gz
c) openssl 0.9.8k (for mod_ssl): http://www.openssl.org/source/openssl-0.9.8k.tar.gz
2. Tools
a) ActivePerl: http://aspn.activestate.com/ASPN/Downloads/ActivePerl/
b) awk & patch tools: http://gnuwin32.sourceforge.net/packages.html
3. Steps
a) Setup Perl environment, add %Perl%/bin
to %PATH%
.
b) Also add awk, path tools to %PATH%
.
c) Decompress the apache source code to %Apache%
, D:Apache
maybe.
d) Decompress the zlib into srclib
subdirectory named zlib
.
e) Decompress the openssl into srclib
subdirectory named openssl
.
f) Now the source tree should look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
%Apache% | + srclib | | | + apr | | | + openssl | | | + zlib | | | + ... | + ... |
g) Patch zlib:
Download the patch from: http://www.apache.org/dist/httpd/binaries/win32/patches_applied/zlib-1.2.3-vc32-2005-rcver.patch. This patch contains minor fixes and enable generation of *.pdb files.
Copy the patch file into zlib
subdirectory, swith to the directory in cmd.exe and run the command:
1 |
# patch -p0 < zlib-1.2.3-vc32-2005-rcver.patch |
h) Patch openssl:
Download the patch from: http://www.apache.org/dist/httpd/binaries/win32/patches_applied/openssl-0.9.8k-vc32.patch. This patch will correct a link issue with zlib and enable generation of *.pdb files.
Copy the patch file into openssl
subdirectory, swith to the directory in cmd.exe and run the command:
1 |
# patch -p0 < openssl-0.9.8k-vc32.patch |
i) Build zlib:
1 |
# nmake -f win32Makefile.msc |
j) Build openssl:
1 2 3 |
# perl Configure no-rc5 no-idea enable-mdc2 enable-zlib VC-WIN32 -I../zlib -L../zlib # msdo_masm.bat # nmake -f msntdll.mak |
k) Patch Apache:
There’s an issue in the Makefile.win that build Apache in 2.2.13: https://issues.apache.org/bugzilla/show_bug.cgi?id=47659. Download the patch against branch into the %Apache% directory and run the command:
1 |
# patch -p0 < r799070_branch_makefile_fix.diff |
l) Build Apache using command line:
Now you can buid Apache by:
1 |
# nmake -f Makefile.win _apache[d|r] |
And install Apache by:
1 |
# nmake -f Makefile.win install[d|r] |
m) Build Apache using Visual Studio 2005:
There’s also a flaw in the *.vcproj conversion of *.dsp through Visual Studio 2005. We must run a perl script to fix it first:
1 |
# perl srclibaprbuildcvtdsp.pl -2005 |
Now, everything are OK. In Visual Studio 2005, open the Apache.dsw and convert all *.dsp files to *.vcproj files. Then build the project “BuildBin”. The project “InstallBin” project will distribute all the project in the Apache solution.
4. Debugging with Visual Studio 2005
It’s quite simple. After build the project “InstallBin”, open the property page of the “httpd” project. Switch to “Debugging” tab, change the Command value into your binary of installed directory. Now, add breakpoints, and press F5 to start your tracing or debugging.
5. Reference
a) Compiling Apache for Microsoft Windows
b) Apache 2.2.9 command line build with the Windows 2008 SDK
Job Open: gonwan’s girlfriend
Brief
I’m now working for ASUS Computer Inc. as a senior software engineer. My wage is about 5k – 8k per month. No house nor car is available.
In spare time, I read books. Learning is important. I also watch animes to relax myself. I like singing. My favorite singer is Fish Leong. Every week, I play badminton or do other sports. But I’m not very good at sports, just for fun. “Living with passion” is my motto.
Lastly, I do not have a plan for marriage in recent two years.
Title
gonwan’s girlfriend
Requirements
·162-172 a must.
·Intelligent, diligent, and with a pleasant personality.
·Being so outgoing that I can trust and always share my thoughts with you.
·No specific zodiac required.
·Good singing skills preferred.
·Good drawing skills a plus.
Responsibilities
·Just whatever a girlfriend should do.
I will offer a better life to you, if you get the position.
Please send your resume to “gonwan (at) gmail (dot) com”. Be sure to mark the title with “applying for position”. Then you will be informed when and where to take an interview session.
Contact me if you are the one.
丸之宅记录2009 (砖头篇)
2008/08 – 2009/07 读过的技术类书籍.
基本按照时间序, 至少读完50% 以上, 其中页数以amazon.com 为准.
Cross-Platform Development in C++
Authors: Syd Logan
Pages: 576
Difficulty: ★★★
Recommended Degree: ★★★
Comprehensive Degree: 95%
本书的作者是Netscape 的资深工程师, 也就是现在正在弄firefox 这个东西. 本书实质性的内容不多, 但是对于跨平台的开发目前看来还是唯一一本. 书里一开始说, 对于一个跨平台的项目, 便一开始就要各个平台并行开发, 不能丢掉任何一个. 也就是态度决定一切. 接着介绍了一般跨平台开发的编码规范, 哪些语言特性是编译器相关的, 哪些特性是平台相关的, 需要避免使用. 然后便是代码的组织结构, 以及如何自己实现跨平台的接口. 在然后是跨平台的一些开发工具. 最后介绍了wxWidgets 这个开源的跨平台项目, 以及作者自己写的一个跨平台类库.
C++ GUI Programming with Qt4, 2E
Authors: Jasmin Blanchette, Mark Summerfield
Pages: 752
Difficulty: ★★★☆
Recommended Degree: ★★★★
Comprehensive Degree: 90%
Qt, 这是一个跨平台的GUI 类库, 当然现在已经不仅仅限于GUI 了. 当初看这本书的原因, 自然是因为前一本看的意犹未尽. 而Qt 的代码, 因为有商业版本的支持, 比wxWidgets 质量高很多(Qt 自4.4 版本以后感觉代码质量有所下降). 可以把Qt 的GUI 库想像成Java 中的swing 库, 因为它们的控件都是用GDI 画出来的. 而可以把wxWidgets 的GUI 库想像成Java 中的awt 库, 它们的控件是调用Windows 的API 来绘制的. 所以你可以把它们分别成为light-weight 和heavy-weight.
言归正传, 这本书可以说是一本半官方的文档. 除了前几章介绍了Qt 的整体框架之外, 之后开始便都在讲如何使用类库. Qt 的好处, 除了跨平台以外, 还有客户端代码的简洁, 以及很好的工具支持. 当然, 要知道类库怎么用并不难, 难的是要知道类库到底是如何设计的. 看这本书的时候, 丸子经常写一个很简单的程序, 然后用Visual Studio 单步调式Qt 的源代码. 之后, 在公司项目中对于Qt 设计思想的使用, 让我对Qt 有了更深的理解.
An Introduction to Design Patterns in C++ with Qt4
Authors: Alan Ezust, Paul Ezust
Pages: 656
Difficulty: ★★
Recommended Degree: ★
Comprehensive Degree: 100%
乍看之下, 本书的名字很牛啊, 又是Qt, 又是C++, 又是design pattern. 但其实却是入门等级的, 丸子也被书名给骗了. 本书的流程大概就是用Qt 的语法, 教你写程序, 顺便提提design pattern. 真无语.
Effective C++, 2E
Authors: Scott Meyers
Pages: 256
Difficulty: ★★★
Recommended Degree: ★★★
Comprehensive Degree: 95%
本书也可以说经典了, 但是丸子却没看过. 书中提了50 条C++ 的编程规范, 让你的code 能更加effective. 当时看的时候, 发现自己几乎都知道, 而且中间有很多的废话, 一般人根本不会那么写代码的. 所以感觉收获并不是很大. 还是推荐另外3 本书比较有难度的书: <<exceptional c++>>, <<more exceptional c++>>, <<c++ object model>>, 保证让你看的醉生梦死.
Design Patterns: Elements of Reusable Object-Oriented Software
Authors: Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
Pages: 416
Difficulty: ★★★★
Recommended Degree: ★★★★★
Comprehensive Degree: 75%
又一本经典, 四人帮的书.
本书被丸子誉为程序员的九阳神功, 有了它等之后练太极, 练乾坤大挪移就能事半功倍.
本书自然是介绍23 种设计模式. 就语言描述来说, 真的是有些难懂, 但确实是目前来说最定义最完整的. 目前公司training 的一本叫做<<head first: design pattern>> 的书, amazon 上评价也不错, 确实更容易理解, 但是这本书说的显然还是太简单了, 而且举的例子事实上很多会混淆读者的理解.
Applying UML and Patterns
Authors: Craig Larman
Pages: 736
Difficulty: ★★★★
Recommended Degree: ★★★★
Comprehensive Degree: 80%
本书其实题目起的不好, 它实际上整个都在讲软件工程的过程控制, 中间突出UML 和Pattern (不只是design pattern, 还有architectural pattern) 的核心作用. 反正看不懂就看吧. 本书在7 月份的分组考试中起到了非常重要的作用.
另, 本书让我想到上课时我们可爱滴牛老师=v=.
Essential COM
Authors: Don Box
Pages: 464
Difficulty: ★★★★☆
Recommended Degree: ★★★
Comprehensive Degree: 60%
本真是目前来说看的最累的一本. 真不知道M$ 那帮人是怎么设计出那么复杂的COM(Component Object Model) 框架的. 本书破天荒的有两篇前言, 一篇还是COM 的设计者, 说没有人能比Box 先生解释COM 解释的更好了. 事实上, 他解释的我也不怎么能看懂, 而且还严重拖延了我的看书计划. 如果没有严重的自虐倾向, 建议看下面这本书. 本书偏理论, 下面那本偏应用.
最后说一下, 为什么要用COM. M$ 的最初设计是为了跨平台, 解决C++ 的二进制兼容型. 当然, 很嘲的是, 横跨的是Windows 平台.
Inside COM
Authors: Dale Rogerson
Pages: 376
Difficulty: ★★★☆
Recommended Degree: ★★★★
Comprehensive Degree: 80%
本书跟上一本都是COM 的必看书之一. 我在看了上一本前3 章之后, 来看这本, 一晚上扫了100 多页, 真是心情愉快啊. 很多的例子代码能帮助你更好的理解.
Pro C# 2008 and the .NET 3.5 Platform, 4E
Authors: Andrew Troelsen
Pages: 1370
Difficulty: ★★★
Recommended Degree: ★★★
Comprehensive Degree: 90%
公司training 的书, 居然有1000 多页. amazon 上评价不错, 但私以为比较垃圾. 本书把你当作C# 的初学者来对待. 作者还很喜欢用这样的词来开头”simply put, …..”, 当我们都是sx. 所以我也就随便看看, 主要看的是C# 3.0, 3.5 的新特性, 比如WPF, WCF, WF, LINQ 等. 而这些新特性本书却写的非常的不详细, 果然是给初学者的书.
WPF 确实是比较比较好的设计. 这一点不想多说, 光看有很多开源的模仿WPF 的框架就知道这个设计思路有多好.
WCF, WF.. 私以为这两个完全没有必要. WCF 虽然说代码的确比较简单, 但那个配置文件没有Visual Studio 的辅助, 基本是配不来的. WF 感觉就是个半成品, 对于Visual Studio 的依赖性更大.
LINQ 的设计思路是把SQL 集成到.NET 的语言级别, 想法很好. 但是平白增加了语言的复杂性. 光为了支持LINQ 特性, .NET 3.5 就增加了好几个关键字, 以及好几个语言特性. 而这些新加的特性除了LINQ 之外, 很少会在其它库中用到.
丸子评价可能带有片面性, 请自行判断.
Programming Windows, 5E
Authors: Charles Petzold
Pages: 1100
Difficulty: ★★★☆
Recommended Degree: ★★★★☆
Comprehensive Degree: 90%
大师的书啊.. Charles Petzold, 响当当的名字.
本书侧重于介绍Windows GUI 的编程. 一个最最简单的Windows 窗口, 完全调用Windows API 的话大概要70-80 行代码. 而*nix/gtk 大概是20 行以内, Qt 和Java 应该能在10 行以内. Windows API 的代码效率实在有待商榷.
言归正传, 本书从Windows 的窗口消息机制讲起, 消息循环, 消息分发, 屏幕重绘, 控件的使用, Owner-draw, Hook. 然后本书的另外一个大头讲了GDI 的相关内容, 非常的深入. GDI 的使用是一件让人很头痛的事情, 功能本身不怎么强大, 但非常容易写出memory leak, 或者GDI handle leak 的代码. 于是M$ 之后发布了GDI+, 这个GDI 的扩展版本确实比GDI 强大了不少, 而且是OO 的. 但是缺点是, 绘图那个慢啊.. 而且debug 困难.
另外推荐一本<<Programmiong Application for Microsoft Windows>>. 这本测试的是Windows API 的非GUI 部分.
Microsoft Windows Internals, 4E
Authors: Mark E. Russinovich, David A. Solomon
Pages: 976
Difficulty: ★★★★☆
Recommended Degree: ★★★★☆
Comprehensive Degree: 80%
本书也是一本牛书, Windows 内核最权威的书, 前Windows 部门的项目经理甚至为它作序. 就书本身来说, 语言方面真的没人能写出那么拗口的句子了, 从句套从句, 有时候一打段文字它居然就只有一句句子. 但没办法, 书就那么一本.
如果说上面那本偏重的是user mode 的话, 那么本书偏中的就是kernel mode. M$ 的东西, 它就是不开源. 一个可能很容易的概念, 一旦把它作为黑盒来分析的话, 理解起来就会非常的累人, 不像Linux, 所有的代码你都可以看. 书中推荐使用Windbg 来调试内核.
本书跟一般的OS 书一样, 介绍了Windows 的进程, 线程, 内存管理, 缓存, 存储管理, 安全性等一系列的相关的实现及最初的设计思路. 让我发现M$ 确实是很有创造力的一家公司, 很多东西都是在Windows 这个OS 上最先出现的哦, 而且它的设计思路完全不走寻常路=v=.
对于本书的理解非常重要. 我一般写程序调用Windows API 的时候, MSDN 上很多时候会说, 某个函数一定要跟另外一个搭配使用, 某个函数一定要传入什么什么参数, 某个函数一定要在什么什么模式下使用. 看完本书之后, 很多东西都能解答了, 也就用不着硬记了.
另外要说的一点是, M$ Windows 的API 兼容型的确很好, 上个世纪编译的程序一样能在最新的Windows 7 下运行. 但代价就是, Windows 代码的冗余. 看看Linux 内核的开发, 不用的代码, 基本都是标记为deprecated 之后保留几个版本, 然后就直接删掉的. Mac OSX 做的更绝, OSX 之前的代码完全不能用, 而10.5 版本在原来Carbon API的基础上完全重写了一套Cocoa 的API. 当然要我选, 我一定选的是高效的代码. 但M$ 却不是, 这也是M$ 聪明的地方吧.