正在尝试构建 xerces c++ 解析器。 Netbeans 和命令行构建错误未定义对“xercesc_3_2 ...”的引用

Posted

技术标签:

【中文标题】正在尝试构建 xerces c++ 解析器。 Netbeans 和命令行构建错误未定义对“xercesc_3_2 ...”的引用【英文标题】:Attempting to build xerces c++ parser. Netbeans & command line build error undefined reference to `xercesc_3_2...' 【发布时间】:2019-12-20 01:41:51 【问题描述】:

我试图在基于 Linux RedHat 的 NetBeans 项目中 Xerces c++ 解析器库。

我遵循了构建指南 (https://xerces.apache.org/xerces-c/build-3.html#UNIX)

1) 下载 tar.gz "xerces-c-3.2.2.tar.gz"

2) 使用“tar xvzf”提取到 tar 用户 my /home/myuser/projects 为 xerces-c-3.2.2

3) 导航到 /home/myuser/projects/xerces-c-3.2.2 并在 linux 上的命令行发出

./configure --disable-shared --disable-static

有很多输出但没有错误,下一个:

4) 我在同一目录中运行了 "make"。创建了很多 .o 和 .lo 文件...

输出是这样的:

 CXX      src/SEnumVal/SEnumVal.o
  CXXLD    SEnumVal
  CXX      src/StdInParse/StdInParse.o
  CXX      src/StdInParse/StdInParseHandlers.o
  CXXLD    StdInParse
  CXX      src/XInclude/XInclude.o
  CXXLD    XInclude

    make[2]: Leaving directory `/home/myUser/projects/xerces-c-3.2.2/samples'
    make[2]: Entering directory `/home/myUser/projects/xerces-c-3.2.2'
    make[2]: Leaving directory `/home/myUser/projects/xerces-c-3.2.2'
    make[1]: Leaving directory `/home/myUser/projects/xerces-c-3.2.2'

没有错误,下一步:

5) cd /src & ls -a 显示.libs 目录已构建。

cd 进入 /home/myUser/projects/xerces-c-3.2.2/src/.libs 显示:

libxerces-c.a  libxerces-c.la  libxerces-c.lai

6) 尝试根据编程指南 (http://xerces.apache.org/xerces-c/program-3.html) 运行示例代码:

#include <xercesc/util/PlatformUtils.hpp>
// Other include files, declarations, and non-Xerces-C++ initializations.

using namespace xercesc;

int main(int argc, char* argv[])

  try 
    XMLPlatformUtils::Initialize();
  
  catch (const XMLException& toCatch) 
    // Do your failure processing here
    return 1;
  

  // Do your actual work with Xerces-C++ here.

  XMLPlatformUtils::Terminate();

  // Other terminations and cleanup.
  return 0;

在按下项目属性、c++ 编译器、包含目录和添加以下路径之前

1)../../projects/xerces-c-3.2.2/src/xercesc

2)../../projects/xerces-c-3.2.2/src

3)../../projects/xerces-c-3.2.2/src/.libs

并包含标题的路径:

1) ../../projects/xerces-c-3.2.2/src/xercesc/util/PlatformUtils.hpp

2) ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLUni.hpp

3) ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLException.hpp

我还去了项目属性,链接器并添加了“附加库目录”和“运行时搜索目录”

1)../../projects/xerces-c-3.2.2/src/xercesc

2)../../projects/xerces-c-3.2.2/src

3)../../projects/xerces-c-3.2.2/src/.libs

最后我在 Netbeans 中按下 clean & build,报告编译器命令和错误:

cd '/home/myUser/NetBeansProjects/SOFF_test'
/usr/bin/gmake -f Makefile CONF=Debug clean
"/usr/bin/gmake" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .clean-conf
gmake[1]: Entering directory `/home/myUser/NetBeansProjects/SOFF_test'
rm -f -r build/Debug
gmake[1]: Leaving directory `/home/myUser/NetBeansProjects/SOFF_test'

CLEAN SUCCESSFUL (total time: 209ms)

cd '/home/myUser/NetBeansProjects/SOFF_test'
/usr/bin/gmake -f Makefile CONF=Debug
"/usr/bin/gmake" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
gmake[1]: Entering directory `/home/myUser/NetBeansProjects/SOFF_test'
"/usr/bin/gmake"  -f nbproject/Makefile-Debug.mk dist/Debug/GNU-Linux/soff_test
gmake[2]: Entering directory `/home/myUser/NetBeansProjects/SOFF_test'
mkdir -p build/Debug/GNU-Linux
rm -f "build/Debug/GNU-Linux/newmain.o.d"

g++    -c -g -I../../projects/xerces-c-3.2.2/src/xercesc -I../../projects/xerces-c-3.2.2/src -include ../../projects/xerces-c-3.2.2/src/xercesc/util/PlatformUtils.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLUni.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLException.hpp -MMD -MP -MF "build/Debug/GNU-Linux/newmain.o.d" -o build/Debug/GNU-Linux/newmain.o newmain.cpp

mkdir -p dist/Debug/GNU-Linux

g++     -o dist/Debug/GNU-Linux/soff_test build/Debug/GNU-Linux/newmain.o -L../../projects/xerces-c-3.2.2/src/ -L../../projects/xerces-c-3.2.2/src/xercesc/ -L../../projects/xerces-c-3.2.2/src/.libs -Wl,-rpath,'../../projects/xerces-c-3.2.2/src/' -Wl,-rpath,'../../projects/xerces-c-3.2.2/src/xercesc/util/'
build/Debug/GNU-Linux/newmain.o: 

In function `main':
/home/myUser/NetBeansProjects/SOFF_test/newmain.cpp:26: undefined reference to `xercesc_3_2::XMLUni::fgXercescDefaultLocale'

/home/myUser/NetBeansProjects/SOFF_test/newmain.cpp:26: undefined reference to `xercesc_3_2::XMLPlatformUtils::Initialize(char const*, char const*, xercesc_3_2::PanicHandler*, xercesc_3_2::MemoryManager*)'

