使用 Visual Studio (2017)、IF_NAMESIZE undefined 构建 Apache APR 1.7

Build Apache APR 1.7 with Visual Studio (2017), IF_NAMESIZE undefined

尝试使用 Visual Studio 在 Windows 上构建 apr 1.7,尝试了 2017 年和 2013 年。

构建项目(调试|x86)或编译时,例如dso.c 如果收到以下错误消息:

1>dso.c
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2143: syntax error: missing ')' before '*'
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2143: syntax error: missing '{' before '*'
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2059: syntax error: ')'
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2061: syntax error: identifier 'apr_winapi_pfn_if_indextoname'
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2059: syntax error: ';'
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2513: ' ': no variable declared before '='
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2065: 'apr_winapi_pfn_if_indextoname': undeclared identifier
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): warning C4047: '=': 'int' differs in levels of indirection from 'int *(__cdecl *)(NET_IFINDEX,PCHAR)'
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2146: syntax error: missing ';' before identifier 'apr_load_dll_func'
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2100: illegal indirection
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): error C2064: term does not evaluate to a function taking 1207 arguments
1>c:\dev\log4cxx\apr\include\arch\win32\apr_arch_misc.h(503): warning C4033: 'apr_winapi_if_indextoname' must return a value

我已成功构建 1.65 版(在应用 http://letcoderock.blogspot.com/2017/09/build-log4cxx-trunk-on-windows-by.html or Apache Cross Compilation Error ./gen_test_char: cannot execute binary file 的提示后)

比较两个版本的 apr_arch_misc.h,我注意到 DLL_IPHLPAPI 是新的枚举 apr_dlltoken_e 并且 Intelisense 抱怨

APR_DECLARE_LATE_DLL_FUNC(DLL_IPHLPAPI, PCHAR, NETIOAPI_API_, if_indextoname, 0, (
    NET_IFINDEX InterfaceIndex,
    PCHAR       InterfaceName),
    (InterfaceIndex, InterfaceName));

和"expecting a ')'"。 如果将 NETIOAPI_API_ 更改为 WINAPI。不知道这是否正确,但现在可以编译文件(在 运行 上面的技巧与 gen_test_char.exe 之后)。

但之后我 运行 进入下一个问题:

1>sockaddr.c
1>network_io\unix\sockaddr.c(144): error C2065: 'IF_NAMESIZE': undeclared identifier
1>network_io\unix\sockaddr.c(144): error C2057: expected constant expression
1>network_io\unix\sockaddr.c(144): error C2466: cannot allocate an array of constant size 0
1>network_io\unix\sockaddr.c(144): error C2133: 'scbuf': unknown size
1>network_io\unix\sockaddr.c(1274): error C2065: 'IF_NAMESIZE': undeclared identifier

我已经在 linux/cygwin 中使用 gcc 成功构建了 apr。我已经研究了 IF_NAMESIZE 的预处理器替换,在这里它被 44 替换了。但是我找不到定义或设置的位置。

有人知道如何解决这个问题吗?以上对 WINAPI 的更改是否正确?

只需使用 cmake 构建 Visual Studio 解决方案:

cmake -G "Visual Studio 15 2017" -A x64

.sln 已正确设置并构建解决方案,没有任何错误。甚至 gen_test_char.exe 正在构建。

也许 apr 项目应该让 cmake 构建说明在他们的网站上更加突出。

以防其他人也遇到这个问题:我使用 cmake + nmake 来构建 APR,但它仍然对我不起作用。

原因是我有旧的编译标志来支持 Windows XP:

cmake -DMIN_WINDOWS_VER=0x0501 ...

调查Iphlpapi.h,似乎只有从 Vista 开始才支持当前版本的 APR netioapi.h 和其他网络 headers 用户:

#if (NTDDI_VERSION >= NTDDI_VISTA)

#include <netioapi.h>

#endif // (NTDDI_VERSION >= NTDDI_VISTA)

因此,为了使编译工作正常,只需删除该 cmake 选项或指定一个高于 0x0600(相当于 Vista)的值。

如 README 文件中所写:

Note you must manually modify the include\apr.hw file before you build to change default options

所以我刚刚从 apr-1.7.0\include\apr.hw 中删除了行 #define _WIN32_WINNT 0x0501 和 运行 nmake -f Makefile.win。对我来说很好。 VS2017 工具,Windows 10.