在C中使用pow时,CMake是否可以检测是否需要链接到libm?

LB-*_*B-- 7 c gcc cmake libm

对于某些编译器,在C程序中使用pow和某些其他功能需要链接到m.但是,某些编译器不需要这样做,并且在链接到m库时会出错.对于带有std::thread和的C++,存在几乎完全相同的情况pthread,但是CMake模块FindThreads完全缓解了这种情况 - 是否有一些类似于libm的模块?

检测CMake如何处理的最佳方法是什么?这是我目前的解决方案,这不太理想,因为有更多的C编译器,而不仅仅是GCC和MSVC:

if(NOT MSVC)
    target_link_libraries(my-c-target PUBLIC m)
endif()
Run Code Online (Sandbox Code Playgroud)

这适用于我的目的,但我很确定有些情况会失败并需要手动用户干预,这对于不了解这种默默无闻的人来说并不好玩.理想情况下,我不希望用户必须通过命令行指定他们的编译器是否很奇怪 ; 我想在CMake中自动检测它,因为这是CMake的全部内容.

arr*_*owd 8

您应该使用该CHECK_FUNCTION_EXISTS命令检查是否pow可以在没有其他标志的情况下使用.如果此检查失败,您可以将m库添加到CMAKE_REQUIRED_LIBRARIES变量,假设链接libm是缺少的.但是你需要CHECK_FUNCTION_EXISTS再次确保连接是足够的.

示例代码:

include(CheckFunctionExists)

if(NOT POW_FUNCTION_EXISTS AND NOT NEED_LINKING_AGAINST_LIBM)
  CHECK_FUNCTION_EXISTS(pow POW_FUNCTION_EXISTS)
  if(NOT POW_FUNCTION_EXISTS)
      unset(POW_FUNCTION_EXISTS CACHE)
      list(APPEND CMAKE_REQUIRED_LIBRARIES m)
      CHECK_FUNCTION_EXISTS(pow POW_FUNCTION_EXISTS)
      if(POW_FUNCTION_EXISTS)
          set(NEED_LINKING_AGAINST_LIBM True CACHE BOOL "" FORCE)
      else()
          message(FATAL_ERROR "Failed making the pow() function available")
      endif()
  endif()
endif()

if (NEED_LINKING_AGAINST_LIBM)
     target_link_libraries(your_target_here m)
endif()
Run Code Online (Sandbox Code Playgroud)


Byo*_*Lee 5

如果我理解正确的话,libm如果存在链接,则始终首选链接。

所以,CheckLibraryExists有效。

CMakeLists.txt

set(POW_LIBS "")
include(CheckLibraryExists)
check_library_exists(m pow "" LIBM)
if(LIBM)
    list(APPEND POW_LIBS "m")
endif()

...
target_link_libraries(${PROJECT_NAME} PUBLIC ${POW_LIBS})
Run Code Online (Sandbox Code Playgroud)

使用 Linux x86_64、glibc 2.23 cmake 3.13.2 进行测试