openssl unicode编译以及VC++2015环境下的问题
这几天需要使用openssl,前期本机上保存的目录不知道哪天整理的时候删除了,索性下载最新的自己编译一下;
在最新版的openssl(openssl-1.0.2e),编译过程中出现了很多问题,这里主要汇总一下:
使用环境:win10/VC2015
1、如何编译unicode 版openssl?
在配置时添加选项:
perl Configure VC-WIN32 -DUNICODE -D_UNICODE
2、如何使得编译的openssl库在debug程序时不报错?
修改ms\do_xx.bat文件即可,如下所示,加上deubg就会生成*.dbg输出目录,否则生成release版本
perl util\mk1mf.pl debug no-asm VC-WIN32 >ms\nt.mak
3、如何生成静态库?
nmake -f ms\ntdll.mak
nmake -f ms\nt.mak
后一项编译生成静态库
4、编译库可能存在以下问题:
1>libeay32.lib(cryptlib.obj) : error LNK2001: 无法解析的外部符号 __vsnwprintf
1>libeay32.lib(cryptlib.obj) : error LNK2001: 无法解析的外部符号 __vsnprintf
1>libeay32.lib(cryptlib.obj) : error LNK2001: 无法解析的外部符号 ___iob_func
1>libeay32.lib(pem_lib.obj) : error LNK2001: 无法解析的外部符号 ___iob_func
1>libeay32.lib(ui_openssl.obj) : error LNK2001: 无法解析的外部符号 ___iob_func
1>libeay32.lib(v3_utl.obj) : error LNK2001: 无法解析的外部符号 _sscanf
1>libeay32.lib(dso_win32.obj) : error LNK2001: 无法解析的外部符号 _sprintf
以下是解决方法:
对于1.2个问题是由于_vsntprintf在系统库中已经有定义了,所以先注掉cryptlib.c中的定义,然后再把_vsntprintf 使用的地方用UNICODE宏区分开,见如下所示:
1 /* 2 # if defined(_UNICODE) || defined(__UNICODE__) 3 # define _vsntprintf _vsnwprintf 4 # else 5 # define _vsntprintf _vsnprintf 6 # endif 7 */ 8 9 ...... 10 11 #if defined(_UNICODE) || defined(__UNICODE__) 12 _vsnwprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap); 13 #else 14 _vsnprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap); 15 #endif //#if defined(_UNICODE) || defined(__UNICODE__)
对于3.4.5三个问题(___iob_func)是由于VC++2015对此宏的定义不一样导致的,需要修改的地方是e_os.h文件
1 # if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(_DLL) && defined(stdin) 2 # if _MSC_VER>=1300 && _MSC_VER<1600 3 4 # undef stdin 5 # undef stdout 6 # undef stderr 7 FILE *__iob_func(); 8 # define stdin (&__iob_func()[0]) 9 # define stdout (&__iob_func()[1]) 10 # define stderr (&__iob_func()[2]) 11 # elif _MSC_VER>1800 /*VC2015*/ 12 FILE *__acrt_iob_func(unsigned) 13 # define stdin (__acrt_iob_func(0)) 14 # define stdout (__acrt_iob_func(1)) 15 # define stderr (__acrt_iob_func(2)) 16 # elif _MSC_VER<1300 && defined(I_CAN_LIVE_WITH_LNK4049) 17 # undef stdin 18 # undef stdout 19 # undef stderr 20 /* 21 * pre-1300 has __p__iob(), but it's available only in msvcrt.lib, 22 * or in other words with /MD. Declaring implicit import, i.e. with 23 * _imp_ prefix, works correctly with all compiler options, but 24 * without /MD results in LINK warning LNK4049: 'locally defined 25 * symbol "__iob" imported'. 26 */
第6个问题,修改v3_utl.c
1 #if defined(_UNICODE) || defined(__UNICODE__) 2 if (wscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) 3 #else 4 if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) 5 #endif //
第7个问题,修改dso_win32.c
1 #if defined(_UNICODE) || defined(__UNICODE__) 2 if (transform) 3 wprintf(translated, "%s.dll", filename); 4 else 5 wprintf(translated, "%s", filename); 6 #else 7 if (transform) 8 sprintf(translated, "%s.dll", filename); 9 else 10 sprintf(translated, "%s", filename); 11 #endif //#if defined(_UNICODE) || defined(__UNICODE__)
5、编译过程中的其它问题都可以在网上直接找到,如nasm的问题等。
作者:SCPlatform
Email:SCPlatform@outlook.com
本文旨在学习、交流使用,任何对文章内容的出版、印刷,对文章中提到的技术的商业使用时,请注意可能存在的法律风险。