Keywords: C++ compilation error | undefined reference | clock_gettime | librt library | Linux linker | POSIX time functions
Abstract: This paper provides an in-depth examination of the 'undefined reference to clock_gettime' and 'undefined reference to clock_settime' errors encountered during C++ compilation in Linux environments. By analyzing the implementation mechanisms of POSIX time functions, the article explains why linking the librt library is necessary and presents multiple solutions, including compiler option configurations, IDE settings, and cross-platform compatibility recommendations. The discussion further explores the role of the real-time library (librt), fundamental principles of the linking process, and best practices to prevent similar linking errors.
Problem Background and Error Manifestation
When developing C++ applications on Linux systems, particularly Ubuntu, developers frequently encounter compilation errors related to time functions. A typical error message is: undefined reference to 'clock_gettime' or undefined reference to 'clock_settime'. These errors typically occur when attempting to use POSIX-standard time functions, even when the <time.h> header file has been correctly included.
Root Cause Analysis
The fundamental cause of this issue lies in the linker's inability to locate the implementations of the relevant functions during the linking phase. Although the <time.h> header file declares the clock_gettime() and clock_settime() functions, their actual implementations are not part of the standard C library but reside in a separate shared library called librt (Real Time Library).
In the POSIX standard, real-time extension functionalities are separated into distinct libraries to enhance modularity. When the compiler processes code like:
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
timespec time1, time2;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
// Perform some operations
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
return 0;
}
The preprocessor includes the function declarations from the header file, but during the linking phase, the linker needs to locate the concrete implementations of these functions. If the librt library is not specified for linking, the linker cannot resolve these symbol references, resulting in "undefined reference" errors.
Solutions
Primary Solution: Linking the librt Library
The most direct and effective solution is to add the -lrt option to the compilation command, instructing the linker to link against the real-time library:
g++ -o program program.cpp -lrt
The -lrt option directs the linker to search for library files named librt.so (shared library) or librt.a (static library). The linker will search standard library paths for these files and link their function implementations into the final executable.
Configuration in IDEs
For developers using CodeBlocks, Visual Studio Code, or other IDEs, it is necessary to add linker options in project settings or build configurations:
- CodeBlocks: Navigate to "Project > Build options > Linker settings" and add
-lrtunder "Other linker options" - CMake Projects: Add
target_link_libraries(your_target rt)in CMakeLists.txt - Makefile Projects: Add
-lrtto the LDFLAGS variable
Verifying the Solution
After adding the -lrt option, the following commands can be used to verify successful linking:
# Compile and link
$ g++ -o time_test time_test.cpp -lrt
# Run the program
$ ./time_test
# Check libraries depended on by the executable
$ ldd time_test | grep rt
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f8c4a200000)
In-Depth Understanding of the librt Library
librt (Real Time Library) is part of the POSIX.1b real-time extension standard, providing the following main functionalities:
- High-Precision Timing:
clock_gettime()supports nanosecond-level time retrieval - Multiple Clock Types: Including system clock, process CPU time, thread CPU time, etc.
- Timer Operations: Functions such as
timer_create(),timer_settime() - Asynchronous I/O: POSIX asynchronous I/O interfaces
- Message Queues: Inter-process communication mechanisms
In most modern Linux distributions, the librt library is typically pre-installed. It can be checked using:
$ ldconfig -p | grep librt
librt.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/librt.so.1
librt.so (libc6,x86-64) => /lib/x86_64-linux-gnu/librt.so
Cross-Platform Compatibility Considerations
While the -lrt solution is effective on most Linux systems, the following factors should be considered for cross-platform development:
- macOS Systems: macOS does not use the
librtlibrary; equivalent functionalities are integrated into system libraries, requiring no additional linking - Windows Systems: Windows lacks direct equivalents, necessitating different APIs (e.g.,
QueryPerformanceCounter) - Older Linux Versions: Some older versions might integrate real-time functions within
libc, but modern distributions follow modular designs
For better cross-platform compatibility, conditional compilation can be considered:
#ifdef __linux__
// Linux-specific code
#include <time.h>
// Requires linking with -lrt during compilation
#elif defined(__APPLE__)
// macOS-specific code
#include <mach/mach_time.h>
#elif defined(_WIN32)
// Windows-specific code
#include <windows.h>
#endif
Best Practices to Prevent Similar Errors
- Understand Function Dependencies: Consult documentation to determine if additional libraries need linking when using new functions
- Utilize pkg-config: For complex library dependencies, use the
pkg-configtool to automatically obtain correct compilation options - Automate Build Systems: Employ build systems like CMake or Autotools to automatically handle platform differences
- Test Across Platforms: Test build processes on different platforms early in development
- Consult Manual Pages: Linux man pages often indicate required libraries for functions; e.g.,
man clock_gettimedisplays "Link with -lrt"
Conclusion
The undefined reference to 'clock_gettime' error is a common issue in Linux C++ development, fundamentally caused by POSIX real-time function implementations residing in the separate librt library. Adding the -lrt linker option effectively resolves this problem. Understanding modular library design, mastering correct linking methods, and considering cross-platform compatibility are key to avoiding similar linking errors. As developers deepen their understanding of the Linux development environment, they can more efficiently handle such compilation and linking issues, thereby enhancing development productivity.