问题
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 withld -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