关于C ++:CMake zlib在Windows上构建

CMake zlib build on Windows

我正在尝试使用CMake为Windows构建zlib 1.2.8,但是出现了我不知道如何解决的构建错误。
这是我的CMake GUI:

enter image description here

这将生成没有错误,但当我生成结果解决方案时。 我收到此错误:

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

我不知道如何解决此问题,因此感谢您的帮助。


根据https://wiki.apache.org/httpd/Win64Compilation,非常类似的错误意味着:

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

我能够用一个简单的方法成功构建:

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

我查看了cmake缓存,发现AMD64设置为false,这与cmake-gui窗口显示的不同。 将其设置为true会导致各种构建错误,尽管不是您所显示的错误。

CMakeLists.txt表示此选项用于启用AMD64程序集实施。 只是不这样做似乎是最简单的解决方案。


您需要Visual Studio项目文件中包含的contrib \ masmx64 \ inffas8664.c。
该文件包含inflate_fast函数,该函数调用相应的asm函数。


日期:20180804(2018年8月4日)

好的。

在进行汇编程序加速时,我发现该问题在(当前)最新版本:v1.2.11([GitHub]:madler / zlib-一个庞大而精巧且不引人注目的压缩库(http://zlib.net) )。

好的。

仅在以下情况下发生此错误(显然,操作系统:Win,构建工具链:VStudio和程序集加速)

好的。

  • CMake构建(对于" $ {ZLIB_SRC_DIR} /win32/Makefile.msc"正常运行)
  • x64(AMD64)架构(适用于x86)
  • 好的。

    下面是解压缩期间的"调用堆栈"(顶部->向下等同于外部->内部)。

    好的。

  • 正常情况:

    好的。

  • 膨胀(inflate.c)
  • inflate_fast(inffast.c)
  • ...
  • 组装箱:

    好的。

  • 膨胀(inflate.c)
  • inflate_fast(contrib / masmx64 / inffast8664.c)
  • inffas8664fnc(contrib / masmx64 / inffasx64.asm)
  • ...
  • 好的。

    问题:

    #2。丢失(" $ {ZLIB_SRC_DIR} /CMakeLists.txt"对inffast8664.c一无所知),因此链断了,导致库无效。

    好的。

    解:

    通过添加以下内容使CMakeLists.txt知道该文件:

    好的。

    1
    2
    3
    4
    set(ZLIB_SRCS
        ${ZLIB_SRCS}
        contrib/masmx64/inffas8664.c
    )

    在?#158行(由if(MSVC)elseif (AMD64)条件包围)。

    好的。

    发布完整的更改。

    好的。

    zlib-1.2.11-msvc_x64_asm_speedups.diff:

    好的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    --- 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

    以上是差异。请参见[SO]:从鼠标右键单击PyCharm Community Edition中的上下文菜单来运行/调试Django应用程序的UnitTests? (@CristiFati的答案)(修补程序运行程序部分),介绍如何在Win上应用修补程序(基本上,每行以一个" +"号开头的行都进入,而每行以一个"-"号开头的行都熄灭)。我正在使用Cygwin,顺便说一句。我还将此修补程序提交到了[GitHub]:madler / zlib-VisualStudio女士-x64上的汇编程序加速,但是我不确定它的命运如何,因为有100多个请求正在等待处理。

    好的。

    输出:

    好的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    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

    笔记:

    好的。

  • 我正在使用VStudio 2015
  • 关于以上输出:

  • 为了使输出尽可能小,我仅构建静态版本

  • 出于相同的原因(并且也将其保留为文本),我正在构建" NMake Makefiles"(cmdline构建)
  • 好的。

  • 正在构建inffas8664.c(接近尾声)
  • 好的。

  • 您也可以禁用汇编程序加速(通过在cmake-gui中取消选中AMD64),但这只是一种解决方法
  • 我做了一些粗略的测试(到目前为止,我并没有声称这些结果是通用的),并且汇编程序实现的性能比标准的(调试版本)提高了(以下百分比是执行时间之间的比率)相同的操作(有/无加速):

  • 压缩:?86%
  • 解压缩:?62%
  • 好的。

    好的。

    好的。

    更新#0

    ([GitHub]:madler / zlib-Windows上构建的ASM zlib给出了错误的结果(@madler的评论))指出:

    好的。

    What assembly code is being used? There are a few in zlib's contrib directory. By the way, the stuff in the contrib directory is not part of zlib. It is just there as a convenience and is supported (or not) by those third-party contributors. What I will do is simply remove the offending code from the next distribution.

    Ok.

    编译警告也是如此(每个人都必须已经看到(并且很可能被忽略了)):

    好的。

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

    显然,汇编器的提速与VStudio的配合不太好。此外,在x86上存在几个问题:

    好的。

  • [SO]提出了一个解决方案:SAFESEH图像C ++的模块不安全(@NayanaAdassuriya的回答)(尽管与问题没有直接关系)。简而言之,inffas32.asm和链接器的选项[MS.Docs]:/ SAFESEH(图像具有安全异常处理程序)不匹配。要摆脱它,可以:

    好的。

  • 禁用该选项(在x86 Release中默认启用)
  • 将/ safeseh选项传递给汇编器(ml.exe)
  • 在asm中声明一个
  • 好的。

    由于我使用cmake为cmdline构建,因此我找到了解决方法。在生成CMakeFiles之后(但在构建之前),我指定了它:

    好的。

  • 在flags.make文件(ASM_MASM_FLAGS)中
  • 由于我构建了静态库(对于Debug构建,我也需要符号),因此我还更改了[MS.Docs]:/ Z7,/ Zi,/ ZI(调试信息格式),因此我修改了同一文件(C_FLAGS )
  • 好的。

    我确信cmake提供了一种正确执行上述操作的方法,但是我没有找到它(也没有进行彻底调查)。

    好的。

  • 令人讨厌的是在减压期间出现段错误(访问冲突)。为此,[GitHub]:madler / zlib-需要将inffas32.asm struct / enum绑定到zlib 1.2.9。

    好的。

  • 好的。

    修复这些问题后,一切正常,并且性能改进与x64类似。

    好的。

    好。