如何使用CMake链接到C数学库?

phi*_*psK 24 c cmake

如何将math库添加到我的CMake文件中?这篇文章引用了添加一个目标链接库,但我对C不太熟悉.附加帖子 - 有人可以举一个例子.文档我正在使用C,我收到了一个undefined reference to 'pow'带有数学标题的pow方法.

cmake_minimum_required(VERSION 3.3)
project(CSCI-E-28-Unix-Linux-Systems-Programming)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES
    CMakeLists.txt
    getchar.c
    main.cpp
        hw0
    more01.c)

#target_link_libraries(<math.h> m)

add_executable(main main.cpp)
add_executable(getchar getchar.c)
add_executable(more01 more01.c)
add_executable(argu print_all_arguments.c)
add_executable(chars chars.c)
add_executable(ch4 ch4.c)
Run Code Online (Sandbox Code Playgroud)

usr*_*567 29

许多数学函数(pow,sqrt,fabs,log等)中声明math.h,并要求该库libm被链接.与libc自动链接的不同,它是libm一个单独的库,通常需要明确的链接.链接器假设所有库都以开头为止lib,因此链接到libm您的链接m.

您必须使用它target_link_libraries(ch4 m)来链接libm到您的目标.第一个参数必须是目标.因此必须在以下之后使用add_executable(ch4 ch4.c):

add_executable(ch4 ch4.c)
target_link_libraries(ch4 m)
Run Code Online (Sandbox Code Playgroud)

  • 令人惊讶的是,Windows上的Cygwin不需要这样做.但遗憾的是*nix需要. (4认同)
  • 对于 MSVC,这会导致以下构建错误: `[CMake] LINK : fatal error LNK1104: 无法打开文件 'm.lib'` (3认同)
  • 你能写出完整的正确答案吗?`m` 是占位符吗?或者只是常识,`math.c` 在一个名为 `m` 的库中?或者它是以我在上面的脚本中无法理解的方式声明的? (2认同)

Xal*_*dew 10

坦率地说,我有点惊讶这种问题对于Modern CMake仍然没有正确的答案。如今,推荐的(并且可移植的)方法是这样的:

find_library(MATH_LIBRARY m)
if(MATH_LIBRARY)
    target_link_libraries(MyTarget PUBLIC ${MATH_LIBRARY})
endif()
Run Code Online (Sandbox Code Playgroud)


Mic*_*rus 5

对于各种目标,最好测试是否需要添加库,如果需要,它位于何处以及如何命名。这是一种方法:

:
include(CheckLibraryExists)

CHECK_LIBRARY_EXISTS(m sin "" HAVE_LIB_M)                                                                                                
                                                                                                                                         
if (HAVE_LIB_M)                                                                                                                          
    set(EXTRA_LIBS ${EXTRA_LIBS} m)                                                                                                      
endif (HAVE_LIB_M)

:
//More tests & build-up of ${EXTRA_LIBS}
:

add_executable(ch4 ch4.c)
target_link_libraries(ch4 PUBLIC ${EXTRA_LIBS})
Run Code Online (Sandbox Code Playgroud)

对于libm是 一部分的目标libc,上述测试应该失败,即${EXTRA_LIBS}会错过它并且target_link不会尝试添加。