When I try to compile that, I receive a particular error. But, it's not possible because I use the right flag. In server.c
there is the library pthread.h
.
So, how can I resolve my linking problem?
I'm using Linux (Ubuntu).
make
gcc -c -Wall -Wunused -ansi -pedantic -ggdb -o Server1.o Server.c
gcc -c -Wall -Wunused -ansi -pedantic -ggdb Util.c
gcc -o Server1.exe -Wall -Wunused -ansi -pedantic -ggdb -lpthread -lm Server1.o Util.o
Server1.o: In function `main':
/home/ruggero/ruggero_fine/Server.c:1002: undefined reference to `pthread_create'
collect2: ld returned 1 exit status
make: *** [Server1.exe] Errore 1
When linking only object files and libraries, list the libraries after the object files:
gcc -o Server1.exe -Wall -Wunused -ansi -pedantic -ggdb Server1.o Util.o -lpthread -lm
When the linking command includes source files, list the source files and object files (if any) before the libaries. The -l
options come at the end of the command line, therefore. Relevant -L
options specifying where a library is found should come before the -l
option specifying the library.
The subsidiary question is:
Why does it work?
When the C compiler invokes the linker, it tells the linker to pull in some system object files with names like crt0.o
, and tells it to look for a symbol main
(or possibly _main()
, depending on local naming conventions). It also supplies the object files and libraries in the order you specified on the command line. When it comes across an object file, the linker notes the definitions it provides, and the unsatisfied references it makes. When it comes across a library, it scans the library to see whether it can satisfy any unsatisfied references. If the library can supply any as yet unsatisfied references, then it includes (the relevant parts of) the library 'in the executable'. For a shared library, the linker ensures that the library will be loaded at runtime. For a static library, the linker includes the object files from the library that satisfy at least one reference, rescanning until there are no further references that can be satisfied. If the library satisfies no references, it is ignored. When the process is complete, if any references are still unsatisfied, you get the error messages.
So, in your scenario, you had -lpthread
before either Server1.o
or Util.o
. Since -lpthread
does not provide a main
function and that was the only relevant unsatisfied symbol, it was ignored. The mathematics library, -lm
may also have been ignored, or it may be an empty stub to keep code devised for other systems where the mathematics library is separate from the main C library. Then the linker read your object files, and found the reference to pthread_create()
. When it scanned the C library -lc
(libc.so
) afterwards, it found symbols to satisfy everything except pthread_create
.
When the libraries are listed after the object files, then the linker knew it needed pthread_create
when it scanned -lpthread
and ensured that the shared library would be loaded at runtime.
ld
and the --as-needed
optionThe discussion above is essentially platform-neutral. If you follow the 'libraries after object files' rule, your linker line has the maximum chance of working correctly on all platforms.
If you are on a system using the GNU binutils
package, and the GNU ld
command in particular, you may find different behaviour.
The manual from Sourceware (which is where you are redirected if you try http://www.gnu.org/software/binutils/manuals) includes the information:
--as-needed
--no-as-needed
This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the--as-needed
option. Normally the linker will add a DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is actually needed or not.--as-needed
causes a DT_NEEDED tag to only be emitted for a library that at that point in the link satisfies a non-weak undefined symbol reference from a regular object file or, if the library is not found in the DT_NEEDED lists of other libraries, a non-weak undefined symbol reference from another dynamic library. Object files or libraries appearing on the command line after the library in question do not affect whether the library is seen as needed. This is similar to the rules for extraction of object files from archives.--no-as-needed
restores the default behaviour.
It appears that different versions of different systems use different values for the as-needed
option. While the --no-as-needed
behaviour is convenient in that it lets you order libraries and object files in more or less any order on your command line, it also means that all the libraries listed on the command line are loaded at run time, even if there are no symbols actually used from the library (thus --no-as-needed
is equivalent to a hypothetical --whether-needed-or-not
flag). Using the --as-needed
option is the classic and portable behaviour.
Rumour has it that some Linux distributions changed the default behaviour on their systems from --no-as-needed
to --as-needed
sometime in the last 5 years or so (the first half of the second decade of the third millennium, for sake of argument). You can find evidence in support of this rumour in a number of questions on SO.
Use -pthread when compiling. Try it and you will solve your problem
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With