Why am I getting an "undefined reference" error using gcc?
为什么我使用gcc会得到一个“未定义引用”错误?
I am trying to create a shared object (.so) that exports one function, "external()". I then try to link against the .so but get "undefined reference 'external'". What am I doing wrong here?
我正在尝试创建一个共享对象(.so),它导出一个函数“external()”。然后我尝试链接到。so,但是得到“未定义的引用‘外部’”。我在这里做错了什么?
File: external.c
文件:external.c
int external() {
return 5;
}
File: program.c
文件:program.c
int external();
int main(char** argv, int* argc) {
return external();
}
Commands:
命令:
$ gcc -fPIC -c external.c
$ gcc -shared -o libexternal.so external.o
$ gcc -L. -lexternal -o program program.c
/tmp/cc3MmhAE.o: In function `main':
program.c:(.text+0x7): undefined reference to `external'
collect2: ld returned 1 exit status
I can even run nm and see that the .so is defining 'external':
我甚至可以运行nm,然后看到,定义'外部'
Command:
命令:
$ nm libexternal.so | grep external
0000040c T external
What am I missing here?
我错过了什么?
1 个解决方案
#1
34
Recent versions of gcc/ld default to linking with --as-needed
.
gcc/ld的最新版本默认为按需链接。
This means if you write -lexternal
before the C file the library will automatically get excluded (the order matters when testing if things are "needed" like this)
这意味着,如果在C文件之前编写-lexternal,库将自动被排除(如果测试的东西是“需要的”,那么顺序很重要)
You can fix this with either of:
你可以用以下两种方法来解决这个问题:
gcc -L. -o program program.c -lexternal
- gcc - l。- o项目计划。c -lexternal
gcc -L. -Wl,--no-as-needed -lexternal -o program program.c
- gcc - l。-Wl,-不需要-lexternal -o程序
The latter of which passes --no-as-needed
to the linker, which would cause the library to still be linked, even if you didn't call external()
from it.
后者传递给链接器——不需要链接器,这将导致库仍然被链接,即使您没有从它调用external()。
Note: -Wl,--no-as-needed
isn't applied globally to everything that's linked, it's only applied to things that follow it in the command line order. So -lexternal -Wl,--no-as-needed
also wouldn't work. This does mean that you can mix and match behaviours though, for example gcc -L. -Wl,--no-as-needed -lexternal -Wl,--as-needed -o program program.c -lmightneed
would always link against external, but only link against mightneed if one or both of program.c/libexternal.so caused it to be needed.
注意:-Wl,- no-as-need并不是全局应用于所有链接的内容,它只应用于按照命令行顺序跟随它的内容。所以-lexternal -Wl,不需要也不会起作用。这确实意味着您可以混合和匹配行为,例如gcc -L。-Wl -不需要-lexternal -Wl -需要-o程序。c -lmightneed将始终链接到外部,但仅当一个或两个program.c/libexternal时链接到可能需要。所以才需要它。
#1
34
Recent versions of gcc/ld default to linking with --as-needed
.
gcc/ld的最新版本默认为按需链接。
This means if you write -lexternal
before the C file the library will automatically get excluded (the order matters when testing if things are "needed" like this)
这意味着,如果在C文件之前编写-lexternal,库将自动被排除(如果测试的东西是“需要的”,那么顺序很重要)
You can fix this with either of:
你可以用以下两种方法来解决这个问题:
gcc -L. -o program program.c -lexternal
- gcc - l。- o项目计划。c -lexternal
gcc -L. -Wl,--no-as-needed -lexternal -o program program.c
- gcc - l。-Wl,-不需要-lexternal -o程序
The latter of which passes --no-as-needed
to the linker, which would cause the library to still be linked, even if you didn't call external()
from it.
后者传递给链接器——不需要链接器,这将导致库仍然被链接,即使您没有从它调用external()。
Note: -Wl,--no-as-needed
isn't applied globally to everything that's linked, it's only applied to things that follow it in the command line order. So -lexternal -Wl,--no-as-needed
also wouldn't work. This does mean that you can mix and match behaviours though, for example gcc -L. -Wl,--no-as-needed -lexternal -Wl,--as-needed -o program program.c -lmightneed
would always link against external, but only link against mightneed if one or both of program.c/libexternal.so caused it to be needed.
注意:-Wl,- no-as-need并不是全局应用于所有链接的内容,它只应用于按照命令行顺序跟随它的内容。所以-lexternal -Wl,不需要也不会起作用。这确实意味着您可以混合和匹配行为,例如gcc -L。-Wl -不需要-lexternal -Wl -需要-o程序。c -lmightneed将始终链接到外部,但仅当一个或两个program.c/libexternal时链接到可能需要。所以才需要它。