Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Linking error , although linker flags are correct

501 views
Skip to first unread message

aft

unread,
Jun 18, 2013, 10:17:46 AM6/18/13
to
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

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 :

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

The reason i can't read symbols out of `librt.so` is that they are "stripped".

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


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

The code i'm trying to compile is :

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

Stackoverflow reference : http://stackoverflow.com/questions/17150075/undefined-reference-to-clock-gettime-although-lrt-is-given

Siri Cruise

unread,
Jun 18, 2013, 11:07:30 AM6/18/13
to
In article <4dbcfe3f-8270-4cad...@googlegroups.com>,
aft <aft...@gmail.com> wrote:

> 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

Not an answer but you can perhaps find the entrypoint with

entrypoint=clock_gettime
find /usr/lib -exec sh -c \
"nm -U -j {} | grep -q $entrypoint && echo {}" \; 2>/dev/null
--
Daddy says Mormons are all programmers because their god is Cobol. Should
I ask Mormons to reschedule Bullwinkle?
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted.

Noob

unread,
Jun 18, 2013, 11:09:25 AM6/18/13
to
aft wrote:

> 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

What if you add another -lrt before -losip2?

Or use --start-group and --end-group
http://stackoverflow.com/questions/5651869/gcc-start-group-and-end-group-command-line-options
-Wl,--start-group -losip2 -lrt -Wl,--end-group

Rainer Weikusat

unread,
Jun 18, 2013, 12:04:57 PM6/18/13
to
aft <aft...@gmail.com> writes:
> 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
>
> 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.

According to some searching around on the web 'some gcc version'
(possibly "some vendor's gcc versions") pass --as-needed to the linker
by default and this implies that undefined symbols in libraries no
longer count regarding which 'other libraries' are considered to be
necessary and thus not discarded when linking. Your libosip2 likely
isn't linked with librt and because of the flag, the program also
won't be linked with it, cf

http://wiki.mandriva.com/en/Underlinking

> 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

If you want the 'dynamic symbols', you'll have to use nm -D, cf

[rw@sapphire]~ $nm -D /lib/librt.so.1 | grep clock
U __vdso_clock_gettime
0000000000003da0 T clock_getcpuclockid
0000000000003de0 T clock_getres
0000000000003e40 T clock_gettime
0000000000003fc0 T clock_nanosleep
0000000000003f40 T clock_settime

Fred Mobach

unread,
Jun 18, 2013, 1:26:34 PM6/18/13
to
aft wrote:

> 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
>
> The man page says :
>
>
> NAME
> clock_getres, clock_gettime, clock_settime - clock and time
> functions
>
> SYNOPSIS
> #include <time.h>
-----------------------++++++
<<snip>>

> Well things become very confusing because the following test code
> compiles and runs just fine :
>
> #include <time.h>
----------------++++++
> #include <unistd.h>
> #include <stdio.h>

<<snip>>

> The code i'm trying to compile is :
>
> #include <eXosip2/eXosip.h>
> #include <netinet/in.h>
> #include <unistd.h>

Am I mistaken when I miss here time.h?
--
Fred Mobach
website : https://fred.mobach.nl
.... In God we trust ....
.. The rest we monitor ..

Rainer Weikusat

unread,
Jun 18, 2013, 1:38:15 PM6/18/13
to
Fred Mobach <fr...@mobach.nl> writes:

[...]

>> The man page says :
>>
>>
>> NAME
>> clock_getres, clock_gettime, clock_settime - clock and time
>> functions
>>
>> SYNOPSIS
>> #include <time.h>
> -----------------------++++++
> <<snip>>
>
>> Well things become very confusing because the following test code
>> compiles and runs just fine :
>>
>> #include <time.h>
> ----------------++++++
>> #include <unistd.h>
>> #include <stdio.h>
>
> <<snip>>
>
>> The code i'm trying to compile is :
>>
>> #include <eXosip2/eXosip.h>
>> #include <netinet/in.h>
>> #include <unistd.h>
>
> Am I mistaken when I miss here time.h?

