gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 00:17:17 26 4
gpt4 key购买 nike

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

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

事情变得非常困惑,因为以下测试代码可以正常编译和运行:

#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 时,liker 仅链接到库的 NEEDED 部分中给出的库。

例如,

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

此处 --as-needed 在 libA 之前给出。因此在链接期间,链接器将检查 libANEEDED 部分。如果在 libANEEDED 部分只列出了 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

libosip2 没有将 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

它有 undefined symbol clock_gettime,由librt.so提供。

这实际上是 libosip2 开发者的错误,他们的 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 链接,这就是为什么它没有在其 NEEDED 列表中列出 librt

如果配置为:

 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

关于linux - 未定义对 `clock_gettime` 的引用,尽管给出了 `-lrt`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17150075/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com