ARTICLE · 1194684
libxml2 源码编译与 XML 读取验证(x86 / ARM)
libxml2 源码编译与 XML 读取验证(x86 / ARM)目标:在 Ubuntu 虚拟机用源码编译 libxml2,先做 x86(gcc) 验证,再复用同一份源码交叉编译 ARM 版本。 安装目录:x86 →
第 2 步:原生编译,装到
第 4 步:写测试程序
第 5 步:准备测试 XML
目标:在 Ubuntu 虚拟机用源码编译 libxml2,先做 x86(gcc) 验证,再复用同一份源码交叉编译 ARM 版本。 安装目录:x86 → /home/jp/Desktop/xml/lib/x86,ARM → /home/jp/Desktop/xml/lib/arm
第 1 步:下载 libxml2 源码
用官方 release 包(自带 configure,不需要 autotools):
cd ~
wget https://download.gnome.org/sources/libxml2/2.11/libxml2-2.11.5.tar.xz
tar -xf libxml2-2.11.5.tar.xz
cd libxml2-2.11.5
备选:
git clone https://gitlab.gnome.org/GNOME/libxml2.git,但需多跑./autogen.sh,且依赖 autoconf/automake/libtool,验证场景不推荐。
第 2 步:原生编译,装到 /home/jp/Desktop/xml/lib/x86(免 sudo)
./configure \
--prefix=/home/jp/Desktop/xml/lib/x86 \
--without-python \
--without-zlib \
--without-lzma
make -j$(nproc)
make install
说明:
--without-zlib/--without-lzma:去掉 gzip/xz 压缩 XML 支持,免装 zlib1g-dev、liblzma-dev(明文 XML 用不到)。--without-python:不编译 Python 绑定。iconv 保持默认(Ubuntu 的 glibc 内置,无需额外包)。
第 3 步:验证安装结果
头文件在 include/libxml2/libxml/ 这一层(libxml/ 前缀由 #include <libxml/...> 自己补):
ls -l /home/jp/Desktop/xml/lib/x86/lib/libxml2.so*
# 应看到: libxml2.so -> libxml2.so.2.x.y(符号链接)和实体 libxml2.so.2.x.y
ls /home/jp/Desktop/xml/lib/x86/include/libxml2/libxml/parser.h
ls /home/jp/Desktop/xml/lib/x86/include/libxml2/libxml/xpath.h
ls /home/jp/Desktop/xml/lib/x86/lib/pkgconfig/libxml-2.0.pc
第 4 步:写测试程序 test_xml.c
#include<stdio.h>
#include<libxml/parser.h>
#include<libxml/xpath.h>
/* 用 XPath 查询所有匹配节点的文本内容 */
staticvoidquery_by_xpath(xmlDocPtr doc, constchar *xpath)
{
xmlXPathContextPtr ctx = xmlXPathNewContext(doc);
if (ctx == NULL) {
printf("创建 XPath 上下文失败\n");
return;
}
xmlXPathObjectPtr result = xmlXPathEvalExpression((xmlChar *)xpath, ctx);
if (result == NULL) {
printf("XPath [%s] 执行失败\n", xpath);
xmlXPathFreeContext(ctx);
return;
}
xmlNodeSetPtr nodes = result->nodesetval;
printf("XPath [%s] 命中 %d 个节点:\n", xpath,
nodes ? nodes->nodeNr : 0);
for (int i = 0; i < (nodes ? nodes->nodeNr : 0); i++) {
xmlChar *content = xmlNodeGetContent(nodes->nodeTab[i]);
printf(" [%d] %s\n", i, content);
xmlFree(content);
}
xmlXPathFreeObject(result);
xmlXPathFreeContext(ctx);
}
intmain(int argc, char *argv[])
{
constchar *file = (argc > 1) ? argv[1] : "test.xml";
xmlInitParser();
/* 读文件建 DOM,XML_PARSE_RECOVER 容错,和项目里一致 */
xmlDocPtr doc = xmlReadFile(file, "UTF-8", XML_PARSE_RECOVER);
if (doc == NULL) {
printf("解析 XML 失败: %s\n", file);
xmlCleanupParser();
return-1;
}
/* 根节点名称 */
xmlNodePtr root = xmlDocGetRootElement(doc);
printf("根节点: <%s>\n\n", root->name);
/* XPath 查询 */
query_by_xpath(doc, "/root/server/ip");
query_by_xpath(doc, "//port");
xmlFreeDoc(doc);
xmlCleanupParser();
printf("\nXML 读取验证通过\n");
return0;
}
第 5 步:准备测试 XML test.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<server>
<ip>192.168.1.100</ip>
<port>2404</port>
</server>
<devicename="inverter">
<port>502</port>
</device>
</root>
第 6 步:编译
注意 -I 指到 include/libxml2 这一层(不要再加 /libxml,#include <libxml/parser.h> 会自己补上 libxml/):
# 方式 A:直接给路径
gcc -o test_xml test_xml.c \
-I/home/jp/Desktop/xml/lib/x86/include/libxml2 \
-L/home/jp/Desktop/xml/lib/x86/lib \
-Wl,-rpath,/home/jp/Desktop/xml/lib/x86/lib \
-lxml2
# 方式 B:用 pkg-config(自动给对 -I 和 -lxml2)
export PKG_CONFIG_PATH=/home/jp/Desktop/xml/lib/x86/lib/pkgconfig
gcc -o test_xml test_xml.c $(pkg-config --cflags --libs libxml-2.0) \
-Wl,-rpath,/home/jp/Desktop/xml/lib/x86/lib
第 7 步:运行
./test_xml test.xml
预期输出:
根节点: <root>
XPath [/root/server/ip] 命中 1 个节点:
[0] 192.168.1.100
XPath [//port] 命中 2 个节点:
[0] 2404
[1] 502
XML 读取验证通过
附:复用同一份源码做 ARM 交叉编译
cd ~/libxml2-2.11.5
make distclean # 清理 x86 编译产物
./configure \
--host=arm-linux-gnueabihf \
CC=arm-linux-gnueabihf-gcc \
--prefix=/home/jp/Desktop/xml/lib/arm \
--without-python \
--without-zlib \
--without-lzma
make -j$(nproc)
make install
file /home/jp/Desktop/xml/lib/arm/lib/libxml2.so.2
# 应显示 ARM,而不是 x86-64
之后把 /home/jp/Desktop/xml/lib/arm/lib/libxml2.so.2(实体文件,不是符号链接)拷到目标板 /usr/lib/,并把项目 makefile 的 XMLINCPATH 与 -L 指到 /home/jp/Desktop/xml/lib/arm 即可。
要点回顾
头文件真实位置是 include/libxml2/libxml/parser.h,但-I只需到include/libxml2这一层;库装在非系统目录,靠 -Wl,-rpath或LD_LIBRARY_PATH让运行期能找到;--without-zlib --without-lzma --without-python是为了免 sudo 装额外依赖,明文 XML 用不到压缩功能;x86 与 ARM 分两个 --prefix,make install只装头文件 + 库,两者互不覆盖;交叉编译前必须 make distclean清理 x86 的.o产物。















































