Yes. The 'example which can be compiled' includes calls to
clock_getttime so it needs time.h to stop the compiler from
complaining about the lack of a declaration for that. In the other
case, the clock_gettime call is contained in the libosip2 binary,
hence, there's no reason to include the header in the program supposed
to be compiled (includes have no link-time effects).

Ben Bacarisse

unread,
Jun 18, 2013, 4:18:30 PM6/18/13
to
aft <aft...@gmail.com> writes:

A couple of small points, not related to you actual question:

> The code i'm trying to compile is :
>
> #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);

You need to #include <stdio.h> for stdout to be defined (as you did in
your other test program).

> 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");

ex_init returns either -1 or 1, both of which cause "success" to be
printed.

> return 0;
> }

--
Ben.

Jorgen Grahn

unread,
Jun 18, 2013, 4:37:02 PM6/18/13
to
On Tue, 2013-06-18, Noob wrote:
> aft wrote:
>
>> 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
>
> What if you add another -lrt before -losip2?

Why would that help? I think you can assume those SIP libraries are
high-level stuff which at the most /use/ librt, not the other way
around.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Jorgen Grahn

unread,
Jun 18, 2013, 4:43:11 PM6/18/13
to
On Tue, 2013-06-18, Jorgen Grahn wrote:
> On Tue, 2013-06-18, Noob wrote:
>> aft wrote:
>>
>>> 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
>>
>> What if you add another -lrt before -losip2?
>
> Why would that help?

After reading the other replies, the answer might be "because you're
thinking of the static linking rules, and this is dynamic".

Rainer Weikusat

unread,
Jun 19, 2013, 4:10:29 AM6/19/13
to
Rainer Weikusat <rwei...@mssgmbh.com> writes:
> Fred Mobach <fr...@mobach.nl> writes:
>
> [...]
>
>>> The man page says :
>>>
>>>
>>> NAME
>>> clock_getres, clock_gettime, clock_settime - clock and time
>>> functions
>>>
>>> SYNOPSIS
>>> #include <time.h>
>> -----------------------++++++
>> <<snip>>
>>
>>> Well things become very confusing because the following test code
>>> compiles and runs just fine :
>>>
>>> #include <time.h>
>> ----------------++++++
>>> #include <unistd.h>
>>> #include <stdio.h>
>>
>> <<snip>>
>>
>>> The code i'm trying to compile is :
>>>
>>> #include <eXosip2/eXosip.h>
>>> #include <netinet/in.h>
>>> #include <unistd.h>
>>
>> Am I mistaken when I miss here time.h?
>
> Yes.

More accurately: 'sort of'. A minimal test program which can actually
be linked with the osip2 library needs to include sys/time.h thanks to
deficiencies in the osip2 headers:

-----------
#include <sys/time.h>
#include <osip2/osip.h>

int main(void)
{
osip_t *p;
osip_init(&p);
return 0;
}

Noob

unread,
Jun 19, 2013, 4:16:15 AM6/19/13
to
Rainer Weikusat wrote:

> More accurately: 'sort of'. A minimal test program which can actually
> be linked with the osip2 library needs to include sys/time.h thanks to
> deficiencies in the osip2 headers:

They'd say "Patch welcome!" ;-)

Rainer Weikusat

unread,
Jun 19, 2013, 4:22:46 AM6/19/13
to
Rainer Weikusat <rwei...@mssgmbh.com> writes:
> aft <aft...@gmail.com> writes:
>> 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

[...]

> According to some searching around on the web 'some gcc version'
> (possibly "some vendor's gcc versions") pass --as-needed to the linker
> by default and this implies that undefined symbols in libraries no
> longer count regarding which 'other libraries' are considered to be
> necessary and thus not discarded when linking. Your libosip2 likely
> isn't linked with librt and because of the flag, the program also
> won't be linked with it, cf
>
> http://wiki.mandriva.com/en/Underlinking

Some more information on this: This used to be the behaviour of the
-as-needed option when it was introduced with ld 2.15 up to ld 2.19,
the original documentation being

--as-needed causes DT_NEEDED tags to only be emitted for
libraries that satisfy some symbol reference from regular
objects which is undefined at the point that the library was
linked.

http://sourceware.org/binutils/docs-2.18/ld/Options.html#Options

