3

I'm trying to build a program that takes 2 timestamps: the timestamp at the end of a first process, then the timestamp at the start of a second process. Then get the delta of the two.

But I cannot compile because the linker complains about clock_gettime, giving an undefined symbol error.

gcc (GCC) 3.2.1
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

void delay(unsigned int mseconds)
{
    clock_t goal = mseconds + clock();
    while (goal > clock());
}

int main()
{       
    struct timespec start, stop;

    double timeStampFull1;
    double timeStampFull2;

    FILE *fOut;
    fOut = fopen("fileOut.txt", "a");

    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
        perror( "clock gettime" );
        exit( EXIT_FAILURE );   
    }

    timeStampFull1 = (double)start.tv_sec + (double)(start.tv_nsec/1000000000.0); 

    delay(1);

    if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
        perror( "clock gettime" );
        exit( EXIT_FAILURE );
    }   

    timeStampFull2 = (double)stop.tv_sec + (double)(stop.tv_nsec/1000000000.0);

    printf("tv1: %f \n", timeStampFull1);
    printf("tv2: %f \n", timeStampFull2);

    fprintf(fOut, "TimeStartOfTest\t\t\t%f\n", timeStampFull1);
    fprintf(fOut, "TimeEndOfTest\t\t\t%f\n", timeStampFull2);


    fclose(fOut);

    return 0;
}

Here is the compiler (linker) error:

gcc -Wall -o time ./time.c
time.c:49:2: warning: no newline at end of file
Undefined                       first referenced
 symbol                             in file
clock_gettime                       /var/tmp//ccuu5CKe.o
ld: fatal: Symbol referencing errors. No output written to time
collect2: ld returned 1 exit status
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ice03
  • 33
  • 4

2 Answers2

6

The clock_gettime() function and a number of other functions are found in the rt (real time) library on modern versions of Solaris, and in the posix4 library (from the days when there was a POSIX part 4 aka POSIX.4 for 'Real Time' extensions) on ancient versions. The real time functions are now included in the base POSIX specification.

So, to resolve clock_gettime():

  • Add either -lrt or, since that didn't work for you, -lposix4 on Solaris.
  • Add -lrt on Linux.
  • Add neither on macOS.

On macOS, the functions (including the mathematical functions often found in -lm) are in the main system library. Apple does provide a dummy -lm library, but you don't need to use it.

Delving into some history, some older versions of Solaris such as Solaris 9 and, I think, Solaris 10 provide -lposix4; I've not used Solaris 11, but I'd expect the library to exist there, even if it is not strictly needed any more. Normally, the manual pages tell you about non-standard libraries that are needed to use a function. Going through the manuals on the Oracle site, I find:

So, on the face of it, using -lrt should have worked for you. However, if you are using an old enough version of Solaris (and the antique version of GCC suggests that you probably aren't using the latest version of Solaris), then you may need to use -lposix4 instead.

A Google search for 'libposix4.so solaris' yields:

where it says:

librt, libposix4 - POSIX.1b Realtime Extensions library

Historically, functions in this library provided many of the interfaces specified by the POSIX.1b Realtime Extension. See standards(5). This functionality now resides in libc(3LIB).

This library is maintained to provide backward compatibility for both runtime and compilation environments. The shared object is implemented as a filter on libc.so.1. New application development need not specify –lrt.

Going back through the version control information for a makefile of mine, I find that in November 1996, I added -lposix4 to a makefile; the prior version from June 1993 did not have that in it. So, it was a long (long) time ago. I'm not sure which version of Solaris you are using. Wikipedia on Solaris suggests that I made the change for Solaris 2.4 (1995) or Solaris 2.5 (1996). So, it may be that one of those versions added -lposix4 for clock_gettime(), or it may be that I wrote a program needing it in that timeframe but it was available earlier. (Just for your amusement, the first version of the makefile was dated 1987-01-27. It's been around for quite a while!)

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • wow! the `-lposix4` worked. i've been trying to fix this for days. thanks a lot. – ice03 Feb 11 '20 at 03:17
  • 1
    That's a museum piece of a GCC you're using. The current version (for another month or so) is 9.2.0; it will soon be 10.1.0. Version 3 of GCC should have been retired a decade ago. – Jonathan Leffler Feb 11 '20 at 03:20
  • @ice03 If `-lposix4` works, but `-lrt` doesn't, there might be something wrong with your Solaris installation. I can't recall any version of Solaris that didn't have `librt.so` somewhere. If you don't have a `librt.so` in `/lib` or `/usr/lib`, that would make me wonder what else is missing. – Andrew Henle Feb 11 '20 at 13:34
  • @JonathanLeffler says in the help that this machine is CDE 1.2. – ice03 Feb 12 '20 at 07:13
  • @AndrewHenle i cant find `librt.so` in `/usr/lib` – ice03 Feb 12 '20 at 07:15
  • 1
    @ice03: A Google search with 'solaris cde 1.2' suggests ancient versions of Solaris — 2.4 and 2.6 showed up for me. Those are old enough that it may be before `librt.so` was provided. You could probably save quite a lot on your electricity bill by upgrading to newer hardware. – Jonathan Leffler Feb 12 '20 at 08:09
  • @JonathanLeffler The [Solaris 2.6 documentation](https://docs.oracle.com/cd/E19504-01/index.html) shows no references to `-lrt` but quite a few to `-lposix4`. The [Solaris 8 documentation](https://docs.oracle.com/cd/E19455-01/805-6333/abstracts-73/index.html) does shows many references to `librt.so`, so `librt.so` must have been introduced either in Solaris 7 or 8. If I remember correctly, 2.6 was EOL'd at least 15 years ago. I have a 280R in my basement, and an even older 2500 - and I never turn them on as the power they suck is insane. – Andrew Henle Feb 14 '20 at 16:15
  • @AndrewHenle — I certainly used Solaris 2.6; it’s quite possible that I noted `-lposix4` back then and never needed to change it because Solaris pulls some insane backwards compatibility stunts (8-bit file descriptors in `FILE`, for example). Thanks for the information. – Jonathan Leffler Feb 14 '20 at 16:19
0

Run following command ./configure LDFLAGS=-lrt CFLAGS=-lrt

Arshid KV
  • 9,631
  • 3
  • 35
  • 36