Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the library linker flag sometimes have to go at the end using GCC?

Tags:

I'm writing a small C program that uses librt. I'm quite surprised that the program won't compile if I place the link flag at the start instead of at the end:

At the moment, to compile the program I do:

gcc -o prog prog.c -lrt -std=gnu99

If I were to do the following, it will fail to find the functions in librt:

gcc -std=gnu99 -lrt -o prog prog.c

Yet, this works with other libraries. I found the issue when attempting to use a simple Makefile. make actually compiled prog.c without liking first (using -c flag) and then did the linking.

This is the Makefile:

CC = gcc  CFLAGS = -std=gnu99  LIBS= -lrt  LDFLAGS := -lrt   prog: prog.o          $(CC) -o prog prog.c -lrt -std=gnu99 

The output I would get when typing make would be:

gcc -std=gnu99   -c -o prog.o prog.c gcc -lrt  prog.o   -o prog prog.o: In function `main': prog.c:(.text+0xe6): undefined reference to `clock_gettime' prog.c:(.text+0x2fc): undefined reference to `clock_gettime' collect2: ld returned 1 exit status make: *** [buff] Error 1 

I have now crafted a Makefile that puts the linking at the end of the gcc line, however I'm puzzled why it doesn't work if the linking flag is at the start.

I would appreciate if anybody can explain this to me. Thanks.

like image 719
theprole Avatar asked Feb 23 '12 16:02

theprole


People also ask

What is the purpose of flag in gcc command?

This flag helps us to specify the name of the final executable produced by GCC. It places the output of the final executable in a file “file” as specified along with the flag.

What does the linker flag do?

The -ObjC Linker Flag Passing the -ObjC option to the linker causes it to load all members of static libraries that implement any Objective-C class or category. This will pickup any category method implementations. But it can make the resulting executable larger, and may pickup unnecessary objects.

Which linker does gcc use?

GCC uses a separate linker program (called ld.exe ) to perform the linking.

Does the order of compiler flags matter?

For the most part, the order you use doesn't matter. Order does matter when you use several options of the same kind; for example, if you specify -L more than once, the directories are searched in the order specified.


2 Answers

As the linker processes each module (be it a library or a object file), it attempts to resolve each undefined symbol while potentially adding to its list of undefined symbols. When it gets to the end of the list of modules, it either has resolved all undefined symbols and is successful or it reports undefined symbols.

In your case, when it processed librt, it had no undefined symbols. Processing proc resulted in clock_gettime being an undefined symbol. gcc will not go back and look in librt for the undefined symbols.

For that reason, you should always have your code first, followed by your libraries, followed by platform provided libraries.

Hope this helps.

like image 53
Lou Avatar answered Oct 01 '22 17:10

Lou


From the ld (the GNU linker) documentation (http://sourceware.org/binutils/docs/ld/Options.html#Options):

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.

So if you specify the library too early, the linker will scan it, but not find anything of interest. Then the linker moves on to the object file produced by the compiler and finds references that need to be resolved, but it has already scanned the library and won't bother looking there again.

like image 34
Michael Burr Avatar answered Oct 01 '22 19:10

Michael Burr