我的目标是理解GNU库自动构建系统。我知道可以使用巧尽心思构建的manully项目成功地构建libiconv,并添加大量的源代码文件。所以这个问题更多的是学术性的,而不是实用性的。我也考虑到了对于gnulib的Windows平台没有官方的支持。
按照INSTALL.windows提供的构建libiconv的指导,我在构建iconv与动态MSVC运行时( cl /MD或cl /MDd)时遇到了下一个编译错误。
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_malloc.h(85): error C2375: 'rpl_free': redefinition; different linkage
D:\work\env\build-env\msvc2019\shared-debug-shared-runtime\iconv\srclib\string.h(599): note: see declaration of 'rpl_free'配置调用:
/cygdrive/d/work/src/libiconv/configure --enable-relocatable --enable-static=no --enable-shared=yes --host=x86_64-w64-mingw32 --prefix=/iconv 'CFLAGS=/MDd /Z7 /Od /D_DEBUG /RTC1' 'CXXFLAGS=/MDd /Z7 /Od /D_DEBUG /RTC1'编译器调用:
compile cl /nologo -DHAVE_CONFIG_H -DEXEEXT=\".exe\" -I. -I/cygdrive/d/work/src/libiconv/srclib -I.. -I../lib -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1 /D_WIN32_WINNT=_WIN32_WINNT_WIN7 /DWIN32 /D_WIN64 /D_UNICODE /D_CRT_SECURE_NO_WARNINGS /MDd /Z7 /Od /D_DEBUG /RTC1 /D_DLL -c -o stat.obj `cygpath -w '/cygdrive/d/work/src/libiconv/srclib/stat.c'`
stat.c配置生成的iconv/srclib/string.h .h
/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
_GL_EXTERN_C void free (void *);
#if 1
# if (1 && !defined free \
&& !(defined __cplusplus && defined GNULIB_NAMESPACE))
# define free rpl_free
_GL_EXTERN_C void free (void *);
# endif
#endifWinSDK/include/ucrt/corecrt_malloc.h
_ACRTIMP _CRT_HYBRIDPATCHABLE
void __cdecl free(
_Pre_maybenull_ _Post_invalid_ void* _Block
);WinSDK/include/ucrt/co瑞t.h定义下一步
#ifndef _ACRTIMP
#if defined _CRTIMP && !defined _VCRT_DEFINED_CRTIMP
#define _ACRTIMP _CRTIMP
#elif !defined _CORECRT_BUILD && defined _DLL
#define _ACRTIMP __declspec(dllimport)
#else
#define _ACRTIMP
#endif
#endif经过研究和研究,我发现gnulib(作为libiconv的GNU autoconf构建系统的一部分)用自己的实现替换了不令人满意的函数调用。rpl_free是从C运行时替换常规空闲()函数的替代名称,因为MSVC函数不被识别为符合POSIX的函数。在我看来,没有任何选项可以告诉配置,而不是替换not功能。一个带有环境变量REPLACE_FREE=0的黑客做到了这一点,我已经关闭了函数替换。
然而,MSVC编译器仍然抱怨不同的链接。我相信,当gnulib声明其免费()函数签名时,MSVC运行时使用__declspec(dllimport)导出它的API函数,没有额外的属性。
我想知道,是否有一条“铺平的道路”来构建libiconv(或其他利用gnulib的GNU库),使用原始的autoconf系统链接到动态MSVC运行时?在不修改gnulib m4文件的情况下,我能做到这一点吗?
发布于 2021-12-31 00:12:24
回答您的一般问题
是的,(Autoconf,可选Automake,Libtool和Gnulib)的GNU项目通常可以用MSVC编译器构建。compile脚本将传统Unix风格的编译器选项转换为用于MSVC的编译器选项。
GNU、gettext和其他包的经验表明,这是完全可能的,这些包基本上都有相同的INSTALL.windows指令。但是它通常需要在构建系统中进行调整,以处理dllimport/dllexport,与反斜杠相关的问题,以及Cygwin语法与本机Windows语法中的文件名,等等。特别要注意的是,在Windows上,从共享库导出变量是多多少少的;导出函数要简单得多。
您通常可以忽略MSVC关于函数的dllimport/ can导出的警告。这个警告仅仅意味着编译器在每个函数调用中增加了一两条额外的指令。
Gnulib确实覆盖了许多libc函数,比如free(),这样应用程序的源代码就不会出现杂乱无章的解决方案。每次重写的确切原因是记录在案。对于空闲()函数,它是文档化的这里。虽然Gnulib有方法禁用特定的解决方案,但在这种情况下,我强烈反对它:错误的errno值的影响可能是任何应用程序的严重故障。
回答关于GNU libiconv的特定问题
您遇到了特定的构建问题;包的自述文件告诉您报告错误的位置。
GNU包有发行版。最新的GNU libiconv版本1.16没有这个问题。通常,在尝试从git存储库编译最新源代码之前,最好使用最新版本。这将是更简单的,因为它通常是在发布之前进行测试的。
https://stackoverflow.com/questions/70525755
复制相似问题