/home/myUser/NetBeansProjects/SOFF_test/newmain.cpp:36: undefined reference to `xercesc_3_2::XMLPlatformUtils::Terminate()'

build/Debug/GNU-Linux/newmain.o:(.gcc_except_table+0x10): undefined reference to `typeinfo for xercesc_3_2::XMLException'

collect2: error: ld returned 1 exit status
gmake[2]: *** [dist/Debug/GNU-Linux/soff_test] Error 1
gmake[2]: Leaving directory `/home/myUser/NetBeansProjects/SOFF_test'
gmake[1]: *** [.build-conf] Error 2
gmake[1]: Leaving directory `/home/myUser/NetBeansProjects/SOFF_test'
gmake: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 456ms)

如果参考g++编译命令:

  g++    -c -g -I../../projects/xerces-c-3.2.2/src/xercesc -I../../projects/xerces-c-3.2.2/src -include ../../projects/xerces-c-3.2.2/src/xercesc/util/PlatformUtils.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLUni.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLException.hpp -MMD -MP -MF "build/Debug/GNU-Linux/newmain.o.d" -o build/Debug/GNU-Linux/newmain.o newmain.cpp


    g++     -o dist/Debug/GNU-Linux/soff_test build/Debug/GNU-Linux/newmain.o -L../../projects/xerces-c-3.2.2/src/ -L../../projects/xerces-c-3.2.2/src/xercesc/ -L../../projects/xerces-c-3.2.2/src/.libs -Wl,-rpath,'../../projects/xerces-c-3.2.2/src/' -Wl,-rpath,'../../projects/xerces-c-3.2.2/src/xercesc/util/'
    build/Debug/GNU-Linux/newmain.o: 

您可以看到包含代码示例的标题:

-include ../../projects/xerces-c-3.2.2/src/xercesc/util/PlatformUtils.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLUni.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLException.hpp

还为链接器提供了 .libs 和 src(可能不是必需的)文件夹

-L../../projects/xerces-c-3.2.2/src/ -L../../projects/xerces-c-3.2.2/src/xercesc/ -L../../projects/xerces-c-3.2.2/src/.libs

NetBeans 能够看到#include &lt;xercesc/util/PlatformUtils.hpp&gt;& 我什至可以点击进入 xerces PlatformUtils.hpp 并通过 IDE 查看函数实现。

1) 为什么即使 IDE 可以解析标头,NetBeans 也无法编译和查找 Xerces 库?

2) 最终,我该如何解决这个问题? (我的包含是否正确?)

更新:

上述原始错误“未定义的引用”已根据用户“jww”的建议得到解决,请参阅 cmets。

1) 我将#include 更改为#include "xercesc/util/PlatformUtils.hpp" 2) 还通过项目属性添加了 libxerces-c.a,然后是链接器、库菜单。

