简体   繁体   English

如何仅在使用CMake的Linux版本上使用特定于Linux的API和库?

[英]How to use Linux-specific APIs and libraries only on Linux builds with CMake?

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. 我有一个项目,我在Linux(主要)上运行,但有时在Darwin / Mac OS X上运行。我使用CMake在Linux上生成Makefile,在Mac OS X上生成Xcode项目。到目前为止,这一点运行良好。

Now I want to use some Linux-specific functions ( clock_gettime() and related functions). 现在我想使用一些特定于Linux的函数( clock_gettime()和相关函数)。 I get linker errors on Mac OS X when I try to use clock_gettime() , so I assume it is only available on Linux. 当我尝试使用clock_gettime()时,我在Mac OS X上遇到链接器错误,因此我认为它仅在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. 我准备在.c文件中引入有条件编译的代码,以便在Linux上使用clock_gettime() ,在Mac OS上使用普通的旧clock() (BTW I was planning to use #include <unistd.h> and #if _POSIX_TIMERS > 0 as the preprocessor expression, unless someone has a better alternative.) (顺便说一下,我打算使用#include <unistd.h>#if _POSIX_TIMERS > 0作为预处理程序表达式,除非有人有更好的选择。)

Things get tricky when it comes to the CMakeLists.txt file. 当谈到CMakeLists.txt文件时,事情变得棘手。 What is the preferred way of introducing linkage to Linux-specific APIs only under the Linux build in a cross-platform CMake project? 仅在跨平台CMake项目中的Linux构建下引入与特定于Linux的API的链接的首选方法是什么?

Note: An earlier revision of this question contained references to glibc, which was overly specific and confusing. 注意:此问题的早期版本包含对glibc的引用,这些内容过于具体且令人困惑。 The question is really about the right way to use Linux-specific APIs and libraries in a cross-platform CMake project. 问题实际上是在跨平台CMake项目中使用特定于Linux的API和库的正确方法。

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的Linux版本上使用特定于Linux的API和库?

CMake provides numerous useful constants that you can check in order to determine which system you are running: CMake提供了许多有用的常量 ,您可以检查这些常量以确定您正在运行的系统:

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...) (我知道你在询问glibc ,但是你真的想知道clock_gettime是否存在,对吧?但你的问题中没有任何内容是特定于Linux的......)

If you want to check for clock_gettime , you can use the preprocessor. 如果要检查clock_gettime ,可以使用预处理器。 If clock_gettime is present, then _POSIX_TIMERS will be defined. 如果存在clock_gettime ,则将定义_POSIX_TIMERS The clock_gettime function is part of an optional POSIX extension ( see spec ), so it is not Linux-specific but not universal either. clock_gettime函数是可选POSIX扩展的一部分( 参见规范 ),因此它不是特定于Linux的,也不是通用的。 Mac OS X does not have clock_gettime : it is not declared in any header nor defined in any library. Mac OS X没有clock_gettime :它没有在任何头中声明,也没有在任何库中定义。

#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. 这并没有解决您仍然需要在Linux上与-lrt链接的问题。 This is typically solved with something like AC_CHECK_LIB in Autoconf, I'm sure there's an equivalent in CMake. 这通常是用Autoconf中的AC_CHECK_LIB来解决的,我敢肯定在CMake中有一个等价物。

From man 2 clock_gettime : 来自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 that CLOCK_MONOTONIC , CLOCK_PROCESS_CPUTIME_ID , CLOCK_THREAD_CPUTIME_ID are available. 在可用这些函数的POSIX系统上,符号_POSIX_TIMERS<unistd.h>定义为大于0的值。符号_POSIX_MONOTONIC_CLOCK_POSIX_CPUTIME_POSIX_THREAD_CPUTIME表示CLOCK_MONOTONICCLOCK_PROCESS_CPUTIME_IDCLOCK_THREAD_CPUTIME_ID可用。 (See also sysconf(3).) (另请参阅sysconf(3)。)

On Darwin you can use the mach_absolute_time function if you need a high-resolution monotonic clock. 在Darwin上,如果需要高分辨率的单调时钟,可以使用mach_absolute_time函数。 If you don't need the resolution or monotonicity, you should probably be using gettimeofday on both platforms. 如果您不需要分辨率或单调性,则应该在两个平台上使用gettimeofday

还有内置的CMake宏来检查符号是否存在 - CheckSymbolExists

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM