试图包含一个库,但不断获得'未定义的'消息引用

KU1*_*KU1 59 ubuntu compiler-errors build linker-errors static-libraries

我正在尝试使用libtommath库.我在Ubuntu linux上使用NetBeans IDE作为我的项目.我已经下载并构建了库,我已经完成了'make install'以将生成的.a文件放入/ usr/lib /并将.h文件放入/ usr/include

它似乎是正确地找到文件(因为我不再得到这些错误,我在安装到/ usr目录之前做了这些错误).

但是,当我创建一个简单的main来调用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
Run Code Online (Sandbox Code Playgroud)

因此,看起来链接器无法在库中找到该函数,但它就在那里,所以我只是不知道是什么原因造成的.

如果我直接输入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
Run Code Online (Sandbox Code Playgroud)

我对这些东西非常生疏,所以我不确定我在这里使用正确的命令,在-L示例中是否找到了库?如果找不到图书馆,我怎么去找图书馆呢?它在/ usr/lib中,我用当前目录中的.a文件尝试过它,等等.我需要设置一个环境变量吗?如果是这样,怎么样等等

我尝试了一个完全不同的库(GMP)并且有完全相同的问题.这必须是某种Ubuntu环境问题?任何人都知道如何解决这个问题?

小智 138

这里的技巧是将库放在您正在编译的模块之后.问题是参考的事情.链接器按顺序解析引用,因此当库在编译模块之前,链接器会混淆并且不认为库中的任何函数是必需的.通过将库放在模块之后,链接器将解析模块中库的引用.

  • +1哦,谢谢!我知道链接解析顺序很有道理,但提醒这些事实真的很有帮助! (9认同)
  • 2020 年仍然具有现实意义 (7认同)
  • 这对我有用。我非常旧的 makefile 曾经可以工作,但现在看来编译器变得太聪明了:) (3认同)
  • 我不会投票重复另一个问题:http://stackoverflow.com/questions/12748837/c-shared-library-undefined-reference-to-fooclasssayhello 因为该答案添加了一个细节:“GCC 的最新版本需要您将目标文件和库按照它们*相互依赖*的顺序放置”。 (2认同)

小智 41

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

gcc -static -L/usr/lib -I/usr/lib main.c -ltommath
Run Code Online (Sandbox Code Playgroud)

  • +1 用于编写链接“libtommath.a”的正确方法 (2认同)

use*_*227 5

如果.c源文件被转换为.cpp(就像在parsec中一样),则extern需要后跟"C",如

extern "C" void foo();
Run Code Online (Sandbox Code Playgroud)