这些是 NetBeans 生成的更新的构建命令:

  g++    -c -g -I../../projects/xerces-c-3.2.2/src/xercesc -I../../projects/xerces-c-3.2.2/src -I../../projects/xerces-c-3.2.2/src/.libs -include ../../projects/xerces-c-3.2.2/src/xercesc/util/PlatformUtils.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLUni.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLException.hpp -MMD -MP -MF "build/Debug/GNU-Linux/newmain.o.d" -o build/Debug/GNU-Linux/newmain.o newmain.cpp
    mkdir -p dist/Debug/GNU-Linux


    g++     -o dist/Debug/GNU-Linux/soff_test build/Debug/GNU-Linux/newmain.o -L../../projects/xerces-c-3.2.2/src/ -L../../projects/xerces-c-3.2.2/src/xercesc/ -L../../projects/xerces-c-3.2.2/src/.libs -Wl,-rpath,'../../projects/xerces-c-3.2.2/src/.libs' -Wl,-rpath,'../../projects/xerces-c-3.2.2/src' -Wl,-rpath,'../../projects/xerces-c-3.2.2/src/xercesc' -lxerces-c

可以看到添加了-lxerces-c标志。

现在我自然有新的错误,与示例代码无关,而是在 xerces 库代码的深处,它们再次与“未定义的引用”性质有关。

See below:

/home/anaim/projects/xerces-c-3.2.2/src/xercesc/util/NetAccessors/Curl/CurlNetAccessor.cpp:70: undefined reference to `curl_global_init'

/home/anaim/projects/xerces-c-3.2.2/src/xercesc/util/NetAccessors/Curl/CurlNetAccessor.cpp:70: undefined reference to `curl_global_init'

../../projects/xerces-c-3.2.2/src/.libs/libxerces-c.a(CurlNetAccessor.o): In function `xercesc_3_2::CurlNetAccessor::cleanupCurl()':
/home/anaim/projects/xerces-c-3.2.2/src/xercesc/util/NetAccessors/Curl/CurlNetAccessor.cpp:78: undefined reference to `curl_global_cleanup'

../../projects/xerces-c-3.2.2/src/.libs/libxerces-c.a(CurlURLInputStream.o): In function `xercesc_3_2::CurlURLInputStream::readMore(int*)':
/home/anaim/projects/xerces-c-3.2.2/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.cpp:269: undefined reference to `curl_multi_perform'

Etc, etc...

我还通过添加 -lcurl 和 -lpthread 解决了上述错误和更多问题

这是最新的编译命令(同样是它的 NetBeans 生成的)

g++    -c -g -I../../projects/xerces-c-3.2.2/src/xercesc -I../../projects/xerces-c-3.2.2/src -include ../../projects/xerces-c-3.2.2/src/xercesc/util/PlatformUtils.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLUni.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/XMLException.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/NetAccessors/Curl/CurlNetAccessor.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/NetAccessors/Curl/CurlURLInputStream.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/util/Transcoders/ICU/ICUTransService.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/xinclude/XIncludeDOMDocumentProcessor.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/xinclude/XIncludeLocation.hpp -include ../../projects/xerces-c-3.2.2/src/xercesc/xinclude/XIncludeUtils.hpp -MMD -MP -MF "build/Debug/GNU-Linux/newmain.o.d" -o build/Debug/GNU-Linux/newmain.o newmain.cpp
mkdir -p dist/Debug/GNU-Linux


g++     -o dist/Debug/GNU-Linux/soff_test build/Debug/GNU-Linux/newmain.o -L../../projects/xerces-c-3.2.2/src/ -L../../projects/xerces-c-3.2.2/src/xercesc/ -L../../projects/xerces-c-3.2.2/src/.libs -Wl,-rpath,'../../projects/xerces-c-3.2.2/src' -Wl,-rpath,'../../projects/xerces-c-3.2.2/src/xercesc' -Wl,-rpath,'../../projects/xerces-c-3.2.2/src/.libs' -lxerces-c -lcurl -lpthread

新错误:

再次提到“未定义的引用”:

../../projects/xerces-c-3.2.2/src/.libs/libxerces-c.a(ICUTransService.o):在函数xercesc_3_2::ICUTransService::upperCase(unsigned short*)': /home/anaim/projects/xerces-c- 3.2.2/src/xercesc/util/Transcoders/ICU/ICUTransService.cpp:358: undefined reference tou_toupper_50'

等等……

1) 那么我是否必须重复相同的步骤并将标头添加到路径中,直到解决这些问题?

这似乎是 NetBeans 问题?

如果开发人员提供了库的写入路径(在本例中为 xerces)并且 NetBeans 能够看到库(它确实如此),为什么 NetBeans 不能生成正确的编译器/链接器命令,这不就是一个重点吗? C/C++ IDE?

