CMake zlib is built on Windows

I am trying to create zlib 1.2.8 for Windows using CMake, but I am getting build errors that I don’t know how to fix. Here is my CMake GUI:

enter image description here

This is generated without errors, but when I create the resulting solution. I get this error:

2> ------ Build started: Project: zlib, Configuration: x64 release ------
2> Creating the C: /Users/erik/Documents/zlib/1.2.8/project/zlib-1.2.8-vc10/Release/zlib.lib library and the C: /Users/erik/Documents/zlib/1.2.8 object /project/zlib-1.2.8-vc10/Release/zlib.exp
2> inflate.obj: error LNK2019: unresolved external symbol inflate_fast referenced by the inflate function
2> infback.obj: error LNK2001: unresolved external character inflate_fast
2> C: \ Users \ erik \ Documents \ zlib \ 1.2.8 \ project \ zlib-1.2.8-vc10 \ Release \ zlib.dll: fatal error LNK1120: 1 unresolved external

I do not know how I can fix this, so I appreciate any help.

+13
c ++ c windows cmake zlib
source share
3 answers

According to https://wiki.apache.org/httpd/Win64Compilation a very similar error means:

This means that you have a typo either in -DASMV -DASMINF, or in your OBJ = "inffasx64.obj gvmat64.obj inffas8664.obj", since inflate_fast is defined in inffas8664.c.


I was able to successfully build with a simple:

mkdir C:\Builds\zlib; cd C:\Builds\zlib cmake -G "Visual Studio 12 2013" -A x64 D:\Downloads\zlib-1.2.8\ cmake --build . 

I looked at my CMake cache, and I see that AMD64 is set to false, unlike what your cmake-gui window shows. By setting it to true, for me there are all kinds of build errors, but not the ones you show.

CMakeLists.txt says this parameter should include an AMD64 build implementation. Just without it, this might be the easiest solution.

+12
source share

You need contrib \ masmx64 \ inffas8664.c included in the visual studio project file. This file contains the inflate_fast function, which calls the corresponding asm functions.

+9
source share

Date: 20180804 (Aug 4th - 2018)

Playing with assembly acceleration, I found that the problem is reproducible in the (currently) latest version: v1.2.11 ( [GitHub]: madler / zlib - a very compact, but delicately unobtrusive compression library (http://zlib.net) ) .

This error only occurs (obviously OS: Win, build assembly toolkit: VStudio and build acceleration included) for:

  • cmake build (works fine for "$ {ZLIB_SRC_DIR} /win32/Makefile.msc")
  • x64 architecture (AMD64) (works fine for x86)

The following is the call stack (top β†’ down is equivalent to external β†’ inner) during unpacking.

  • Normal case:

    1. inflate (inflate.c)
    2. inflate_fast (inffast.c)
    3. ...
  • Assembler body:

    1. inflate (inflate.c)
    2. inflate_fast (contrib / masmx64 / inffast8664.c)
    3. inffas8664fnc (contrib / masmx64 / inffasx64.asm)
    4. ...

Problem:

# 2. missing ("$ {ZLIB_SRC_DIR} /CMakeLists.txt" knows nothing about inffast8664.c), so the chain is broken, which leads to an invalid library.

Decision:

Make CMakeLists.txt aware of this file by adding:

 set(ZLIB_SRCS ${ZLIB_SRCS} contrib/masmx64/inffas8664.c ) 

in line ~ # 158 (enclosed in conditional expressions if(MSVC) and elseif (AMD64) ).


Posting full changes as well.

Zlib-1.2.11-msvc_x64_asm_speedups.diff:

 --- CMakeLists.txt.orig 2017-01-15 08:29:40.000000000 +0200 +++ CMakeLists.txt 2018-09-03 13:41:00.314805100 +0300 @@ -79,10 +79,10 @@ endif() set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein - ${ZLIB_PC} @ONLY) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein + ${ZLIB_PC} @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) @@ -136,30 +136,34 @@ set(ZLIB_ASMS contrib/amd64/amd64-match.S) endif () - if(ZLIB_ASMS) - add_definitions(-DASMV) - set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) - endif() + if(ZLIB_ASMS) + add_definitions(-DASMV) + set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) + endif() endif() if(MSVC) if(ASM686) - ENABLE_LANGUAGE(ASM_MASM) + ENABLE_LANGUAGE(ASM_MASM) set(ZLIB_ASMS - contrib/masmx86/inffas32.asm - contrib/masmx86/match686.asm - ) + contrib/masmx86/inffas32.asm + contrib/masmx86/match686.asm + ) elseif (AMD64) - ENABLE_LANGUAGE(ASM_MASM) + ENABLE_LANGUAGE(ASM_MASM) set(ZLIB_ASMS - contrib/masmx64/gvmat64.asm - contrib/masmx64/inffasx64.asm - ) + contrib/masmx64/gvmat64.asm + contrib/masmx64/inffasx64.asm + ) + set(ZLIB_SRCS + ${ZLIB_SRCS} + contrib/masmx64/inffas8664.c + ) endif() - if(ZLIB_ASMS) - add_definitions(-DASMV -DASMINF) - endif() + if(ZLIB_ASMS) + add_definitions(-DASMV -DASMINF) + endif() endif() # parse the full version number from zlib.h and include in ZLIB_FULL_VERSION 

