今天遇到个奇怪的问题,在编译minizip(https://github.com/nmoinvaz/minizip) 的时候,指定静态zlib库(zlibstatic.lib),但是编译完成后,使用会出现:
error LNK2019: 无法解析的外部符号 _crc32,该符号在函数 _mz_crypt_crc32_update 中被引用
error LNK2019: 无法解析的外部符号 _deflate,该符号在函数 _mz_stream_zlib_deflate 中被引用
error LNK2019: 无法解析的外部符号 _deflateEnd,该符号在函数 _mz_stream_zlib_close 中被引用
error LNK2019: 无法解析的外部符号 _inflate,该符号在函数 _mz_stream_zlib_read 中被引用
error LNK2019: 无法解析的外部符号 _inflateEnd,该符号在函数 _mz_stream_zlib_close 中被引用
error LNK2019: 无法解析的外部符号 _deflateInit2,该符号在函数 mz_stream_zlib_open 中被引用
error LNK2019: 无法解析的外部符号 _inflateInit2,该符号在函数 _mz_stream_zlib_open 中被引用
debug\zipTest.exe : fatal error LNK1120: 7 个无法解析的外部命令
按照理论上说,已经静态编译,所有源码都应该包含在minizip.lib中,但是还是会提示该错误,只能在项目中再去链接zlib.lib一次才能正常编译,而且exe的导入模块中还会包含zlib.dll。
问题就是上面描述的这样,搜索了大量文章(ZLIB_WINAPI)经测试没任何效果,只能自己琢磨,首先用了set VERBOSE=1
查看了nmake执行的命令,结果坑爹的是cmake会把大量参数指定到类似nm20D6.tmp的文件中:
D:\Develop\msvc2019\VC\Tools\MSVC\14.22.27905\bin\Hostx86\x86\cl.exe @D:\Temp\nm20D6.tmp filter_encoder.c
而且边编译边删除,想保存下来查看内容都很难操作,之后只能禁止删除权限来获取:
内容倒是获取到了,但是搜索发现没有出现zlibstatic.lib相关内容,其中:
[100%] Linking C static library minizip.lib
E:\Downloads\cmake\bin\cmake.exe -P CMakeFiles\minizip.dir\cmake_clean_t
arget.cmake D:\Develop\msvc2019\VC\Tools\MSVC\14.22.27905\bin\Hostx86\x86\link.exe /
lib /nologo /machine:X86 /out:minizip.lib @CMakeFiles\minizip.dir\objects1.rsp
看了下object1.rsp文件,保存了所有obj文件名,尝试将D:/zlib/lib/zlibstaticd.lib
添加进去编译,之后发现编译出来的lib文件相比之前大了一些,测试了一下没问题了。
目前这个只是临时方案,不清楚是否跟CMakefile相关,对cmake相关并不是太了解,只是觉得如果cmake这样太复杂还不如手动敲命令来的直观。
后续
之后又经过几次测试,花了点时间将minizip的CMakefile转换成了xmake,然后使用—verbose参数显示编译过程。
发现zlibstatic.lib根本没有参与到链接过程中去(使用IDA之类工具可以查看lib文件信息)。
也就是说如果将minizip编译成静态库根本不用指定ZLIB_LIBRARY
,静态库无法链接进静态库文件中去(合并成单独一个lib文件),只能在项目使用中链接minizip.lib
和zlibstatic.lib
或者zlib.lib
(需要包含zlib.dll)。
参考链接:
https://blog.csdn.net/newchenxf/article/details/51735600
https://github.com/nmoinvaz/minizip/issues/374
https://stackoverflow.com/questions/2157629/linking-static-libraries-to-other-static-libraries
没有评论:
发表评论