静态链接失败,尽管名称存在

Static linking failed although the name exists

本文关键字:存在 链接 失败 静态      更新时间:2023-10-16

我正在尝试链接到一个静态库libcovis.a。一切看起来都很好,但我仍然有

对"CoViG_PublicDemo::MoInS::reset()"的未定义引用

我检查了该名称是否存在于库中

$nm libcovis.a | grep reset

_ZN16CoViG_PublicDemo5MoInS5resetEv

我正在使用链接参数 -L/path/to/libcovis.a -lcovis

我做错了什么?

编辑:错误可能是其他原因,如果这样做

gcc main.cpp -I/usr/include/opencv -I/usr/include/cairo -I../../source -o slam -rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lglut -lXi -lxml2 -lboost_filesystem-mt -llapack -lblas -lcv -lcxcore -lcvaux -lhighgui -lcairo ../../来源/libcovis.a ../../Source/contrib/gnuplot_i/libcovis_contrib_gnuplot_i.a -lgl2ps

它有效!

但是当我在KDevelop中使用cmake时,我不再工作了。我使用

CMAKE_EXE_LINKER_FLAGS:STRING=-rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lglut -lXi -lxml2 -lboost_filesystem-mt -llapack -lblas -lcv -lcxcore -lcvaux -lhighgui -lcairo/usr/local/src/CoViS-0.0.0-1/Source/libcovis.a/usr/local/src/CoViS-0.0.0-1/Source/contrib/gnuplot_i/libcovis_contrib_gnuplot_i.a -lgl2ps

CMAKE_CXX_FLAGS:STRING=-I/usr/

local/src/CoViS-0.0.0-1/Source -I/usr/include/opencv -I/usr/include/cairo

我能看到的唯一区别是路径是绝对的,而不是相对的,但如果他找不到库,他会说......

这里有两个不同的问题,第一个是最简单的,你使用了错误的编译器选项。-L 选项告诉链接器在查找库时也查找目录。-l 告诉它链接特定的库。要链接,您将使用:

g++ -o test

test.o -L/path/to -lcovis

g++ -o test

test.o -l/path/to/libcovis.a

如果同一库中的动态库作为动态库存在于同一目录中,则强制静态链接。

第二个潜在问题是链接器命令行中静态库的顺序确实很重要,因此如果依赖于不同的静态库,这也可能是个问题。

g++ -o test tests.o -ldependent -lprovider

链接器将按照命令行中的顺序处理库,并且从每个静态库中,它将仅提取所需的符号(具有与链接器当时具有的一样多的信息)。在上面的命令行中,链接器将从dependent中提取test.o所需的符号,这反过来可能会向程序添加新的未定义符号(dependent的依赖项)。当它处理provider时,它将填写这些符号。如果在命令行中颠倒顺序,则dependent需要但test.o不需要的符号将不会添加到可执行文件中,因为链接器不知道在处理provider时将需要这些符号。

参数应该像-L/path/to/ -lcovis吗?

此外,例如,目标文件应放在库之前

g++ obj1.o obj2.o -L/path/to/ -lcovis .

如果您看到链接在一个上下文中成功,但在另一个上下文中没有成功,我怀疑问题可能是由链接操作的执行顺序引起的,因为链接器将丢弃库中的符号,如果在引用库时不需要它们。

这是一个解释的链接:http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html

我过去遇到过类似的情况,发现链接顺序是问题的原因。