用VS2019编译librdkafka库

编译好的文件下载:

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 安装时没有选项,需要在完成后要将执行程序添加到系统的环境变量中。

1、开始编译openssl

只编译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 目录下。

2、编译zlib

打开 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_tablelib输出的符号中为_get_crc_table@0
这个肯定是问题所在,在网上看到如下资料:
C与C++的名称修饰符_shifters的博客-CSDN博客_c++ @@
C语言通过不同的调用协议来产生修饰名称,当使用__cdeclC调用协议)时,会在函数名称前加一个下划线,不考虑参数和返回值。使用__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
因此生成的符号当然有个@加上参数长度了
找到问题后就好解决了,修改函数中ZEXPORTZEXPORTVA
#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文件中看到符号了。


3、编译zstd

打开 D:\dev\zstd-1.4.9\build\VS2010目录下的zstd.sln

直接编译 libzstd 和libzstd-dll即可。

4、编译librdkafka-1.5.3

打开librdkafka-1.5.3\win32目录下的librdkafka.sln

编译librdkafka和librdkafkacpp。设置librdkafka项目的包含目录、库目录和lib文件名:

libeay32.lib
ssleay32.lib
zlibstat.lib
libzstd_static.lib

先编译librdkafka,再编译 librdkafkacpp。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值