查看文章 |
编译Windows版本的GNU工具——VC篇
2008-12-22 20:14
编译Windows版本的GNU工具 tombkeeper@xfocus 2004.3.23 算不得技术文章,只是过程颇有曲折,写个step by step出来备忘,省得下次从头再来。 一开始只打算折腾几种软件,后来逐渐目标多了,有些软件也不是GNU的,继续用这个标题就有不实之嫌。不过没关系,就当它是GNU的好了。其实,我一直认为Windows都是GNU的。 下载地址: http://www.openssl.org/source/openssl-0.9.7d.tar.gz http://curl.haxx.se/download/curl-7.11.1.tar.gz http://ftp.gnu.org/pub/gnu/wget/wget-1.9.1.tar.gz http://www.gzip.org/zlib/zlib-1.2.1.tar.gz ftp://wuarchive.wustl.edu/mirrors/gnu/gzip/gzip-1.2.4.tar.gz ftp://sources.redhat.com/pub/bzip2/v102/bzip2-1.0.2.tar.gz http://ftp.cvshome.org/release/stable/cvs-1.11.14/cvs-1.11.14.tar.bz2 ftp://ftp19.us.postgresql.org/pub/postgresql/source/v7.4.2/postgresql-7.4.2.tar.gz http://www.stunnel.org/download/stunnel/src/stunnel-4.05.tar.gz http://the.earth.li/~sgtatham/putty/latest/putty-src.zip 准备编译环境: 要确定系统上安装了VC 6以上版本、masm32、Win32版本MingW的gcc、perl、cygwin。并且相应的path、include、lib等环境变量都设置好了,注意在“include”变量中把openssl的include目录加进去。如果不打算用汇编编译openssl也可以不装masm32。 要编译支持https的wget和curl就需要openssl的,所以要先编译openssl。 编译openssl及静态链接库: ======================== 编译openssl自身的可执行文件最好是用masm32 + VC,所以在命令提示符中顺序键入: perl Configure VC-WIN32 ms\do_masm.bat 完成后,就可以在out32目录中找到libeay32.lib和ssleay32.lib,现在把这两个库复制到编译环境的lib目录中去。 如果要用MingW来产生静态库,那么不能相信openssl的install.w32文件里面说的,用那个ms\mingw32.bat能编译成功。指望在命令提示符下用Win32版本的MingW编译openssl是不现实的,倒不是编译器的问题,主要是编译脚本中的那些unix命令一般的windows系统上是没有的。而且,里面用的那些符号链接之类,Windows也不支持。一定要的Cygwin环境下才能顺当。 顺序输入以下命令: tar zxf openssl-0.9.7d.tar.gz cd openssl-0.9.7d ./Configure mingw make 现在我们就有了libcrypto.a和libssl.a这两个静态链接库。 编译wget: ========= Windows版本的wget在键入--help参数的时候总是试图打开wget.hlp,非常讨厌,在编译之前,先打开src\main.c,注释掉这一行: ws_help (exec_name); 还要注释掉src\mswindows.c中的ws_help函数。 Wget提交的请求特征比较明显,服务器可以很容易分辨出来。下面将其尽量修改得接近于IE 6.0。 打开src\http.c,找到下面这段代码: else { useragent = (char *)alloca (10 + strlen (version_string)); sprintf (useragent, "Wget/%s", version_string); } 修改为 else { STRDUP_ALLOCA (useragent,"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); } 找到: #define HTTP_ACCEPT "*/*" 修改为: #define HTTP_ACCEPT "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, \ application/x-shockwave-flash, application/vnd.ms-powerpoint, \ application/vnd.ms-excel, application/msword, */*" 找到“ sprintf (request, "\”的那一段,修改为: sprintf (request, "\ %s %s HTTP/1.0\r\n\ Accept: %s\r\n\ User-Agent: %s\r\n\ Host: %s%s%s%s\r\n\ %s%s%s%s%s%s%s%s%s%s\r\n", command, full_path, HTTP_ACCEPT, useragent, squares_around_host ? "[" : "", u->host, squares_around_host ? "]" : "", port_maybe ? port_maybe : "", request_keep_alive ? request_keep_alive : "", referer ? referer : "", cookies ? cookies : "", wwwauth ? wwwauth : "", proxyauth ? proxyauth : "", range ? range : "", pragma_h, post_content_type ? post_content_type : "", post_content_length ? post_content_length : "", opt.user_header ? opt.user_header : ""); 在命令提示符中输入: configure.bat --msvc 然后修改src\Makefile文件,将CFLAGS中的“/MT”改为“/MD”,在DEFS中增加“/DHAVE_STRPBRK”并在LIBS里加上“gdi32.lib”,然后运行nmake。 如果要使用MingW编译出来的静态库就需要将刚才编译的libssl.a libcrypto.a以及MingW目录下lib\gcc-lib\mingw32\2.95.3-8\libgcc.a复制到src目录,再nmake。 编译curl: ========= curl依赖于zlib,所以要先编译zlib: nmake -f win32/Makefile.msc 我们就得到了zlib.lib这个静态链接库。 然后修改curl的src和lib两个目录下的Makefile.vc6文件,在里面分别先设置好正确的OPENSSL_PATH和ZLIB_PATH,src目录下的Makefile.vc6文件中也要加上OPENSSL_PATH的定义(curl-7.13.1之后的版本已经没有这个问题了)。并在src目录下的Makefile.vc6文件的cl.exe参数中加上/DUSE_MANUAL,还可以curlr.res相关的内容去掉。 因为我们定义了USE_MANUAL,但是,curl的hugehelp.c文件中包含的相关文档是西文编码的,在中文系统上显示有问题,按照以下方法处理: 1、用IE打开hugehelp.c,另存为一个文本文件的时候选择GB2312编码。 2、在新的hugehelp.c中删除所有“­”。然后就可以替换src目录下的老hugehelp.c。 (curl-7.13.1之后的版本已经没有这个问题了) 下面修改curl的默认User-Agent,找到main.c中的: if(NULL == config->useragent) { /* set non-zero default values: */ snprintf(useragent, sizeof(useragent), CURL_NAME "/" CURL_VERSION " (" OS ") " "%s", curl_version()); config->useragent= useragent; } 修改为: if(NULL == config->useragent) { /* set non-zero default values: */ snprintf(useragent, sizeof(useragent), "%s", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); config->useragent= useragent; } 打开lib\http.c,找到: http->p_accept = "Accept: */*\r\n"; 修改为: http->p_accept = "Accept: image/gif, image/x-xbitmap, image/jpeg, \ image/pjpeg, application/x-shockwave-flash, application/vnd.ms-powerpoint, \ application/vnd.ms-excel, application/msword, */*\r\n"; 然后开始编译: nmake vc-ssl 就得到curl.exe了 编译gzip: ========= 编译之前,将gzip.h、util.c、gzip.c中的“strlwr”替换为“mystrlwr”。因为gzip是在linux 上开发的,可能开发人员没想到windows上本身就有一个名为strlwr的函数。 然后,nmake -f nt\Makefile就可以了。 如果不想链接msvcrt.dll,可以修改nt\Makefile,在!include <ntwin32.mak>后加上: cc = cl.exe link = link.exe DEFS = -DWIN32 cflags = -c -O2 -nologo cvarsdll = linkdebug = conflags = -nologo -release conlibsdll = 还要删除下面的“DEFS =”,否则我们定义的-DWIN32就没了。 编译bzip2: ========== 没有任何障碍,直接运行“nmake -f makefile.msc”。 Windows版本的MackFile默认不会产生bunzip2.exe,不过bunzip2和bzip2的区别只是文件名不同,程序检测到自己文件名是bunzip2的时候,默认就执行解压缩操作而已。所以我们可以自己拷贝出一个bunzip2.exe。 编译cvs: ======== 没有任何障碍,直接运行“nmake -f cvsnt.mak CFG="cvsnt - Win32 Release"” 编译postgresql客户端: ===================== 修改src\bin\psql\win32.mak,将 "..\..\interfaces\libpq\Release\libpqdll.lib" 修改为 "..\..\interfaces\libpq\Release\libpq.lib" 然后运行在src\目录下运行nmake -f win32.mak就可以得到静态版本的psql.exe。 编译stunnel: ============ stunnel自己带的makefile是用gcc的,不过在和上面用gcc编译好的静态ssl库链接时有问题。好在stunnel的程序员很照顾我,代码都是ANSI C,可以不出任何问题地用VC编译。先把libeay32.lib和ssleay32.lib拷贝到src目录,然后用下面这些命令: cl -DUSE_WIN32 -DHAVE_OPENSSL -c stunnel.c cl -DUSE_WIN32 -DHAVE_OPENSSL -c ssl.c cl -DUSE_WIN32 -DHAVE_OPENSSL -c client.c cl -DUSE_WIN32 -DHAVE_OPENSSL -c protocol.c cl -DUSE_WIN32 -DHAVE_OPENSSL -c sthreads.c cl -DUSE_WIN32 -DHAVE_OPENSSL -c log.c cl -DUSE_WIN32 -DHAVE_OPENSSL -c options.c cl -DUSE_WIN32 -DHAVE_OPENSSL -c sselect.c cl -DUSE_WIN32 -DHAVE_OPENSSL -c gui.c rc resources.rc link -out:stunnel.exe ws2_32.lib gdi32.lib user32.lib shell32.lib comdlg32.lib libeay32.lib ssleay32.lib stunnel.obj ssl.obj client.obj protocol.obj sthreads.obj log.obj options.obj sselect.obj gui.obj resources.res 编译putty: ========== Putty是一个很不错的SSH客户端,源代码下载后直接用VC的IDE界面打开编译,没有任何问题。 对Putty的改造主要是针对配置信息的。Putty将Session、SSH Host Key等信息都保存在注册表中,我们需要让它全部保存到配置文件中去。 配置文件相关的函数是源代码目录下的WINDOWS\WINSTORE.C,Refdom曾经对这下面的函数进行了改写,将对注册表的操作转换为对配置文件的操作。但是配置文件会被保存在当前目录下而不是程序所在的目录。 在WINDOWS\WINSTORE.C中加上: extern char SessionsFile[MAX_PATH+2]; extern char SshHostKeysFile[MAX_PATH+2]; 并修改其余代码,将这两个文件作为保存Session和SSH Host Key的配置文件。 打开WINDOWS\WINDOW.C,在文件前面添加: #define SESSIONSFILE "Sessions.ini" #define SSHHOSTKEYSFILE "SshHostKeys.ini" char SessionsFile[MAX_PATH+2]; char SshHostKeysFile[MAX_PATH+2]; 找到WinMain函数中的这段代码: strcpy(r, PUTTY_HELP_CONTENTS); if ( (fp = fopen(b, "r")) != NULL) { help_has_contents = TRUE; fclose(fp); } else help_has_contents = FALSE; 在之后添加: strcpy(r, SESSIONSFILE); strcpy(SessionsFile, b); strcpy(r, SSHHOSTKEYSFILE); strcpy(SshHostKeysFile, b); 然后编译,就可以得到一个把配置信息保存在自身所在目录下的Putty.exe。 以上修改仅针对Putty相关代码,并不会对PLink、PSftp等生效。 |
类别:技术探索 research
| 浏览()
| 评论 (3)