Openssl和libetpan库的win32编译笔记

来源:互联网 发布:seo文章页面优化 编辑:程序博客网 时间:2024/05/03 05:28
过程还是很简单的,重要参考http://blog.chinaunix.net/u1/50394/showart_411514.html
只是遇到的问题有所不同,可能由于我使用的版本不同
首先是Openssl
1、到http://www.openssl.org/source/下载openssl-1.0.0a.tar.gz,并解压
2、到http://www.activestate.com/Products/下载ActivePerl-5.12.1.1201-MSWin32-x86-292674.msi,并安装
3、我只有VC6开发环境,其中没有nasm和nasmw两个命令,下载拷贝到Microsoft Visual Studio\VC98\Bin,编译需要用。
4、运行cmd。
a)运行>vcvars32.bat
b)cd命令进入入openssl的目录下面
c)运行>perl Configure VC-WIN32
d)运行>ms\do_masm
e)运行>nmake -f ms\ntdll.mak(动态库编译)
编译时在app\s_cb.c的733行等4处出现struct in6_addr未定义错误,查了一下,ws2tcpip.h中定义的是struct in_addr6 和 IN6_ADDR,所以加入define in6_addr in_addr6解决。
f)运行>nmake -f ms\nt.mak(静态库编译)
g)去out32dll拷贝出动态库,out32dll拷贝出静态库,复制出Openssl目录下的inc32目录就全了。
openssl编译可看http://www.stunnel.org/examples/ms-ca-newbie.html
VC2005下面编译libetpan
    libetpan源代码build-windows目录有VC7的项目文件,打开编译即可。
    libetpan源码版本不同有些需要注意。
     a)V0.42一次性通过了。
     b)V0.52在src/data_types/connect.c中用到EINPROGRESS宏定义,在win32中是WSAEINPROGRESS,改一下即可。
c)V1.0
在src/data_types/connect.c中用到EINPROGRESS宏定义,在win32中是WSAEINPROGRESS,改一下即可。
在src/data_types/mailstream_ssl.c->ssl_data_close()中,使用socket_data变量明显错误,改为ssl_data。
源码V0.52以后没有src/data_types/cinthash.cpp和src/windows/wsocket.cpp,从工程中去掉。
在src/low-level/imap/quota*.c几个文件没有加上,需要加上,否则出现连接时找不到变量和函数。
VC6下的编译。
    libetpan源代码中build-windows目录中的VC项目是VC7的,VC8下编译基本没有什么问题。我用小工具将VC7项目文件转换成VC6的,效果还不错。
    VC6还要注意以下几点:
1、修改工程设置中的“输出路径”,原来项目中定义的“$(ConfigurationName)”支持不好。
2、工程选项中去掉转换过来时带的PRECOMP_VC7_TOBEREMOVE参数,乱来奇怪。
3、在windows/libetpan-config.h中加入typedef unsigned short UINT16的定义,VC6中没定义这个。会出现有关uint16_t的错误。
4、在windows/inet_aton.c中有与ULONG_PTR类型相关的错误,改改代码,直接用unsigned long代替。
5、libcrypto=libeay32,libssl=ssleay32。
    如果openssl和libetpan都是在VC8下编译没有问题,但在混编过程中出现连接时symbol _iob()错误。
该错误主要是由于静态库在VC6编译而主程序在VC2005编译,大家用的CRT不同。解决办法,代码中增加
#ifdef __cplusplus
extern "C"
#endif
FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]};
此错误的产生根源:
在VC6的stdio.h之中有如下定义
_CRTIMP extern FILE _iob[];
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])
stdin、stdout、stderr是通过查_iob数组得到的。所以,VC6编译的程序、静态库只要用到了printf、scanf之类的函数,都要链接_iob数组。
而在vc2005中,stdio.h中变成了
_CRTIMP FILE * __cdecl __iob_func(void);
#define stdin (&__iob_func()[0])
#define stdout (&__iob_func()[1])
#define stderr (&__iob_func()[2])
_iob数组不再是显式的暴露出来了,需要调用__iob_func()函数获得。所以vc6的静态库链接VC2005的C运行库就会找不到_iob数组.
通过重新定义
FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]};
就把vc6需要用到的_iob数组搞出来了
Mingw编译libetpan。
    etpan没有提供直接mingw编译方法,但是mingw也是gcc嘛,看看他的Makefile和config.h。
    但是openssl也需要编译为mingw版的。编译方法很简单,如下
    运行ms\mingw32.bat
    或
    perl Configure -DMK1MF_BUILD mingw
    make

    再待一下。。。