Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to link to the C math library with CMake?

Tags:

c

cmake

How do I add the math library to my CMake file? This post references adding a target link library, yet I am not too familiar with C. An Additional post - Could someone please demonstrate an example. Documentation I am using C and I receive an undefined reference to 'pow' with the pow method of the math header.

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) 
like image 397
phillipsK Avatar asked Jan 06 '16 04:01

phillipsK


Video Answer


2 Answers

Many mathematical functions (pow, sqrt, fabs, log etc.) are declared in math.h and require the library libm to be linked. Unlike libc, which is automatically linked, libm is a separate library and often requires explicit linkage. The linker presumes all libraries to begin with lib, so to link to libm you link to m.

You have to use it like target_link_libraries(ch4 m) to link libmto your target. The first argument must be a target. Thus it must be used after add_executable(ch4 ch4.c) like:

add_executable(ch4 ch4.c) target_link_libraries(ch4 m) 
like image 196
usr1234567 Avatar answered Oct 15 '22 16:10

usr1234567


For various targets it's a good idea to test if adding a library is needed or not and if so where it's located of how it's named. Here's one way to do it:

: 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}) 

For targets where libm is part of libc, the above test should fail, i.e. ${EXTRA_LIBS} will miss it and target_link will not try to add.

like image 35
Michael Ambrus Avatar answered Oct 15 '22 15:10

Michael Ambrus