尝试使用 libxml2 静态构建应用程序
我遇到类似错误undefined reference to `__imp_xmlTextReaderRead'
删除
-static
选项,效果完美。我使用的命令是:
gcc -o myapp.exe `xml2-config --cflags` -I /mingw64/include myapp.c `xml2-config --libs` -static
要纠正对
__imp_xml*
形式的符号的未定义引用,请预定义预处理器宏
LIBXML_STATIC
在您的
gcc
命令行上,如下所示:gcc -DLIBXML_STATIC -o myapp.exe `xml2-config --cflags` \
-I /mingw64/include myapp.c `xml2-config --libs` -static
为什么?
您正在 Windows 上使用
gcc
。
__imp_xml*
形式的未定义引用表明您的编译器正在按照您的预期工作 代码将在运行时动态链接到
libxml2.dll
,为此将链接到 在构建时该 DLL 的导入库
libxml2.lib
。
__imp_xml*
参考文献将通过以下方式解决:
libxml2.dll
代理中的构建时导入库。您的编译器正在将这些引用发出到 释放在源代码中找到的
__declspec(dllimport) xml*
形式的 DLL 导入声明,
预处理后。
这些
dllimport
声明的存在证明编译器正在看到预处理的代码
not旨在启用针对
libxml2
的静态链接,即针对静态库
libxml2.a
的链接, 其中定义的符号没有
__imp_
前缀。
但是你是一个指定的静态链接(
-static
)。这禁止链接器考虑导入库, 即使它们可用。通过 shell 扩展在命令行中产生的库选项
xml2-config --libs
的形式为
-l xml2 [...]
。在存在
-static
的情况下,链接器将尝试 通过仅扫描其搜索目录以查找
-l xml2
,而不是
libxml2.a
来解决 libxml2.lib
因此,正如您所观察到的,当您从项目中删除
__imp_xml*
选项时,未定义的
-static
参考错误就会消失。 命令行 - 因为链接器可以自由搜索
libxml2.lib
。由于您想要静态链接,编译器不应该看到用于动态链接的预处理代码 连锁。但是,无论编译器可以解决这个问题,
-static
选项都不会这样做,因为
这是一个链接选项,不影响编译。
预处理器确实会影响编译,并且
libxml2
使用预处理器宏 LIBXML_STATIC
作为
switch 来决定其公共头文件中的 API 函数声明是否会从预处理中出现
以 __declspec(dllimport)
为前缀,或以 __declspec(dllexport)
为前缀,或两者都不带。相关的
预处理器样板文件可在头文件 libxml2/libxml/exmlexports.h
中找到,该文件将包含在
您在自己的代码中包含的任何 libxml2
公共头文件。
...[cut]...
#if defined(_WIN32) || defined(__CYGWIN__) /* We are on Windows */
#ifdef LIBXML_STATIC /* We are building for static linkage *
#define XMLPUBLIC /* Our public API symbols are left as seen */
/* Else we are building for dynamic linkage
#elif defined(IN_LIBXML) /* If we are building libxml2 itself */
#define XMLPUBLIC __declspec(dllexport) /* DLL export our API symbols */
#else /* We are building client code */
#define XMLPUBLIC __declspec(dllimport) /* DLL import our API names */
#endif
...[cut]...
(评论都是我的。)
这就是为什么你需要在编译开始之前定义
LIBXML_STATIC
,
每个命令行选项-DLIBXML_STATIC
,抑制客户端的默认生成
假定动态链接的代码。
但是...
预先警告,并非所有未定义的符号链接错误都一定会随着__imp_xml*
错误而消失。 如果您指定
-static
,则链接器必须找到程序所需的all 库的静态版本: 不仅是
libxml2
,还包括
libxml2
递归依赖的所有内容。有相当多的 这些,您很可能还没有安装它们的静态版本。如果您确实拥有所有这些,您的应用程序将是一个非常大的可执行文件,但功率重量比非常小。你 可能已经或可能没有考虑到这一点。如果链接
libxml2
本身足以满足您的需求 静态地,但不是它的整个依赖链,你也可以这样做。请参阅GNU 链接器的命令行选项 了解相关链接器选项
-Bstatic
和
-Bdynamic
,以及GCC 的命令行选项 关于选项
-Wl
,了解
gcc
如何将链接器特定的选项传递给链接器。