虽然给出了'-lrt',但是没有定义对'clock_gettime'的引用

我已经将-lrt作为编译器的最后一个链接器标志。 但仍然得到这个错误。

 arif@khost:~/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符号没有运气:

 arif@khost:~/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 

更新1我无法从librt.so读取符号的librt.so是它们被“剥离”。 我在哪里可以得到符号名称?

 arif@khost:~/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 

更新2

那么事情变得非常混乱,因为下面的testing代码编译和运行得很好:

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

内置

 arif@khost:~/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; } 

那么问题就解决了如果我通过这个链接器标志

 -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在图书馆之前提供时, --as-needed只与在图书馆的NEEDED部分给出的图书馆联系。

例如,

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

这里 – 需要在libA之前libA 。 所以在链接期间,链接器将检查libANEEDED部分。 如果在NEEDED部分libA只列出libC ,那么libB将不被链接。

发生这个具体问题是因为

 arif@khost:~/sak/sak.exosip$ objdump -p /opt/osip2/lib/libosip2.so.10 | grep NEEDED NEEDED libosipparser2.so.10 NEEDED libc.so.6 

librt不会将librt列为NEEDED

如果我传递--no-as-needed ,那么无论ELF的NEEDED部分给出了什么,所有的库都将被链接。

虽然这不应该是这样的,

 arif@khost:~/sak/sak.exosip$ nm --demangle /opt/osip2/lib/libosip2.so.10 | grep clock_gettime U clock_gettime 

它有librt.so提供的未定义符号clock_gettime

那么它实际上是一个--as-needed开发人员的错误,他们的autotools不能使用--as-needed

osip使用的链接命令:

 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中:

 arif@khost:~/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

更新:

osip开发者回复了我的邮件。 他修复了一个不同的补丁(更一般的解决方案,然后我的) http://git.savannah.gnu.org/cgit/osip.git/commit/?id=bd5b1ad58381e4bfce08bad9b66ad00cd28f9b65