The above is the differential. See [SO]: Run / debug UnitTests of a Django application from the right-click context menu in PyCharm Community Edition? (Reply @CristiFati) (section " Patch on utrunner ") on how to apply patches on Win (basically, each line starting with one "+" sign is entered, and each line starting with one "-" character , disappears). I am using Cygwin, by the way.
I also posted this patch to [GitHub]: madler / zlib - Ms VisualStudio - x64 assembler acceleration , but I'm not sure what its fate is, since more than 100 receive requests are pending.

Output :

 e:\Work\Dev\StackOverflow\q029505121\build\x64>"c:\Install\Google\Android_SDK\cmake\3.6.4111459\bin\cmake.exe" -G "NMake Makefiles" -DAMD64=ON "e:\Work\Dev\StackOverflow\q029505121\src\zlib-1.2.11" -- The C compiler identification is MSVC 19.0.24215.1 -- Check for working C compiler: C:/Install/x86/Microsoft/Visual Studio Community/2015/VC/bin/amd64/cl.exe -- Check for working C compiler: C:/Install/x86/Microsoft/Visual Studio Community/2015/VC/bin/amd64/cl.exe -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Looking for sys/types.h -- Looking for sys/types.h - found -- Looking for stdint.h -- Looking for stdint.h - found -- Looking for stddef.h -- Looking for stddef.h - found -- Check size of off64_t -- Check size of off64_t - failed -- Looking for fseeko -- Looking for fseeko - not found -- Looking for unistd.h -- Looking for unistd.h - not found -- Renaming -- E:/Work/Dev/StackOverflow/q029505121/src/zlib-1.2.11/zconf.h -- to 'zconf.h.included' because this file is included with zlib -- but CMake generates it automatically in the build directory. -- The ASM_MASM compiler identification is MSVC -- Found assembler: C:/Install/x86/Microsoft/Visual Studio Community/2015/VC/bin/amd64/ml64.exe -- Configuring done -- Generating done -- Build files have been written to: E:/Work/Dev/StackOverflow/q029505121/build/x64 e:\Work\Dev\StackOverflow\q029505121\build\x64>"c:\Install\Google\Android_SDK\cmake\3.6.4111459\bin\cmake.exe" --build . --target zlibstatic Scanning dependencies of target zlibstatic [ 5%] Building C object CMakeFiles/zlibstatic.dir/adler32.obj adler32.c [ 10%] Building C object CMakeFiles/zlibstatic.dir/compress.obj compress.c [ 15%] Building C object CMakeFiles/zlibstatic.dir/crc32.obj crc32.c [ 21%] Building C object CMakeFiles/zlibstatic.dir/deflate.obj deflate.c Assembler code may have bugs -- use at your own risk [ 26%] Building C object CMakeFiles/zlibstatic.dir/gzclose.obj gzclose.c [ 31%] Building C object CMakeFiles/zlibstatic.dir/gzlib.obj gzlib.c [ 36%] Building C object CMakeFiles/zlibstatic.dir/gzread.obj gzread.c [ 42%] Building C object CMakeFiles/zlibstatic.dir/gzwrite.obj gzwrite.c [ 47%] Building C object CMakeFiles/zlibstatic.dir/inflate.obj inflate.c [ 52%] Building C object CMakeFiles/zlibstatic.dir/infback.obj infback.c [ 57%] Building C object CMakeFiles/zlibstatic.dir/inftrees.obj inftrees.c [ 63%] Building C object CMakeFiles/zlibstatic.dir/inffast.obj inffast.c Assembler code may have bugs -- use at your own risk [ 68%] Building C object CMakeFiles/zlibstatic.dir/trees.obj trees.c [ 73%] Building C object CMakeFiles/zlibstatic.dir/uncompr.obj uncompr.c [ 78%] Building C object CMakeFiles/zlibstatic.dir/zutil.obj zutil.c [ 84%] Building C object CMakeFiles/zlibstatic.dir/contrib/masmx64/inffas8664.obj inffas8664.c [ 89%] Building ASM_MASM object CMakeFiles/zlibstatic.dir/contrib/masmx64/gvmat64.obj Microsoft (R) Macro Assembler (x64) Version 14.00.24210.0 Copyright (C) Microsoft Corporation. All rights reserved. Assembling: E:\Work\Dev\StackOverflow\q029505121\src\zlib-1.2.11\contrib\masmx64\gvmat64.asm [ 94%] Building ASM_MASM object CMakeFiles/zlibstatic.dir/contrib/masmx64/inffasx64.obj Microsoft (R) Macro Assembler (x64) Version 14.00.24210.0 Copyright (C) Microsoft Corporation. All rights reserved. Assembling: E:\Work\Dev\StackOverflow\q029505121\src\zlib-1.2.11\contrib\masmx64\inffasx64.asm [100%] Linking C static library zlibstatic.lib [100%] Built target zlibstatic 

