2013-06-17 3 views
7

Ich habe -lrt als das letzte Linker-Flag für den Compiler angegeben. Aber immer noch diesen Fehler zu bekommen.Undefinierter Verweis auf `clock_gettime`, obwohl` -lrt` angegeben ist

[email protected]:~/sak/sak.exosip$ gcc eXo_init.c -I/opt/osip2/include -I/opt/exosip/include -L/opt/osip2/lib -L/opt/exosip/lib -leXosip2 -losipparser2 -losip2 -lrt 
/opt/osip2/lib/libosip2.so: undefined reference to `clock_gettime' 
collect2: ld returned 1 exit status 

Der Mann Seite sagt:

NAME 
     clock_getres, clock_gettime, clock_settime - clock and time functions 

SYNOPSIS 
     #include <time.h> 

     int clock_getres(clockid_t clk_id, struct timespec *res); 

     int clock_gettime(clockid_t clk_id, struct timespec *tp); 

     int clock_settime(clockid_t clk_id, const struct timespec *tp); 

     Link with -lrt. 

So bin ich irgendwie verwirrt, wo ich es falsch mache.

Ich habe versucht, Symbole in librt.so ohne Glück zu lesen:

[email protected]:~/sak/ortp/src/tests$ nm /lib/x86_64-linux-gnu/librt-2.15.so 
nm: /lib/x86_64-linux-gnu/librt-2.15.so: no symbols 

UPDATE 1 Der Grund, warum ich nicht Symbole aus librt.so lesen kann, ist, dass sie „gestrippt“ werden. Wo kann ich die Symbolnamen bekommen?

[email protected]:~/sak/ortp/src/tests$ file /lib/x86_64-linux-gnu/librt-2.15.so 
/lib/x86_64-linux-gnu/librt-2.15.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), BuildID[sha1]=0x375b2c35c4e6503a5d1a88ab6f76f5b6e0ee81df, for GNU/Linux 2.6.24, stripped 

UPDATE 2

Nun Dinge werden sehr verwirrend, da der folgende Test-Code kompiliert und läuft ganz gut:

#include <time.h> 
#include <unistd.h> 
#include <stdio.h> 

int main(int argc, char **argv, char **arge) { 
    struct timespec tps, tpe; 
    if ((clock_gettime(CLOCK_REALTIME, &tps) != 0) 
     || (clock_gettime(CLOCK_REALTIME, &tpe) != 0)) { 
     perror("clock_gettime"); 
     return -1; 
    } 
    printf("%lu s, %lu ns\n", tpe.tv_sec-tps.tv_sec,tpe.tv_nsec-tps.tv_nsec); 
    return 0; 
} 

Errichtet mit

[email protected]:~/sak/sak.exosip$ gcc what.c -lrt 

UPDATE3 Der Code Ich versuche kompilieren:

#include <eXosip2/eXosip.h> 
#include <netinet/in.h> 
#include <unistd.h> 

int ex_init(int port) 
{ 
    struct eXosip_t *eXcontext; 
    int i; 
    TRACE_INITIALIZE(6, stdout); 
    i = eXosip_init(eXcontext); 
    if (i != 0) 
     return -1; 

    i = eXosip_listen_addr(eXcontext, IPPROTO_UDP, NULL, port, AF_INET, 0); 
    if (i != 0) { 
     eXosip_quit(eXcontext); 
     fprintf (stderr, "could not initialize transport layer\n"); 
     return -1; 
    } 

    return 1; 
} 

int main(int argc, char **argv) { 
    if(ex_init(1000)) 
     printf("success \n"); 
    return 0; 
} 
+0

Könnten Sie uns den ursprünglichen fehlerhaften Code geben? Danke – Mathuin

+0

Ich muss nicht viel mit gcc cmd Zeilen arbeiten, aber würde es helfen, den Verweis auf '-lrt' näher an den Anfang der cmd Zeile zu verschieben? Viel Glück. – shellter

+0

@ MatthR3D gegeben, wie Sie gefragt haben. Wie Sie sehen können, ist es ein sehr trivialer Code. – Aftnix

Antwort

16

Nun das Problem gelöst ist, wenn ich diesen Linker-Flag in der Befehlszeile

-Wl,--no-as-needed 

Vor der Bibliotheksliste übergeben.

Warum das funktioniert, weil Linker in meiner Plattform immer mit -Wl,--as-needed übergeben wird.

Von ld Handbuch:

--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 satisfies an undefined 
      symbol reference from a regular object file or, if the library is 
      not found in the DT_NEEDED lists of other libraries linked up to 
      that point, an undefined symbol reference from another dynamic 
      library. --no-as-needed restores the default behaviour. 

Also, wenn --as-needed vor einer Bibliothek gegeben ist, liker verbindet nur mit den Bibliotheken, die in NEEDED Sektion der Bibliothek gegeben sind.

Zum Beispiel

-Wl,--as-needed -llibA -llibB -llibC 

Hier --as benötigte vor libA gegeben. So wird Linker während des Linkens den Abschnitt NEEDED von libA untersuchen. Wenn in NEEDED Abschnitt libA Listen nur libC, dann die libB wird nicht verknüpft werden.

Dieses spezifische Problem trat auf, weil

[email protected]:~/sak/sak.exosip$ objdump -p /opt/osip2/lib/libosip2.so.10 | grep NEEDED 
    NEEDED    libosipparser2.so.10 
    NEEDED    libc.so.6 

libosip2 keine Listen librt als NEEDED tut.

Wenn ich --no-as-needed übergebe, werden alle Bibliotheken verknüpft, unabhängig davon, was in ELF NEEDED Abschnitt angegeben ist.

Obwohl dies sollte nicht der Fall sein, weil,

[email protected]:~/sak/sak.exosip$ nm --demangle /opt/osip2/lib/libosip2.so.10 | grep clock_gettime 
       U clock_gettime 

Es undefined hat Symbol clock_gettime, die von librt.so vorgesehen ist.

Nun ist es tatsächlich ein Fehler der libosip2 Entwickler, dass ihre autotools nicht mit --as-needed arbeitet.

Der Befehl Link von osip verwendet:

libtool: link: gcc -shared -fPIC -DPIC .libs/ict_fsm.o .libs/ist_fsm.o .libs/nict_fsm.o .libs/nist_fsm.o .libs/ict.o .libs/ist.o .libs/nict.o .libs/nist.o .libs/fsm_misc.o .libs/osip.o .libs/osip_transaction.o .libs/osip_event.o .libs/port_fifo.o .libs/osip_dialog.o .libs/osip_time.o .libs/port_sema.o .libs/port_thread.o .libs/port_condv.o -Wl,-rpath -Wl,/home/arif/sak/osip/src/osipparser2/.libs -Wl,-rpath -Wl,/opt/osip2-test/lib -lnsl ../osipparser2/.libs/libosipparser2.so -Wl,-soname -Wl,libosip2.so.10 -o .libs/libosip2.so.10.0.0 

seine Verknüpfung also nicht mit librt und das ist, warum es nicht librt in seiner NEEDED Liste

Auflistung Wenn mit konfiguriert:

LDFLAGS="${LDFLAGS} -lrt" ./configure --prefix=/opt/osip2-test/ 

Dann wird der Verbindungsbefehl:

libtool: link: gcc -shared -fPIC -DPIC .libs/ict_fsm.o .libs/ist_fsm.o .libs/nict_fsm.o .libs/nist_fsm.o .libs/ict.o .libs/ist.o .libs/nict.o .libs/nist.o .libs/fsm_misc.o .libs/osip.o .libs/osip_transaction.o .libs/osip_event.o .libs/port_fifo.o .libs/osip_dialog.o .libs/osip_time.o .libs/port_sema.o .libs/port_thread.o .libs/port_condv.o -Wl,-rpath -Wl,/home/arif/sak/osip/src/osipparser2/.libs -Wl,-rpath -Wl,/opt/osip2-test/lib -lnsl ../osipparser2/.libs/libosipparser2.so -lrt -Wl,-soname -Wl,libosip2.so.10 -o .libs/libosip2.so.10.0.0 

So seine Verknüpfung mit librt. Es ist auch in seiner ELF wider:

[email protected]:~/sak/osip/src/osip2/.libs$ objdump -p libosip2.so.10 | grep NEEDED 
    NEEDED    libosipparser2.so.10 
    NEEDED    librt.so.1 
    NEEDED    libc.so.6 

Dieser Patch behebt dieses:

diff --git a/src/osip2/Makefile.am b/src/osip2/Makefile.am 
index bb0d8f3..b72c22a 100644 
--- a/src/osip2/Makefile.am 
+++ b/src/osip2/Makefile.am 
@@ -14,7 +14,7 @@ libosip2_la_SOURCES+=port_sema.c port_thread.c port_condv.c 
endif 

libosip2_la_LDFLAGS = -version-info $(LIBOSIP_SO_VERSION) \ 
- $(FSM_LIB) $(EXTRA_LIB) ../osipparser2/libosipparser2.la -no-undefined 
+ $(FSM_LIB) $(EXTRA_LIB) ../osipparser2/libosipparser2.la -no-undefined -lrt 


INCLUDES = -I$(top_srcdir)/includ 

Relevante direkten Download zur Diskussion: https://groups.google.com/forum/#!topic/comp.unix.programmer/VKbARy6W4AY

UPDATE:

osip Entwickler auf meine Mail geantwortet. Er reparierte es mit einem anderen Patch (Allgemeinere Lösung als meins) http://git.savannah.gnu.org/cgit/osip.git/commit/?id=bd5b1ad58381e4bfce08bad9b66ad00cd28f9b65

Verwandte Themen