46

I just have a system crash and reinstall Ubuntu 11.10, and my code produces this strange error.

I wrote a simple code sample to test where the problem is:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>

int main (void) {

    int i;

    i = shm_open ("/tmp/shared", O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);   printf ("shm_open rc = %d\n", i);

    shm_unlink ("/tmp/shared");

    return (0);
}

and the compile command is

gcc -lrt test.c -o test

The error is:

/tmp/ccxVIUiP.o: In function `main':
test.c:(.text+0x21): undefined reference to `shm_open'
test.c:(.text+0x46): undefined reference to `shm_unlink'
collect2: ld returned 1 exit status

I have already added -lrt lib, why does it still not compile?

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
bxshi
  • 2,252
  • 5
  • 31
  • 50

4 Answers4

74

Libraries at the end:

gcc test.c -o test -lrt

From GCC Link Options:

-llibrary
-l library
    Search the library named library when linking. 
    (The second alternative with the library as a separate argument
    is only for POSIX compliance and is not recommended.)

    It makes a difference where in the command you write this option;
    the linker searches and processes libraries and object files in the
    order they are specified.
    Thus, `foo.o -lz bar.o' searches library `z' after file foo.o but
    before bar.o. If bar.o refers to functions in `z', those functions
    may not be loaded.
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • 1
    I guess adding libraries somewhere in the middle also works. Just curious why `gcc` treats the order as so important? – Pavan Manjunath Mar 29 '12 at 10:26
  • 1
    This time I need to add lib at the end of this gcc command, but before I reinstall my linux, I could add lib just after `gcc` and it also could compile. How's that happen? Is there any configure file or variable about that? – bxshi Mar 29 '12 at 10:30
  • 2
    @PavanManjunath: newer GCC versions accept libraries anywhere on the command line and in any order. Older ones require them to be listed last and in dependency order (so anything that requires `librt` comes before it). – Fred Foo Mar 29 '12 at 10:30
  • @PavanManjunath: It has to. Libraries are searched **in order** to resolve undefined symbols. If the order did not matter, there would be no way to control which library got used when the wanted symbol is defined in two or more libraries you'll be searching. – R.. GitHub STOP HELPING ICE Mar 29 '12 at 14:04
  • @R..: my GCC (Debian 4.4.5-8) links the OP's program just fine with the given command line. I'm not sure when this feature was introduced and how exactly it's implemented, but it's given rise to a lot of SO questions before. – Fred Foo Mar 29 '12 at 14:27
  • I don't doubt your report, but I also don't see how library search can work correctly if the order doesn't matter in general. Perhaps they just made some hack so libraries at the beginning get moved to after all source/object files... – R.. GitHub STOP HELPING ICE Mar 29 '12 at 14:45
9

Change the compile line from

gcc -lrt test.c -o test

to

gcc test.c -o test -lrt
codaddict
  • 445,704
  • 82
  • 492
  • 529
  • Does gcc always need to add lib at the end? I did not change my code and Makefile, but before I reinstall my computer, it works just okay. – bxshi Mar 29 '12 at 10:28
4

In Expert C programming Page 108: <Handy Heuristic> Where to Put Library Options:Always put the -l library options at the rightmost end of your compilation command line. But it doesn't tell why, so i guess this is somewhat a rule?:)

Coaku
  • 977
  • 1
  • 9
  • 23
3

For those of you using super-auto-magical CMAKE like me, try to add:

target_link_libraries(your_binary_name PRIVATE librt.so)

to your CMakeLists.txt

Alternatively, replace PRIVATE for PUBLIC as needed..


If you have well established paths to libraries (e.g. all needed libs in /usr/lib), you may be fine with just stating in CMakeLists.txt:

set(CMAKE_CXX_FLAGS "-lrt")

Sold Out
  • 1,321
  • 14
  • 34