尽管给出了-lrt,但未定义对clock_gettime的引用 [英] Undefined reference to `clock_gettime` although `-lrt` is given

查看:148
本文介绍了尽管给出了-lrt,但未定义对clock_gettime的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我给了-lrt作为编译器的最后一个链接器标志.但是仍然出现此错误.

I've give -lrt as the last linker flag to the compiler. But still getting this error.

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.

所以我对做错地方感到困惑.

So i'm kind of confused where i'm doing it wrong.

我试图在librt.so中读取符号没有运气:

I've tried to read symbols in librt.so with no luck :

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中读取符号的原因是它们被剥离"了.我在哪里可以获得符号名称?

UPDATE 1 The reason i can't read symbols out of librt.so is that they are "stripped". Where can i get the symbol names ?

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

事情变得非常混乱,因为以下测试代码可以编译并正常运行:

Well things become very confusing because the following test code compiles and runs just fine :

#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 我正在尝试编译的代码:

UPDATE3 The code i'm trying compile :

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

推荐答案

如果我通过了此链接器标志,则解决了问题

Well the problem is solved If i pass this linker flag

-Wl,--no-as-needed

在命令行中的库列表之前.

Before the library list in command line.

为什么行之有效,因为在我的平台中,链接器总是与-Wl,--as-needed一起传递.

Why this works because in my platform, linker is always passed with -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部分中给出的库链接.

So when --as-needed is given before a library , liker only links with the libraries which are given in NEEDED section of the library.

例如,

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

在此处-在libA之前提供所需的内容.因此,在链接期间,链接器将检查libANEEDED部分.如果在libANEEDED部分中仅列出libC,则libB将不会链接.

Here --as-needed is given before libA. So during linking, linker will examine the NEEDED section of libA. If in NEEDED section of libA lists only libC, then the libB will not be linked.

发生此特定问题是因为

arif@khost:~/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部分中给出的内容如何,​​所有库都将被链接.

If i pass --no-as-needed, then all the libraries will be linked regardless of what is given in ELF's NEEDED section.

虽然不是这种情况,因为

Although this should not be the case because,

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

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

It has undefined symbol clock_gettime which is provided by librt.so.

这实际上是libosip2开发人员的错误,即他们的autotools无法与--as-needed一起使用.

Well its actually a fault of the libosip2 devs that their autotools is not working with --as-needed.

osip使用的链接命令:

The link command used by 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链接,这就是为什么它没有在NEEDED列表中列出librt的原因

So its not linking with librt and thats why its not listing librt in its NEEDED list

如果配置为:

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

So its linking with librt. Its also reflected in its 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

此修补程序可解决此问题:

This patch fixes this :

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.程序员/VKbARy6W4AY

Relevant usenet discussion thread : https://groups.google.com/forum/#!topic/comp.unix.programmer/VKbARy6W4AY

更新:

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

osip developer responded to my mail. He fixed it with a different patch (More general solution then mine) http://git.savannah.gnu.org/cgit/osip.git/commit/?id=bd5b1ad58381e4bfce08bad9b66ad00cd28f9b65

这篇关于尽管给出了-lrt,但未定义对clock_gettime的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