尝试包含库,但不断收到“未定义引用”消息

Trying to include a library, but keep getting 'undefined reference to' messages

提问人:KU1 提问时间:10/5/2009 最后编辑:ROMANIA_engineerKU1 更新时间:4/20/2023 访问量:154461

问:

我正在尝试使用 libtommath 库。我在 Ubuntu Linux 上将 NetBeans IDE 用于我的项目。我已经下载并构建了库,我做了一个“make install”,将生成的 .a 文件放入 /usr/lib/ 中,将 .h 文件放入 /usr/include 中

它似乎正在适当地找到文件(因为我不再收到这些错误,我在安装到 /usr 目录之前就这样做了)。

但是,当我创建一个简单的主调用mp_init(在库中)时,当我尝试创建我的项目时,我收到以下错误:

mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/main.o.d
gcc -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.c
mkdir -p dist/Debug/GNU-Linux-x86
gcc -o dist/Debug/GNU-Linux-x86/cproj1 build/Debug/GNU-Linux-x86/main.o
build/Debug/GNU-Linux-x86/main.o: In function 'main':
/home/[[myusername]]/NetBeansProjects/CProj1/main.c:18: undefined reference to `mp_init'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/cproj1] Error 1

因此,链接器似乎无法在库中找到该函数,但它就在那里,所以我不知道是什么原因导致的。

如果我直接键入 gcc 命令并跳过 makefile,我会遇到同样的错误,我还确保静态库也使用 gcc 编译。

编辑添加:

如果我直接进行编译并使用 -l 或 -L 添加库,我会得到这些相同的错误:

$ gcc -l /usr/lib/libtommath.a main.c 
/usr/bin/ld: cannot find -l/usr/lib/libtommath.a
collect2: ld returned 1 exit status

$ gcc -llibtommath.a main.c 
/usr/bin/ld: cannot find -llibtommath.a
collect2: ld returned 1 exit status

$ gcc -Llibtommath.a main.c 
/tmp/ccOxzclw.o: In function `main':
main.c:(.text+0x18): undefined reference to `mp_init'
collect2: ld returned 1 exit status

$ gcc -Llibtommath.a main.c 
/tmp/ccOxzclw.o: In function `main':
main.c:(.text+0x18): undefined reference to `mp_init'
collect2: ld returned 1 exit status

我对这些东西非常生疏,所以我不确定我在这里使用了正确的命令,在 -L 示例中是否找到了库?如果找不到库,我到底如何让它找到库?它在 /usr/lib 中,我已经尝试过使用当前目录中的 .a 文件等。是否有需要设置的环境变量?如果是这样,如何等。

我尝试了一个完全不同的库 (GMP),并遇到了完全相同的问题。这一定是某种Ubuntu环境问题吗?有人知道如何解决这个问题吗?

Ubuntu 构建 编译 static-libraries 链接器错误

评论

0赞 jdhao 7/3/2021
密切相关:stackoverflow.com/a/409470/6064933

答:

205赞 David Wheeler 3/22/2010 #1

这里的诀窍是将库放在您正在编译的模块之后。这个问题是一个参考的东西。链接器按顺序解析引用,因此当库位于正在编译的模块之前时,链接器会感到困惑,并且认为不需要库中的任何函数。通过将库放在模块之后,链接器将解析对模块中库的引用。

评论

15赞 Shalom Craimer 12/20/2011
+1 哦,谢谢!我知道链接解析顺序非常有意义,但提醒这些事实确实很有帮助!
3赞 gak 4/28/2012
这对我有用。我非常旧的 makefile 曾经工作过,但现在编译器似乎变得太聪明了,无法:)
2赞 Victor Sergienko 7/5/2013
我不会投票重复另一个问题:stackoverflow.com/questions/12748837/...因为这个答案增加了一个细节:“最新版本的 GCC reuqire 你按照它们相互依赖的顺序放置目标文件和库”。
1赞 piccy 8/14/2018
我想给你投 1000 次赞 - 我花了几天时间试图让我的项目链接,而你的解决方案就是解决方法!
7赞 GottZ 8/26/2020
2020 年仍然相关
53赞 Amol Dalavi 1/14/2011 #2

是的,需要在源文件/对象文件之后添加库。此命令将解决问题:

gcc -static -L/usr/lib -I/usr/lib main.c -ltommath

评论

4赞 Shalom Craimer 12/20/2011
+1 用于编写正确的链接方式libtommath.a
9赞 user3342227 2/15/2017 #3

如果 .c 源文件是.cpp转换的(如 parsec),则 extern 后面需要跟 “C”,如

extern "C" void foo();
0赞 GVyas 4/20/2023 #4

检查路径中是否缺少 lib