2013-06-17 1 views
7

Я дал -lrt как последний флаг компоновщика компилятору. Но все равно получить эту ошибку.Неопределенная ссылка на `clock_gettime` хотя` -lrt` дана

[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 

Страница человек говорит:

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. 

Так я вроде запутался, где я делаю это неправильно.

Я пытался читать символы в librt.so не повезло:

[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 Причина я не могу читать символы из librt.so является то, что они «раздели». Где я могу получить имена символов?

[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

Ну вещи становятся очень запутанным, так как следующий тестовый код компилирует и работает просто отлично:

#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; 
} 

Построенный с

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

Update3 Код я пытаюсь скомпилировать:

#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

Не могли бы вы дать нам оригинальный оскорбительный код? Спасибо – Mathuin

+0

Мне не нужно много работать с gcc cmd-строками, но поможет ли это переместить ссылку на '-lrt' ближе к фронту линии cmd? Удачи. – shellter

+0

@ MatthR3D, как вы просили. Как вы можете видеть, это очень тривиальный код. – Aftnix

ответ

16

Ну проблема решена Если я прохожу этот линкер флаг

-Wl,--no-as-needed 

Перед список библиотек в командной строке.

Почему это работает, потому что в моей платформе линкер всегда передается с -Wl,--as-needed.

Из ld инструкции:

--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. 

Так что, когда --as-needed дается перед библиотекой, Liker связывает только с библиотеками, которые приведены в разделе NEEDED библиотеки.

Например,

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

Здесь --as необходимой дается до libA. Поэтому во время связывания линкер рассмотрит раздел NEEDED от libA. Если в NEEDED раздел libA перечисляет только libC, то libB не будет связан.

Эта специфическая проблема возникла из-за

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

libosip2 не списки librt в NEEDED.

Если я передаю --no-as-needed, то все библиотеки будут связаны независимо от того, что указано в разделе ELF NEEDED.

Несмотря на то, что это не должно быть так, потому что,

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

Это имеет неопределенный символ clock_gettime, который предоставляется librt.so.

Ну, на самом деле это ошибка libosip2, что их autotools не работает с --as-needed.

Команда ссылка используется Осипа:

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 

Таким образом, ее не связывающей с librt и вот почему его не перечисляя librt в NEEDED списке

Если настроен:

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

Затем команда связи становится:

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 

Соответствие действительности: librt. Его также отражено в его ELF:

[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 

Этот патч исправляет это:

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 

Соответствующая Usenet обсуждение темы: https://groups.google.com/forum/#!topic/comp.unix.programmer/VKbARy6W4AY

UPDATE:

разработчик Осип ответил на мою почту. Он установил его другим патчем (более общее решение тогда мое) http://git.savannah.gnu.org/cgit/osip.git/commit/?id=bd5b1ad58381e4bfce08bad9b66ad00cd28f9b65