未定义“clock_gettime”,但给出了“-lrt”。

时间:2022-09-26 20:36:23

I've give -lrt as 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.so with no luck :

我试着在librt上读符号。所以运气不好:

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 1 The reason i can't read symbols out of librt.so is that they are "stripped". Where can i get the symbol names ?

更新1:我不能从librt读取符号的原因。所以他们被“剥夺”了。我在哪里可以得到符号名?

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

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

1 个解决方案

#1


16  

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的方式传递。

From ld manual :

从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-needed is given before a library , liker only links with the libraries which are given in NEEDED section of the library.

因此,当需要的时候,在一个库之前,liker只会链接到库中需要的部分的库。

For example,

例如,

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

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.

这里——需要的是在libA之前。因此在链接过程中,链接器将检查libA的需要部分。如果在libA的需要部分只列出libC,那么libB将不会被链接。

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

libosip2 does not lists librt as NEEDED.

libosip2不会根据需要列出librt。

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

如果我通过了——不需要,那么所有的库都将被链接,而不管ELF需要的部分中给出了什么。

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_gettime which is provided by librt.so.

它有一个未定义的符号clock_gettime,它是由librt提供的。

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

这实际上是libosip2 devs的一个错误,他们的自动工具不需要。

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 librt and thats why its not listing librt in its NEEDED list

因此,它与librt之间没有联系,这就是为什么它不在需要的列表中列出librt。

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的联系。它也反映在它的精灵:

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.程序员/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开发人员回复了我的邮件。他用一个不同的补丁(更通用的解决方案)解决了这个问题。

#1


16  

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的方式传递。

From ld manual :

从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-needed is given before a library , liker only links with the libraries which are given in NEEDED section of the library.

因此,当需要的时候,在一个库之前,liker只会链接到库中需要的部分的库。

For example,

例如,

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

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.

这里——需要的是在libA之前。因此在链接过程中,链接器将检查libA的需要部分。如果在libA的需要部分只列出libC,那么libB将不会被链接。

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

libosip2 does not lists librt as NEEDED.

libosip2不会根据需要列出librt。

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

如果我通过了——不需要,那么所有的库都将被链接,而不管ELF需要的部分中给出了什么。

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_gettime which is provided by librt.so.

它有一个未定义的符号clock_gettime,它是由librt提供的。

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

这实际上是libosip2 devs的一个错误,他们的自动工具不需要。

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 librt and thats why its not listing librt in its NEEDED list

因此,它与librt之间没有联系,这就是为什么它不在需要的列表中列出librt。

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的联系。它也反映在它的精灵:

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.程序员/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开发人员回复了我的邮件。他用一个不同的补丁(更通用的解决方案)解决了这个问题。