夜雨聆风学习资料网

ARTICLE · 1194684

libxml2 源码编译与 XML 读取验证(x86 / ARM)

libxml2 源码编译与 XML 读取验证(x86 / ARM)

目标:在 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 产物。

相关学习资料