我最近的尝试:

我已经开始使用不依赖于 NetBeans 的自定义 Makefile。

这是 Makefile:

   # vars c++
CXX := g++
CXXFLAGS := -std=c++11 -Wall -g 

#collect  all c++ files $(wildcard *.cpp)
SOURCES_CC = newmain.cpp 

#vars c
CC := gcc
CFLAGS := -std=c99 -Wall -g

#collect all c files
SOURCES_C := $(wildcard *.c) 

#objects 
OBJECTS_DIR := build

#construct objects from .c and .cpp to .o
OBJECTS := $(SOURCES_C:%.c=%.o) $(SOURCES_CC:%.cpp=%.o)

#final executable in dist 
DIST_DIR := dist
PROGRAM  := $(DIST_DIR)/main

#required libraries 
LDFLAGS = -L../../projects/xerces-c-3.2.2/src/xercesc/ -lxerces-c

debug := CFLAGS

.PHONY: all
all debug: $(PROGRAM)

$(PROGRAM): $(OBJECTS)
    $(CXX) -o $@ $(OBJECTS) $(LDFLAGS)

.PHONY: clean
    clean:
    rm -f $(PROGRAM) $(OBJECTS) 

这是最新的错误:

cd '/home/myuser/NetBeansProjects/SOFF_test'
/usr/bin/gmake -f Makefile CONF=Debug
gmake: *** No rule to make target `-I../../projects/xerces-c-3.2.2/src/xercesc', needed by `dist/main'.  Stop.

我能够使用此命令行构建 xerces:

g++ -std=c++11 -Wall -g -L../../projects/xerces-c-3.2.2/src/xercesc/ -o main newmain.cpp -lxerces-c

**这是我唯一的问题!如何更改此自定义 Makefile 以使用我自己的源文件(.c 和 .cpp)构建示例 xerces 示例

谢谢一百万!

【问题讨论】:

如果您没有在系统目录中执行sudo make install,则包含#include &lt;xercesc/util/PlatformUtils.hpp&gt; 可能不正确。使用双引号,而不是 lt 和 gt 括号。我认为有一个编译器选项告诉编译器将非系统目录视为系统目录,但我不记得它是什么。 换句话说,使用-I $HOME/projects/xerces-c-3.2.2/src/编译器选项,使用#include "xercesc/util/PlatformUtils.hpp" 对于链接器问题,您永远不会使用 -l(小写 elle)指定库。您只需使用-L 指定库的路径。您需要使用-lxerces-l:libxerces-c.a 或类似名称将实际库添加到LDFLAGS @jww,首先非常感谢你。我更新到#include "xercesc/util/PlatformUtils.hpp" & 也通过属性,链接器菜单指向 libxerces-c.a & 它被识别。我已经解决了这些原始错误,但是我有新的错误,这些错误再次是未定义的引用,但不在示例代码中,它们源自 xerecs 库的深处。我会用详细信息更新我的帖子。 在您最初的配置调用中,您同时使用“禁用共享库”和“禁用静态库”,但稍后您想使用静态库。你确定这是正确的选择吗?在我们这样做的同时,我还建议您切换到使用 CMake 进行构建,对于您正在尝试的子树静态构建,这会使事情变得更容易。 【参考方案1】:

根据您的 cmets,这是一个简单的 makefile .. 希望这会有所帮助:)

CC = gcc
CXX = g++
CFLAGS = -std=c99 -Wall
CXXFLAGS = -std=c++11 -Wall

PROGRAM  = dist/main

SOURCES_C = $(wildcard *.c) 
SOURCES_CC = newmain.cpp 

OBJS = $(SOURCES_C:%.c=%.o) $(SOURCES_CC:%.cpp=%.o)

LIBS = -L../../projects/xerces-c-3.2.2/src/xercesc/ -lxerces-c

all: $(PROGRAM)

clean:
    rm -f $(PROGRAM) $(OBJS) 

%.o : %.c
    $(CC) -c $(CFLAGS) $<

%.o : %.cpp
    $(CXX) -c $(CXXFLAGS) $<

$(PROGRAM): $(OBJS)
    $(CXX) -o $@ $(OBJS) $(LIBS)

.PHONY: all clean

【讨论】:

【参考方案2】:

在您的自定义 makefile 中,这一行

$(PROGRAM): $(INCLUDES) $(OBJECTS)

不正确。你告诉 make 你的程序依赖于目标文件和告诉编译器包含文件所在位置的预处理器选项-I../../projects/xerces-c-3.2.2/src/xercesc 不是可执行文件所依赖的文件。

