“undefined reference to symbol” error when using `ld` to link

烈酒焚心 提交于 2021-02-04 18:48:49

问题


I am new to writing programs on Linux. I have a single module program that uses shm_open, ftruncate, mmap, fork, and wait. I compiled this program with gcc -c and then linked it with ld -lrt (librt is needed for shm_open) and I got a strange linker error:

undefined reference to symbol 'waitpid@@GLIBC_2.2.5'

The manpage for wait says

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
   waitid():
       Since glibc 2.26: _XOPEN_SOURCE >= 500 ||
           _POSIX_C_SOURCE >= 200809L
       Glibc 2.25 and earlier:
           _XOPEN_SOURCE

but putting #define _XOPEN_SOURCE in the code doesn't help, and if I do

gcc -c -D _XOPEN_SOURCE 

the compiler says an implicit declaration of ftruncate.

I am running Ubuntu under VMWare. GCC is version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609.

What could be wrong?


回答1:


I compiled this program with gcc -c and then linked it with ld -lrt

Until you are much more experienced, you should not attempt to invoke ld directly. Instead, link your programs, as well as compiling them, using the gcc (or cc) command. For your use case, a command line like this:

gcc -o myprogram myprogram.o -lrt

should work. (Note the placement of the -lrt; in most cases, -l options need to go after object files on the command line, for tedious historical reasons.)

Under the hood, when you link a program using the gcc command, it runs ld for you, but it includes a whole bunch of additional arguments. These are all needed to construct normal programs, and they're complicated enough that normal programmers shouldn't have to worry about them. One of the extra arguments is -lc, telling ld to include the core of the C runtime library, which provides the definition of waitpid@@GLIBC_2.2.5 that was missing from your link. (Don't just try sticking -lc on the ld command line yourself. Actually, do try it. You'll discover that you only get an even more mysterious error message, probably something like warning: cannot find entry symbol _start or undefined reference to __bswapsi2 or who even knows.)

You can see what all those extra arguments are, if you're curious, by adding a -v to the above gcc invocation, but it's a big mess and only compiler developers need to worry about most of it.

Why is it the gcc command and not the ld command that knows all these extra arguments you need to link a normal program correctly? It's mostly historical, but the idea is that ld is minimal, so if you're doing something unusual (e.g. linking an operating system kernel) you don't need to turn anything normal off, you just need to start from zero and build up. But, for normal programs, people can use (g)cc and not have to worry about the extra arguments.

Incidentally, the stuff you found in the manual about _XOPEN_SOURCE is not about how to make wait available at link time; it's about how to make the declaration of wait available at compile time. Also, the value you define _XOPEN_SOURCE to matters. Defining it as -D_XOPEN_SOURCE rather than -D_XOPEN_SOURCE=500 is why you got a complaint about an implicit declaration of ftruncate.



来源:https://stackoverflow.com/questions/54611358/undefined-reference-to-symbol-error-when-using-ld-to-link

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!