由于汇编单独生成obj导致的编译zlib-1.2.11中的minizip时出现LINK 2019,找不到match_init函数问题解决方案

为了压缩解压zip,下载了zlib库。库用CMake生成vs 2019的sln,没有问题。但是zlib本身压缩得到的数据没有zip文件头,不能输出当zip用。

不过zlib里带了minizip库,可以实现压缩到zip文件和从zip文件解压。
打开contrib\vstudio\vc14,打开sln。
在这里插入图片描述
把zlibvc作为启动项目,把生成目标从dll改成lib(我打算静态编译)。编译,ok,得到了lib。

但在编译minizip项目时遇到问题了。
在这里插入图片描述
说是没找到match_init的实现。我草草搜了一下,发现deflate.c里看到了match_init。

我怀疑是符号表生成有问题,使用lib.exe /list查看,deflate.obj确实在lib里。
在这里插入图片描述
准备从lib导出obj,发现自己傻了,lib本来就是obj组成的。找到中间过程中生成的obj。
在这里插入图片描述
使用objdump -t 查看obj内符号表,发现match_init在里面。(但是地址为0,这里我发现了不对劲,但也很疑惑)
在这里插入图片描述
确认了符号表的名称确实是C方式的,不是C++方式的(C++方式生成的符号表会带很多@&&这样的符号,用于区分重载函数)。这也正常,因为zlibvc项目里没有.cpp文件,都是.c文件。

这就更蹊跷了,符号表里有,但怎么就链接不上呢?

我想起,match_init的符号表里地址是0,重新返回去deflate.c去看,发现match_init只有声明没有实现,之前草草看了一眼并没有确认一下。

想着match_init的实现可能在其他文件里,我在解决方案里搜也没找到,我就又下了一个DocFetcher来做全文搜索。
在这里插入图片描述
搜完只有deflate.c里的match_init声明处出现过。这就更奇葩了。实现到底在哪儿?

终于想起libvc编译时执行了一个bat。
在这里插入图片描述
在masmx64发现了可疑的obj,用objdump -t查看:
在这里插入图片描述
居然藏在这里面!是由汇编单独编译的obj。

把这个obj加入到minizip的依赖项中,编译通过!

为了让minizip不用单独链接这个obj,我打算把gvmat64.obj插入到zlibwapi.lib里。lib /out:命令可以做到。

在libvc的项目属性里,在 生成事件 - 生成后事件 里的命令行,加入:

lib /out:x64\ZlibDllDebug\zlibwapi.lib x64\ZlibDllDebug\zlibwapi.lib ..\..\masmx64\gvmat64.obj

zlibwapi.lib出现了两次,是因为/out:代表输出文件名,后面的参数代表输入obj,要同时输入原来的lib和加入的obj,才能合并两者。

是参考了这篇得到的提示:
LIB: Adding Files to Existing Library
在这里插入图片描述

现在不用单独在minizip中链接gvmat64.obj了。编译通过。


后记:

我后来发现了zlibvc项目的本意是动态库,我强行改成静态编译的,所以才有这么多问题。

zlibstat的本意是静态库,用zlibstat生成lib,然后minizip链接zlibstat.lib,一点问题都没有。

白饶了一大个圈子。不过探索过程倒是可以供读者参考,不知道有没人会碰上和我一样的问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值