从该行中删除 $(INCLUDES) 并将其用作预处理器选项:

CPPFLAGS := $(INCLUDES)

$(PROGRAM): $(OBJECTS)
    $(CXX) -o $@ $(OBJECTS) $(LDFLAGS)

您的LDFLAGS 中可能需要-L../../projects/xerces-c-3.2.2/src/xercesc/

注意:您正在使用 SOURCES_CC 变量,但没有在任何地方定义它。

【讨论】:

我能够使用命令行 g++ -std=c++11 -Wall -g -L../../projects/xerces-c-3.2.2/src/xercesc/ -o main newmain.cpp -lxerces-c 构建项目我如何更改我的 Makefile 来做到这一点。【参考方案3】:

善意的版主“Cody”删除了这个(下面的)答案,没有解释,尽管它是正确答案的一部分。简而言之,老兄是在询问他/她的自定义 makefile,而不是 Netbeans 生成的东西。

我还注意到一个人关于从对象的构建依赖项中删除“.d”文件的回复.. 通常(但不总是)这些是在编译后更新的,但它们也需要构建在初始编译发生之前。简单地将它们从对象依赖项中删除可能意味着如果标头中有任何更改,受影响的对象可能不会被重建,即使它们依赖于这些标头。这有点像鸡蛋与蛋的悖论,解决它的方法是建立一个特殊的目标,比如“依赖”......那就是“让依赖”。我在 Makefile sn-p 中没有看到这个目标,但也许我错过了它?另一种不太常见的方法是制作像“NODEPS”这样的宏,在makefile中添加一些条件以避免/跳过将“.d”文件添加为依赖项。因此,您将在初始构建时执行“make NODEPS=1”,然后在随后的“make”构建中出现“鸡”。

这是他/她的最后一个问题:这是我唯一的问题!如何更改此自定义 Makefile 以构建示例:xerces 示例以及我自己的源文件(.c 和 .cpp)?

如果您从 /home/myuser/NetBeansProjects/SOFF_test 目录中执行 'ls ../../projects/xerces-c-3.2.2/src/xercesc' .. 它会在其他目录中找到该目录吗?换句话说,从您运行编译器的位置开始,该相对路径是否有效?如果没有,那么您需要更改它 - 它可能就像在其中添加额外的 ../ 一样简单,例如 -

包括:= -I../../../projects/xerces-c-3.2.2/src/xercesc -I../../../projects/xerces-c-3.2.2 /src -include ../../../projects/xerces-c-3.2.2/src/xercesc/util/PlatformUtils.hpp -include ../../../projects/xerces-c-3.2 .2/src/xercesc/util/XMLUni.hpp -include ../../../projects/xerces-c-3.2.2/src/xercesc/util/XMLException.hpp -MMD -MP -MF "构建/Debug/GNU-Linux/newmain.o.d"

【讨论】:

@Adrew Atrens,是的 ls ../../projects/xerces-c-3.2.2/src/xercesc 命令从 /home/myuser/NetBeansProjects/SOFF_test 正确执行。 很好奇 'dist/main' 的关系.. 可以重新运行 make as 'make -w' 以查看遇到此错误时您真正所在的目录? 当我运行“make -w”时,我得到了serverxyzmyuser% make -w make: Entering directory /home/myuser/NetBeansProjects/SOFF_test make: Nothing to be done for all'. make: Leaving directory /home/myuser/NetBeansProjects/SOFF_test`跨度> @Adrew Atrens,我已经上传了一个新的简化 Makefile,我想在命令行 g++ -std=c++11 -Wall -g -L../../projects/xerces-c-3.2.2/src/xercesc/ -o main newmain.cpp -lxerces-c 上使用它来代替这个命令,你的想法是什么。我能够让 xerces 编译和运行 g++ 编译器命令,但是我想使用正确的 Makefile。

以上是关于正在尝试构建 xerces c++ 解析器。 Netbeans 和命令行构建错误未定义对“xercesc_3_2 ...”的引用的主要内容,如果未能解决你的问题,请参考以下文章

Xerces2 XML 解析器和 Xalan XSLT 处理器——状态和替换?

使用 Xerces 将 DOM 序列化为 FileOutputStream

在 Windows 上构建 C++ 项目时,Tensorflow 2.3 无法解析机器生成的文件中的外部符号

对大文件有效的轻量级 XML 解析器?

C++使用TinyXml(开源库)读取*.XMl文件

不能在 Xerces 或 Neko 的节点上调用 getElementsByTagName?