Linux下g++链接xerces-c出现XMLException类型信息未定义引用问题
问题根因定位
所有报错本质和LD_LIBRARY_PATH配置没有任何关系,之前的排查方向完全走偏了——LD_LIBRARY_PATH是程序运行时查找动态库的环境变量,编译链接阶段的符号查找完全不依赖这个变量,哪怕把这个变量配满了无效路径,也不会导致链接报undefined reference。
特殊现象解释
换xerces3.1.1还是报xercesc_3_2的相关报错,完全是正常现象
原因非常简单:你根本没有重新编译gcam本身的代码。之前生成的libgcam.a是对着xerces3.2版本的头文件编译出来的,目标文件内部硬编码依赖的就是xercesc_3_2命名空间下的所有符号,哪怕你把系统里的xerces换成3.1.1版本,只要老的静态库不删掉重编,链接时永远会找3.2版本对应的符号,报的错自然和之前一模一样。
config.log里的内容分类
- 打印出来的
ACLOCAL/AUTOCONF这类内容只是configure流程输出的自动化开发工具检测结果,不是报错,完全不用处理。 - 真正的异常是
undefined reference to clock_gettime、undefined reference to wcsupr:说明xerces本身的configure检测环节就没通过,最终编译产出的库本身就是残缺的,根本没有实现XMLException、XMLString这类类的代码,哪怕你路径指对了,链接的时候也找不到对应的符号。其中clock_gettime报错是新glibc的常见兼容问题——高版本glibc把这个函数从libc挪到了librt库,configure默认检测没带上-lrt参数,就会导致库编译不完整。
你当前编译链接命令的硬伤
拆解开你贴的g++命令就能看到几个直接导致报错的问题:
- 无效的库搜索路径:你在
-L参数里加了src/xercesc/dom、src/xercesc/util两个目录,这俩是xerces的源码子目录,根本没有编译产出的库文件,纯属无效路径。 - 参数拼接语法错误:命令里连续出现两个
-Wl,-rpath参数,第二个rpath后面没有接实际路径,直接跟了main.o,按照gcc的参数解析规则,会把后面的main.o当成rpath的参数值,导致链接流程异常。 - 没有安装完整可用的xerces库:你一直直接用xerces源码目录下的文件当库用,既没有跑install步骤把库装到统一的独立目录,也没有解决configure阶段的检测报错,本身库就是残缺的。
分步解决流程
- 重编译完整可用的xerces库,不要直接在源码目录下操作
- 新建独立的安装目录,比如
/home/201999800003/xerces-install,不要在源码根目录直接跑make install导致文件散落得到处都是。 - 跑configure时显式补上缺失的链接参数解决检测失败问题:执行
./configure --prefix=/home/201999800003/xerces-install CXXFLAGS="-std=c++14" LDFLAGS="-lrt",补上librt的链接配置解决clock_gettime的检测报错。 - 依次执行
make、make install完成编译后,检查安装目录下的lib文件夹,确认存在完整的libxerces-c.so、libxerces-c.a文件,用nm libxerces-c.so | grep "XMLException"命令验证文件里确实有对应的类符号,别用源码目录下的残缺文件当链接库。
- 新建独立的安装目录,比如
- 修正gcam编译的Makefile配置
- 把原来
-L参数里的src/xercesc/dom、src/xercesc/util两个无效路径全部删掉,替换成刚才xerces安装路径下的lib目录:-L/home/201999800003/xerces-install/lib。 - 排查Makefile里的参数拼接逻辑,为什么会出现空的
-Wl,-rpath,项,把空参数删掉,避免参数解析错误。 - 确认库的链接顺序:
-lxerces-c必须放在-lgcam的后面,因为libgcam.a里的代码依赖xerces的符号,链接器必须先扫描到依赖方,再去被依赖的库里找实现,顺序反了就会报undefined reference。
- 把原来
- 清理所有老的编译产物重新编译gcam
把之前生成的所有.o目标文件、libgcam.a静态库全部删掉,重新走一遍gcam的编译流程,让所有源文件对着新的、完整的xerces头文件生成目标文件,就不会再出现换了xerces版本还报旧版本符号的问题。 - 正确配置环境变量
把之前配的LD_LIBRARY_PATH里的src/xercesc/dom、src/xercesc/util无效路径删掉,只保留xerces安装路径下的lib目录:export LD_LIBRARY_PATH=/home/201999800003/xerces-install/lib:$LD_LIBRARY_PATH。这个变量只在你运行gcam.exe程序的时候起作用,配不配都不影响编译链接阶段的报错。
内容的提问来源于stack exchange,提问作者panday1995
相关产品推荐
相关产品推荐

