I have a project that I run on Linux (primarily), but sometimes on Darwin/Mac OS X. I use CMake to generate Makefiles on Linux and an Xcode project on Mac OS X. So far, this has worked well.
Now I want to use some Linux-specific functions (clock_gettime()
and related functions). I get linker errors on Mac OS X when I try to use clock_gettime()
, so I assume it is only available on Linux. I am prepared to introduce conditionally-compiled code in the .c files to use clock_gettime()
on Linux and plain old clock()
on Mac OS. (BTW I was planning to use #include <unistd.h>
and #if _POSIX_TIMERS > 0
as the preprocessor expression, unless someone has a better alternative.)
Things get tricky when it comes to the CMakeLists.txt file. What is the preferred way of introducing linkage to Linux-specific APIs only under the Linux build in a cross-platform CMake project?
Note: An earlier revision of this question contained references to glibc, which was overly specific and confusing. The question is really about the right way to use Linux-specific APIs and libraries in a cross-platform CMake project.
Abstracting away from your examples, and answering only this question:
How to use Linux-specific APIs and libraries only on Linux builds with CMake?
CMake provides numerous useful constants that you can check in order to determine which system you are running:
if (${UNIX})
# *nix-specific includes or actions
elsif (${WIN32})
# Windows-specific includes or actions
elsif (${APPLE})
# ...
endif (${UNIX})
(I know you're asking about glibc
, but you really want to know whether clock_gettime
is present, right? But nothing in your question is Linux-specific...)
If you want to check for clock_gettime
, you can use the preprocessor. If clock_gettime
is present, then _POSIX_TIMERS
will be defined. The clock_gettime
function is part of an optional POSIX extension (see spec), so it is not Linux-specific but not universal either. Mac OS X does not have clock_gettime
: it is not declared in any header nor defined in any library.
#include <time.h>
#include <unistd.h> /* for _POSIX_TIMERS definition, if present */
#if _POSIX_TIMERS
...use clock_gettime()...
#else
...use something else...
#endif
This doesn't solve the problem that you still have to link with -lrt
on Linux. This is typically solved with something like AC_CHECK_LIB
in Autoconf, I'm sure there's an equivalent in CMake.
From man 2 clock_gettime
:
On POSIX systems on which these functions are available, the symbol
_POSIX_TIMERS
is defined in<unistd.h>
to a value greater than 0. The symbols_POSIX_MONOTONIC_CLOCK
,_POSIX_CPUTIME
,_POSIX_THREAD_CPUTIME
indicate thatCLOCK_MONOTONIC
,CLOCK_PROCESS_CPUTIME_ID
,CLOCK_THREAD_CPUTIME_ID
are available. (See also sysconf(3).)
On Darwin you can use the mach_absolute_time
function if you need a high-resolution monotonic clock. If you don't need the resolution or monotonicity, you should probably be using gettimeofday
on both platforms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With