C++ error: undefined reference to 'clock_gettime' and 'clock_settime'
Asked Answered
C

5

172

I am pretty new to Ubuntu, but I can't seem to get this to work. It works fine on my school computers and I don't know what I am not doing. I have checked usr/include and time.h is there just fine. Here is the code:

#include <iostream>
#include <time.h>
using namespace std;

int main()
{
    timespec time1, time2;
    int temp;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
    //do stuff here
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
    return 0;
}

I am using CodeBlocks as my IDE to build and run as well. Any help would be great, thank you.

Caduceus answered 10/3, 2010 at 15:36 Comment(1)
You often need -D_XOPEN_SOURCE=600, too. Also see GCC with -std=c99 complains about not knowing struct timespec.Hazelwood
I
304

Add -lrt to the end of g++ command line. This links in the librt.so "Real Time" shared library.

Intend answered 10/3, 2010 at 15:38 Comment(6)
that works if I compile manually - any idea how I automate that in codeblocks?Caduceus
try Project -> Build Options -> Linker Settings ; then add library rtIntend
Your suggestion works fine for me..I am new to C...what does the -lrtdo ?Mythopoeic
@Mythopoeic It commands the linker to search for rt library and use it to resolve undefined symbols, en.wikipedia.org/wiki/Linker_(computing)Intend
Sorry to noob it up in this joint, but could you use that in a complete example, somehing like g++ -o main -lrt main.cpp does not work for meTini
@Tini Try putting -lrt after main.cpp - order of shared libraries matter - see this or that for more detailsIntend
M
44

example:

c++ -Wall filefork.cpp -lrt -O2

For gcc version 4.6.1, -lrt must be after filefork.cpp otherwise you get a link error.

Some older gcc version doesn't care about the position.

Murine answered 11/11, 2011 at 1:48 Comment(2)
Thank you, the -lrt not being in the right position was causing me a headache. Is there any motivation for this crazy (well, many say criminal) setting?Cockrell
@Cockrell - the order matters for historical reasons. Compilers used to just process each argument in order. Because libraries are "soft" references, as opposed to "hard" references in the *.o arguments, the library functions are ignored unless they are referenced previously, which means, to the left.Gaullism
H
38

Since glibc version 2.17, the library linking -lrt is no longer required.

The clock_* are now part of the main C library. You can see the change history of glibc 2.17 where this change was done explains the reason for this change:

+* The `clock_*' suite of functions (declared in <time.h>) is now available
+  directly in the main C library.  Previously it was necessary to link with
+  -lrt to use these functions.  This change has the effect that a
+  single-threaded program that uses a function such as `clock_gettime' (and
+  is not linked with -lrt) will no longer implicitly load the pthreads
+  library at runtime and so will not suffer the overheads associated with
+  multi-thread support in other code such as the C++ runtime library.

If you decide to upgrade glibc, then you can check the compatibility tracker of glibc if you are concerned whether there would be any issues using the newer glibc.

To check the glibc version installed on the system, run the command:

ldd --version

(Of course, if you are using old glibc (<2.17) then you will still need -lrt.)

Hoodmanblind answered 18/9, 2015 at 10:5 Comment(0)
I
27

I encountered the same error. My linker command did have the rt library included -lrt which is correct and it was working for a while. After re-installing Kubuntu it stopped working.

A separate forum thread suggested the -lrt needed to come after the project object files. Moving the -lrt to the end of the command fixed this problem for me although I don't know the details of why.

Inexplicable answered 10/11, 2011 at 10:53 Comment(1)
Quoting twkm from ircnet: the linker only maintains a list of symbols needed. once a file's symbols have been searched, only what it needs is kept, what it provides is discarded and it moves to the next filename. so left to right, but very forgetful.Burch
A
0

People arriving here with this error may have a different program intercepting the lookup for build tools, and removing it from your PATH will allow the preferred build tools to be executed.

I encountered this error because I had paths in my PATH with their own compiler and linker. Running make caused these build tools to be run rather than the system defaults.

which ld
/usr/local/fsl/bin/ld
echo $PATH
/home/mike/.nvm/versions/node/v18.19.1/bin:/usr/local/fsl/share/fsl/bin:/usr/local/freesurfer/7.3.2/bin:/usr/local/freesurfer/7.3.2/fsfast/bin:/usr/local/freesurfer/7.3.2/tktools:/usr/local/fsl/bin:/usr/local/fsl/share/fsl/bin:/usr/local/freesurfer/7.3.2/mni/bin:/usr/local/fsl/share/fsl/bin:/usr/local/fsl/share/fsl/bin:/home/mike/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/mike/.local/share/JetBrains/Toolbox/scripts:/home/mike/bin:/usr/local/fsl/bin:/opt/antsbin/ANTS-build/Examples:/home/mike/.config/gems/bin:/opt/workbench/bin_linux64:/home/mike/LocalProjects/jjm_utils/mri:/home/mike/abin

I re-exported my PATH without any of the clutter that was irrelevant to this project.

export PATH=/home/mike/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
which ld
/usr/bin/ld

In this shell, with the simplified PATH, the project built perfectly.

Abshier answered 29/4 at 21:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.