赞
踩
编译好的文件下载:
librdkafka-1.5.3.zip_rdkafka32位-桌面系统文档类资源-CSDN下载
Librdkafka依赖于zlib、Zstd和OpenSSL库,编译之前要先编译这三个库,本文只编译32位版本,64位编译方法类似。各库版本为:zlib-1.2.8,zstd-1.4.9、openssl-1.0.2p、librdkafka-1.5.3。
先编译openssl,需要openssl-1.0.2p nasm-2.14rc15-installer-x64.exe ActivePerl-5.26.1.2601-MSWin32-x64-404865.exe 。
下载所需工具
准备工作
安装 Perl 和 NASM,默认下一步下一步就可以了。Perl 安装的时候记得勾选将执行程序添加到系统环境变量中。NASM 安装时没有选项,需要在完成后要将执行程序添加到系统的环境变量中。
只编译32位版本,debug模式,使用多线程调试静态链接运行库。
使用 x86 Native Tools Command Prompt for VS 2019,以管理员方式运行。
打开后切换到 D:\openssl-1.0.2p 目录,执行如下命令生成 makefile 文件。
perl configure VC-WIN32
如果是生成 64 位则
使用 x86 Native Tools Command Prompt for VS 2019,以管理员方式运行。
perl configure VC-WIN64A
成功后如下所示:
如果你要编译 debug 版本,则修改 ms/do_nasm.bat 文件,将原来
perl util\mkfiles.pl >MINFO
perl util\mk1mf.pl nasm VC-WIN32 >ms\nt.mak
perl util\mk1mf.pl dll nasm VC-WIN32 >ms\ntdll.mak
perl util\mk1mf.pl nasm BC-NT >ms\bcb.mak
perl util\mkdef.pl 32 libeay > ms\libeay32.def
perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
修改为:
perl util\mkfiles.pl >MINFO
perl util\mk1mf.pl nasm debug VC-WIN32 >ms\nt.mak
perl util\mk1mf.pl dll nasm debug VC-WIN32 >ms\ntdll.mak
perl util\mk1mf.pl nasm BC-NT >ms\bcb.mak
perl util\mkdef.pl 32 libeay > ms\libeay32.def
perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
就是将第二行和第三行编译选项增加了 debug。修改完成后执行 ms/do_nasm.bat。
ms\do_nasm.bat
运行后结果如下:
修改完成执行如下命令开始编译(如果想编译成 dll,则执行 nmake -f ms\ntdll.mak,编译前要修改 ms\ntdll.mak 将 CFLAG 的 /MD 属性修改为 /MT,与你调用项目匹配):
nmake -f ms\nt.mak
如果没有错误,几分钟后编译后的文件就会生成于 D:\openssl-1.0.2p\out32.dbg 目录下。
打开 zlib-1.2.8\contrib\vstudio\vc11目录下的zlibvc.sln,打开项目后,其中的zlibstat是编译为静态库,zlibvc是编译为动态库,本例使用静态库。
需要修改
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
为:
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPIV
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
编译生成的库为
ZlibStatDebug\zlibstat.lib
和
ZlibStatRelease\zlibstat.lib。
编译动态库时会出现:error LNK2026 模块对于 SAFESEH 映像是不安全的,解决方法:
1.打开该项目的“属性页”对话框。
2.单击“链接器”文件夹。
3.单击“命令行”属性页。
4.将 /SAFESEH:NO 键入“其他选项”框中,然后点击应用。
出现错误 LNK1118 “VERSION”语句中的语法错误 zlibvc D:\dev\zlib-1.2.8\contrib\vstudio\vc11\zlibvc.def 4
将zlibvc.def文件的VERSION 1.2.8 这一行注释掉。
写了一个例子想测试一下,结果出现链接错误:
1>unzip.obj : error LNK2019: 无法解析的外部符号_inflateInit2_,该符号在函数_unzOpenCurrentFile3 中被引用
1>unzip.obj : error LNK2019: 无法解析的外部符号_inflate,该符号在函数_unzReadCurrentFile 中被引用
1>unzip.obj : error LNK2019: 无法解析的外部符号_crc32,该符号在函数_unzReadCurrentFile 中被引用
1>zip.obj : error LNK2001: 无法解析的外部符号_crc32
1>unzip.obj : error LNK2019: 无法解析的外部符号_inflateEnd,该符号在函数_unzCloseCurrentFile 中被引用
1>zip.obj : error LNK2019: 无法解析的外部符号_get_crc_table,该符号在函数_zipOpenNewFileInZip4_64 中被引用
1>zip.obj : error LNK2019: 无法解析的外部符号_deflateInit2_,该符号在函数_zipOpenNewFileInZip4_64 中被引用
1>zip.obj : error LNK2019: 无法解析的外部符号_deflate,该符号在函数_zipWriteInFileInZip 中被引用
1>zip.obj : error LNK2019: 无法解析的外部符号_deflateEnd,该符号在函数_zipCloseFileInZipRaw64 中被引用
1>C:\test\testzlib\Debug\testzlib.exe : fatal error LNK1120: 8 个无法解析的外部命令
刚开始百思不得其解,后来用lib命令查看zlibstat.lib的符号,发现其中的函数名称会多一个@,比如
_get_crc_table在lib输出的符号中为_get_crc_table@0
这个肯定是问题所在,在网上看到如下资料:
(C与C++的名称修饰符_shifters的博客-CSDN博客_c++ @@)
C语言通过不同的调用协议来产生修饰名称,当使用__cdecl(C调用协议)时,会在函数名称前加一个下划线,不考虑参数和返回值。使用__fastcall函数,在函数名称前后各加一@符号,后跟参数长度,不考虑返回值。例如extern “C” int __fastcall Test(int n)的修饰名称为@Test@4. 对于使用标准调用协议(__stdcall)的函数,在函数名称前加一下划线,后跟参数长度,不考虑返回值。如extern “C” int __stdcall Test (int n, int m) 的修饰名称为_Test@8
因此再回到zibstat的工程中
发现函数的定义中有ZEXPORT:
比如(zlib.h):
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
而ZEXPORT的定义为(zconf.h):
# define ZEXPORT WINAPI
而WINAPI的定义为(windef.h)
#define WINAPI __stdcall
因此生成的符号当然有个@加上参数长度了
找到问题后就好解决了,修改函数中ZEXPORT为ZEXPORTVA
#define ZEXPORTVA WINAPIV----->#define WINAPIV __cdecl
注意需要修改头文件和源代码。
另外
1、发现zlibvc.def文件在静态库中是不起作用的,只对动态库的输出符号有作用,这导致走了一点弯路
2、输出符号的方式,在/contrib/vstudio/vc9/x86/ZlibStatDebug下调用
>"c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat"
创建编译环境,然后调用>dumpbin /symbols zlibstat.lib >t1.txt
即可在t1.txt文件中看到符号了。
打开 D:\dev\zstd-1.4.9\build\VS2010目录下的zstd.sln
直接编译 libzstd 和libzstd-dll即可。
打开librdkafka-1.5.3\win32目录下的librdkafka.sln
编译librdkafka和librdkafkacpp。设置librdkafka项目的包含目录、库目录和lib文件名:
libeay32.lib
ssleay32.lib
zlibstat.lib
libzstd_static.lib
先编译librdkafka,再编译 librdkafkacpp。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。