最经我用MinGW编译OpenSSL的过程中发生了很多问题,不过好在已经解决了,现在写出来以备查询
以OpenSSL-0.9.8l为例:
前略(下载,解压)注意要安装Perl,如果你只是用来安装OpenSSL的可以下ActivePerl,以后还有其它用的下strawberry-perl
(先说问题)
使用MinGW编译OpenSSL时我发现有以下问题
1、解压目录/ms/mingw32.bat内的路径有问题,直接使用会报找不到文件
2、编译过程中报错(内容如下)
./crypto/des/set_key.c:68: error: static declaration of '_hide_DES_check_key' follows non-static declaration ./crypto/des/set_key.c:68: error: previous declaration of '_hide_DES_check_key' was here
mingw32-make: *** [tmp/set_key.o] Error 1
3、其它编译问题(我没有遇到,不过似乎官方有准备)
4、使用静态链接库libcrypto.a时
libcrypto.a(rand_win.o)(.text+0xb13):rand_win.c: undefined reference to '_CreateDCA@16'
libcrypto.a(rand_win.o)(.text+0xb24):rand_win.c: undefined reference to '_CreateCompatibleDC@4'
等错误
解决法案:
一、解决这一种问题方法是将mingw32.bat从 解压目录/ms 下面复制回 解压目录 下面,即将mingw32.bat放在解压后的OpenSSL的根目录下
二、编译过程中出现上述的报错,问题出在 解压目录/e_os2.h 中:264行
# define OPENSSL_IMPLEMENT_GLOBAL(type,name) /
extern type _hide_##name; /
type *_shadow_##name(void) { return &_hide_##name; } /
static type _hide_##name
其中的static修饰,解决方法有两个:
1、将static修饰删了,不过这样可能会改变原来作者的意图
2、这个方法有点麻烦需要修改 解压目录/e_os2.h 解压目录/crypto/des/enc_read.c 解压目录/crypto/des/set_key.c这三个文件
=======================================================================================
解压目录/e_os2.h:
定位第255行(参照句出现的行号,并非需要修改的直接行号)做如下操作,每行前的 - 号代表删除行,+ 号代表添加行:
The way it's done allows definitions like this:
// in foobar.c
- OPENSSL_IMPLEMENT_GLOBAL(int,foobar) = 0;
+ OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
// in foobar.h
OPENSSL_DECLARE_GLOBAL(int,foobar);
#define foobar OPENSSL_GLOBAL_REF(foobar)
*/
#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
- # define OPENSSL_IMPLEMENT_GLOBAL(type,name) /
- extern type _hide_##name; /
- type *_shadow_##name(void) { return &_hide_##name; } /
- static type _hide_##name
+ # define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) /
+ type *_shadow_##name(void) /
+ { static type _hide_##name=value; return &_hide_##name; }
# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
#else
- # define OPENSSL_IMPLEMENT_GLOBAL(type,name) OPENSSL_GLOBAL type _shadow_##name
+ # define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value
# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
# define OPENSSL_GLOBAL_REF(name) _shadow_##name
#endif
=======================================================================================
解压目录/crypto/des/enc_read.c
定位第64行(参照句出现的行号,并非需要修改的直接行号)做如下操作,每行前的 - 号代表删除行,+ 号代表添加行:
/* This has some uglies in it but it works - even over sockets. */
/*extern int errno;*/
- OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode)=DES_PCBC_MODE;
+ OPENSSL_IMPLEMENT_GLOBAL(int,DES_rw_mode,DES_PCBC_MODE);
=======================================================================================
解压目录/crypto/des/set_key.c
定位第66行(参照句出现的行号,并非需要修改的直接行号)做如下操作,每行前的 - 号代表删除行,+ 号代表添加行:
#include "des_locl.h"
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#endif
- OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key); /* defaults to false */
+ OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0); /* defaults to false */
=======================================================================================
三、至于其它编译问题(不是上面的问题,至于是什么问题,我不知道,因为我没有出现过)官方给出的解决办法是,在执行mingw32.bat时添加no-asm参数,即在控制台先执行(转到根目录,或者将根目录添加到 环境变量 中去)
mingw32 no-asm
四、这是因为libcrypto.a需要静态链接Gdi32.lib(libgdi32.a),直接添加Gdi32.lib或libgdi32.a就可以了(一定要添加在libcrypto.a后面,即-I libcrypto.a -I libgdi32.a),使用dllwrap的也可以直接添加-lgdi32参数,使用Code::Blocks的在链接器设置(Linker Setting)->链接库(link libraries)的libcrypto.a下方添加libgdi32.a
P.S MinGW(GCC)中没有VC中的#pragma comment预处理命令,它只能用执行参数-I 来添加静态或导入库