Notes :

  • I am using VStudio 2015
  • Regarding the above output:
    • To keep the output as small as possible, I only build a static version
      • For the same reason (and also to leave it as text), I create "NMake Makefiles" (cmdline assembly)
    • inffas8664.c is being built (somewhere near the end)
  • You can also disable assembler acceleration ( unchecking AMD64 in cmake-gui), but this will just be a workaround
  • I conducted several rough tests (of course, I do not pretend that these results were general), and there was an improvement in the performance of the assembler implementation compared to the standard (debug versions) (a percentage lower is the ratio between the time spent on the same operation ( with / without) accelerations):
    • Compress: ~ 86%
    • Unpacking: ~ 62%

@ EDIT0 :

Comment by @MarkAdler ( [GitHub]: madler / zlib - building ASM zlib on Windows gives erroneous results ) states:

What assembly code is used? In the zlib contrib directory there are several. By the way, the material in the contrib directory is not part of zlib. This is just for convenience and is supported (or not) by third parties. What I will do is just remove the offensive code from the next release.

Just like a compilation warning (that everyone must have seen (and most likely ignored)):

 Assembler code may have bugs -- use at your own risk 

Obviously, accelerating assembler and VStudio do not get along very well. Moreover, on x86 there are several problems:

  • [SO] offers one fix : the module is unsafe for SAFESEH C ++ image (answer by @NayanaAdassuriya) (although this is not directly related to the question). In short, inffas32.asm and the linker option [MS.Docs]: / SAFESEH (the image has safe exception handlers) do not match. To get rid of this, either:

    • Disable this option (enabled by default in x86 Release)
    • Pass the / safeseh option to the collector (ml.exe)
    • Declare one in asm

    Since I use cmake to build for cmdline, I found a workaround for this. After generating CMakeFiles (but before the build) I specify this:

    I'm sure cmake offers a way to do the above properly, but I did not find it (nor did I fully investigate it).

  • The unpleasant thing is segfault (access violation) during decompression. This requires [GitHub]: madler / zlib - inffas32.asm struct / enum to bind to zlib 1.2.9 .

After the fix, everything works fine, and the performance improvements are similar to x64.

+7
source share

All Articles