Linux 尽管给出了 `-lrt`,但未定义对 `clock_gettime` 的引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17150075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:14:33  来源:igfitidea点击:

Undefined reference to `clock_gettime` although `-lrt` is given

linuxlinkerlibc

提问by Aftnix

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

我已将-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

The man page says :

手册页说:

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.

所以我有点困惑我在哪里做错了。

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

我试图在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

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

更新 1我无法读取符号的原因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

UPDATE 2

更新 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;
}

Built with

内置

arif@khost:~/sak/sak.exosip$ gcc what.c -lrt

UPDATE3The code i'm trying compile :

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

采纳答案by Aftnix

Well the problem is solved If i pass this linker flag

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

-Wl,--no-as-needed

Before the library list in command line.

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

Why this works because in my platform, linker is always passed with -Wl,--as-needed.

为什么这有效,因为在我的平台中,链接器总是通过-Wl,--as-needed.

From ldmanual :

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.

So when --as-neededis given before a library , liker only links with the libraries which are given in NEEDEDsection of the library.

因此,当--as-needed在 library 之前给出时,liker 仅与图书馆部分中给出NEEDED的图书馆链接。

For example,

例如,

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

Here --as-needed is given before libA. So during linking, linker will examine the NEEDEDsection of libA. If in NEEDEDsection of libAlists only libC, then the libBwill not be linked.

这里 --as-needed 之前给出libA。所以在连接时,连接器将检查NEEDED的部分libA。如果仅在列表的NEEDED部分中,则不会链接。libAlibClibB

This specific problem occurred because

出现此特定问题是因为

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

libosip2does not lists librtas NEEDED.

libosip2librt列为NEEDED

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

如果我通过--no-as-needed,那么无论 ELFNEEDED部分中给出了什么,所有库都将被链接。

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

It has undefined symbol clock_gettimewhich is provided by librt.so.

它有未定义的符号clock_gettime,由librt.so.

Well its actually a fault of the libosip2devs that their autotoolsis not working with --as-needed.

那么它实际上是一个错误libosip2的开发者,他们autotools不与工作--as-needed

The link command used by osip:

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

So its not linking with librtand thats why its not listing librtin its NEEDEDlist

所以它没有链接,librt这就是为什么它没有列librt在它的NEEDED列表中

If configured with :

如果配置为:

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

Then the link command becomes :

然后链接命令变为:

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

所以它与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

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

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

相关usenet讨论线程:https://groups.google.com/forum/#! topic/comp.unix.programmer/VKbARy6W4AY

UPDATE:

更新:

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

osip 开发人员回复了我的邮件。他用不同的补丁修复了它(比我的更通用的解决方案) http://git.savannah.gnu.org/cgit/osip.git/commit/?id=bd5b1ad58381e4bfce08bad9b66ad00cd28f9b65