Because the idea that libaries should be linked with their
dependencies apparently didn't have enough fans (nobody will ever
accuse 'the GNU project' of valueing what works more than what is
'right' [for some prefectly abitrary definition of 'right']), this
behaviour was changed with ld 2.20 so that symbol references from
either regular objects or shared libraries are taken into account, cf

--as-needed causes a DT_NEEDED tag to only be emitted for a library
that satisfies a symbol reference from regular objects which is
undefined at the point that the library was linked, or, if the
library is not found in the DT_NEEDED lists of other libraries
linked up to that point, a reference from another dynamic
library.

http://sourceware.org/binutils/docs-2.20/ld/Options.html#Options

'We' are still operating some Debian lenny system which have ld 2.18
installed. The Debian libosip2 does not need clock_gettime 'for some
reason' but it needs libpthread (without linking to it). In this
environment, the behaviour can be reproduced by trying to link the
'minimal test program' I already posted elsewhere,

--------------
#include <sys/time.h>
#include <osip2/osip.h>

int main(void)
{
osip_t *p;
osip_init(&p);
return 0;
}
-------------

gcc -Wl,-as-needed a.c -losip2 -lpthread

fails with

/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/libosip2.so: undefined reference to `sem_init'
/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/libosip2.so: undefined reference to `sem_destroy'
/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/libosip2.so: undefined reference to `pthread_create'

[etc]

the same command without the flag works.

aft

unread,
Jun 19, 2013, 6:05:33 AM6/19/13
to
On Tuesday, June 18, 2013 9:07:30 PM UTC+6, Siri Cruise wrote:
> In article <4dbcfe3f-8270-4cad...@googlegroups.com>,
>
> aft <aft...@gmail.com> wrote:
>
>
>
> > 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
>
>
>
> Not an answer but you can perhaps find the entrypoint with
>
>
>
> entrypoint=clock_gettime
>
> find /usr/lib -exec sh -c \
>
> "nm -U -j {} | grep -q $entrypoint && echo {}" \; 2>/dev/null

MY nm does not support "-U " or "-j" :)

And my librt.so is stripped anyway.

aft

unread,
Jun 19, 2013, 6:07:16 AM6/19/13
to
On Tuesday, June 18, 2013 9:09:25 PM UTC+6, Noob wrote:
> aft wrote:
>
>
>
> > 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
>
>
>
> What if you add another -lrt before -losip2?

I don't understand this.

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

So this symbol is undefined in libosip2. And according to standard
linking practice in linux, dependencies to of library should appear
"after" that library in command line.

Also This does not solve the problem.
Message has been deleted

aft

unread,
Jun 19, 2013, 6:12:59 AM6/19/13
to
That actually solved my problem. If i pass --no-as-needed flag, then it links fine.

Although i'm little confused why it works.

>
>
> > 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
>
>
>
> If you want the 'dynamic symbols', you'll have to use nm -D, cf
>
>
>
> [rw@sapphire]~ $nm -D /lib/librt.so.1 | grep clock
>
> U __vdso_clock_gettime
>
> 0000000000003da0 T clock_getcpuclockid
>
> 0000000000003de0 T clock_getres
>
> 0000000000003e40 T clock_gettime
>
> 0000000000003fc0 T clock_nanosleep
>
> 0000000000003f40 T clock_settime

Thanks for the tip.

aft

unread,
Jun 19, 2013, 6:17:23 AM6/19/13
to
arif@khost:~/sak/sak.exosip$ ld --version
GNU ld (GNU Binutils for Ubuntu) 2.22



aft

unread,
Jun 19, 2013, 6:45:23 AM6/19/13
to
Well the whole problem seems to be libosip2 does not lists librt.so as NEEDED. So when --as-needed flag is passed, -lrt is completely ignored.

arif@khost:~/sak/sak.exosip$ objdump -p /opt/osip2/lib/libosip2.so.10


Dynamic Section:
NEEDED libosipparser2.so.10
NEEDED libc.so.6



aft

unread,
Jun 19, 2013, 8:45:14 AM6/19/13
to
Well I've explained the whole thing here in "answers": http://stackoverflow.com/questions/17150075/undefined-reference-to-clock-gettime-although-lrt-is-given

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
0 new messages