cunixsolarissunos

clock_gettime() undefined symbol SunOS


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

Solution

  • 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():

    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!)