Why isn't cmake locating gtest and gmock libs? - c++

Here's a link to my project, just in case.
So, here's my CMakeLists.txt file:
cmake_minimum_required (VERSION 2.6)
enable_testing()
project (IeiuniumTela)
set (IeiuniumTela_VERSION_MAJOR 1)
set (IeiuniumTela_VERSION_MINOR 0)
set (IeiuniumTela_VERSION_PATCH 0)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin)
# TODO: Make conditional for OS X compilation
set(CMAKE_CXX_COMPILER g++-4.7)
set(CMAKE_CC_COMPILER gcc-4.7)
# TODO: Require gcc >= 4.7
set(SOURCES "${SOURCES}" "${CMAKE_BINARY_DIR}/src/http/request.cpp")
set(SOURCES "${SOURCES}" "${CMAKE_BINARY_DIR}/src/http/response.cpp")
set(SOURCES "${SOURCES}" "${CMAKE_BINARY_DIR}/src/http/server.cpp")
set(SOURCES "${SOURCES}" "${CMAKE_BINARY_DIR}/src/log.cpp")
set(SOURCES "${SOURCES}" "${CMAKE_BINARY_DIR}/src/main.cpp")
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
add_executable(ieiunium_tela.srv ${SOURCES})
target_link_libraries(ieiunium_tela.srv yaml-cpp)
target_link_libraries(ieiunium_tela.srv boost_system-mt)
set(GTEST_DIR "${CMAKE_BINARY_DIR}/../gtest-1.6.0")
include_directories(SYSTEM "${GTEST_DIR}/include")
find_library(GTEST_LIBRARY
NAMES gtest
libgtest
libgtest.a
PATHS "${GTEST_DIR}")
find_library(GTEST_LIBRARY_MAIN
NAMES gtest_main
libgtest_main
libgtest.a
PATHS "${GTEST_DIR}")
set(GMOCK_DIR "${CMAKE_BINARY_DIR}/../gmock-1.6.0")
include_directories(SYSTEM "${GMOCK_DIR}/include")
include_directories(SYSTEM "${GMOCK_DIR}/gtest/include")
find_library(GMOCK_LIBRARY
NAMES gmock
libgmock
libgmock.a
PATHS "${GMOCK_DIR}")
find_library(GMOCK_LIBRARY_MAIN
NAMES gmock_main
libgmock_main
libgmock_main.a
PATHS "${GMOCK_DIR}")
set(TEST_SOURCES "${TEST_SOURCES}" "${CMAKE_BINARY_DIR}/test/unit/http/test_request.cpp")
set(TEST_SOURCES "${TEST_SOURCES}" "${CMAKE_BINARY_DIR}/test/unit/http/test_response.cpp")
set(TEST_SOURCES "${TEST_SOURCES}" "${CMAKE_BINARY_DIR}/test/unit/http/test_server.cpp")
set(TEST_SOURCES "${TEST_SOURCES}" "${CMAKE_BINARY_DIR}/test/unit/test_log.cpp")
set(TEST_SOURCES "${TEST_SOURCES}" "${CMAKE_BINARY_DIR}/test/unit/test_main.cpp")
add_executable(ieiunium_tela.srv_TEST ${TEST_SOURCES})
target_link_libraries(ieiunium_tela.srv_TEST ${GTEST_LIBRARY} ${GTEST_LIBRARY_MAIN})
target_link_libraries(ieiunium_tela.srv_TEST ${GMOCK_LIBRARY} ${GMOCK_LIBRARY_MAIN})
And, here's my question: Why isn't cmake finding my gtest/gmock libs?
I've gone into their respective directories and built them using ./configure && make -j4 and a brief find for the shared libraries shows them there.

Another option would be to build gtest and gmock as part of your main CMake build rather than building them separately and using find_package() or find_library(). This comes with some advantages, including:
They are built with the same compiler and settings as your main build, so there won't be issues with mismatched symbols, etc.
No manual steps required before the build and no need to tell CMake where to find things in your main CMakeLists.txt.
I recently wrote an article about how to download and build gtest as part of your build. Unlike the more commonly suggested approaches, my article shows how to download gtest during configure time (i.e. when CMake is run), which then allows you to bring it into your project using add_subdirectory(). This makes the gtest and gtest_main CMake targets directly available to your project, so you can just link against them like any other library. The approach is general and may work for mock too. You can find that article here:
https://crascit.com/2015/07/25/cmake-gtest/
Update: This approach is now also part of the googletest documentation.

The gtest/gmock libraries aren't built to the actual root of these projects. I believe on Linux they're built to "lib" inside the root.
To tell CMake to search in "lib" but without modifying your GTEST_DIR or GMOCK_DIR variables, you can use the PATH_SUFFIXES argument to the find_library command:
find_library(GTEST_LIBRARY
NAMES gtest
libgtest
libgtest.a
PATHS "${GTEST_DIR}"
PATH_SUFFIXES lib)
You can add a list of suffixes to give values appropriate for Windows builds too if required.
There is a standard CMake module provided to find gtest (FindGTest). You could look at the code in there for ideas, or actually use it instead of your own code. Unfortunately, there isn't a FindGMock module.
I have a couple of other minor points.
It might be worth considering allowing the GTEST_DIR and GMOCK_DIR variables to be set by the user via the -D flag to allow these to exist anywhere relative to your project's root. In that case, you'd only set them inside the CMakeLists.txt if they weren't already set.
Another minor point is that GMock comes with GTest included. You could just allow users to build GMock, and then find and use the version inside the GMock tree.

Related

How to use Caffe library in C++ project with CMakeLists.txt

I'm trying to use Caffe in my C++ project which I compile with CMakeLists.txt, but it doesn't want to work. My only line in the code is
#include <caffe/caffe.hpp>
I compiled Caffe myself, it is installed in the directory "/home/tamas/caffe". My CMakeLists.txt looks like this so far:
cmake_minimum_required (VERSION 3.5)
include(FindPkgConfig)
project (main)
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD_REQUIRED TRUE)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -pthread")
set (source_dir "${PROJECT_SOURCE_DIR}/src/")
set (OpenCV_DIR "/home/tamas/opencv/include/opencv2")
set (Caffe_DIR "/home/tamas/caffe")
file (GLOB source_files "${source_dir}/ssd_video.cpp")
find_package(OpenCV 4.4.0 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
find_package(Caffe REQUIRED)
include_directories(${Caffe_INCLUDE_DIRS})
add_executable (main ${source_files})
target_link_libraries(main ${OpenCV_LIBS})
target_link_libraries(main ${Caffe_LIBRARIES})
The error is the following:
CMake Error at CMakeLists.txt:24 (find_package):
By not providing "FindCaffe.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Caffe", but
CMake did not find one.
Could not find a package configuration file provided by "Caffe" with any of
the following names:
CaffeConfig.cmake
caffe-config.cmake
Add the installation prefix of "Caffe" to CMAKE_PREFIX_PATH or set
"Caffe_DIR" to a directory containing one of the above files. If "Caffe"
provides a separate development package or SDK, be sure it has been
installed.
-- Configuring incomplete, errors occurred!
The problem is that I have searched and I don't have a FindCaffe.cmake file on my computer. I found an example for CaffeConfig.cmake, but I tried it and it doesn't work either.
Is there a way I can link Caffe with my C++ project? Thanks!
To fix this issue you may do the following:
Download this FindCAFFE.cmake file
Create cmake dir in your repo root directory and put the downloaded file there.
Modify your CMake file:
add set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
change set (Caffe_DIR "/home/tamas/caffe") to set (CAFFE_ROOT_DIR "/home/tamas/caffe")
change find_package(Caffe REQUIRED) to find_package(CAFFE REQUIRED)
use CAFFE_INCLUDE_DIRS and CAFFE_LIBRARIES for include directories and link libraries respectively
Clean up your build dir and run cmake command again
<library>_DIR should not be set manually in CMake code usually. There are better alternatives that should be used as setting these variable won't necessarily do what you want. It won't change where find_package finds its libraries.
The CaffeConfig.cmake file is generated when building Caffe. You should never download another one, these files are compatible only with a specific build configuration.
The Caffe library supports to be used with CMake, so FindCaffe.cmake is unnecessary.
For find_package to work, either set the <package>_ROOT variable (require CMake 3.12 minimum) or you must append the install path in CMAKE_PREFIX_PATH. Here's a CMake example that uses the prefix path:
# If you only built the library
list (APPEND CMAKE_PREFIX_PATH "/home/tamas/caffe/build-dir")
# If you installed the library there
list (APPEND CMAKE_PREFIX_PATH "/home/tamas/caffe/")
find_package(Caffe REQUIRED)
Note that the Caffe_LIBRARIES and Caffe_INCLUDE_DIRS won't be set. This is old CMake style and the Caffe library uses the new style. This is what you should do:
target_link_libraries(main PUBLIC caffe caffeproto)
This line add both include directory and adds linking to the libraries too.

Integrate CMake subproject with another

I've wrote a C++ library MyLib and I'd like to integrate it with another project ExternPro. So in ExternPro I wrote CMakeLists.txt like this:
add_subdirectory(MyLib)
ADD_EXECUTABLE(test test.cpp)
include_directories(${MyLib_INCLUDE_DIRS})
target_link_libraries(test ${MyLib_LIBRARIES})
To set variables MyLib_LIBRARIES and MyLib_INCLUDE_DIRS I wrote:
set(MyLib_LIBRARIES ${PROJECT_SOURCE_DIR}/src/MyLib.a CACHE INTERNAL "")
set(MyLib_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "")
But something wrong "No rule to make target MyLib/src/MyLib.a, needed by test. Stop."
So my question is, how should I wrote CMakeLists.txt correctly so cmake could help me build MyLib first and then take care of dependencies of ExternPro?
If those are two separate projects, I normally use "CMake find scripts" to reference one library from the other: http://www.vtk.org/Wiki/CMake:How_To_Find_Libraries#Writing_find_modules
But I normally use slightly different find script than described there (FindMyLibrary.cmake):
# Find MyLibrary installation
#
# This module needs following variables specified (e.g. through cmake -Dvar=)
# MyLibrary_ROOT_DIR - root directory of the library installation
#
# This module defines the following variables:
# MyLibrary_INCLUDE_DIRS - Where to find the public headers
# MyLibrary_LIBRARIES - List of mandatory and optional libraries
# MyLibrary_FOUND - True if an installation was found
#
# Configuration variables for tis module:
# MyLibrary_USE_STATIC_LIBS - Set to ON to force the use of the static
# libraries. Default is OFF.
# If MyLibrary_ROOT_DIR was defined in the environment, use it.
if(NOT MyLibrary_ROOT_DIR AND NOT $ENV{MyLibrary_ROOT_DIR} STREQUAL "")
set(MyLibrary_ROOT_DIR $ENV{MyLibrary_ROOT_DIR})
endif()
if(NOT MyLibrary_ROOT_DIR)
set(MyLibrary_ROOT_DIR /usr)
endif()
message(STATUS "Using MyLibrary_ROOT_DIR: ${MyLibrary_ROOT_DIR}")
find_path(MyLibrary_INCLUDE_DIRS
NAMES mylib/mylib.hpp
PATHS ${MyLibrary_ROOT_DIR}
PATH_SUFFIXES include)
# Here we set the default components
if(NOT MyLibrary_FIND_COMPONENTS)
set(MyLibrary_FIND_COMPONENTS mylibrary)
endif()
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
if(MyLibrary_USE_STATIC_LIBS)
set(_mylib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif()
endif()
foreach(COMPONENT ${MyLibrary_FIND_COMPONENTS})
find_library(MyLibrary_${COMPONENT}_LIBRARY
NAMES ${COMPONENT}
HINTS ${MyLibrary_ROOT_DIR}
PATH_SUFFIXES lib64 lib
NO_DEFAULT_PATH)
set(MyLibrary_LIBRARIES ${MyLibrary_LIBRARIES} ${MyLibrary_${COMPONENT}_LIBRARY})
endforeach()
# Restore the original find library ordering
if(MyLibrary_USE_STATIC_LIBS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_mylib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
# handle the QUIETLY and REQUIRED arguments and set MyLibrary_FOUND to
# TRUE if all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
MyLibrary "Could NOT find MyLibrary: set MyLibrary_ROOT_DIR to a proper location"
MyLibrary_LIBRARIES
MyLibrary_INCLUDE_DIRS)
mark_as_advanced(MyLibrary_INCLUDE_DIRS MyLibrary_LIBRARIES)
Then used like this:
find_package(MyLibrary REQUIRED)
include_directories(SYSTEM ${MyLibrary_INCLUDE_DIRS})
target_link_libraries(${TARGET}
${MyLibrary_LIBRARIES}
)
Basically, it goes like this:
The library is built and installed (make install) to either the default location (e.g. /usr), or some other location (usual in development).
The FindMyLibrary.cmake is part of the library installation (for RPM the library devel package) and installs as well (into ${instdir}/share/cmake/Modules, for example).
The dependent project then adds the path to the CMAKE_MODULE_PATH and uses the find script to find the public headers and libraries as installed.
The advantage is that this way you can either use it during the development (when you have the library sources and build the library), or without the library sources as well (with just the library and headers - the devel package - installed in the system).
Similar technique is normally used by Boost etc. (the find scripts provided already by the CMake).
Instead of path to the library, use library target for target_link_libraries.
Assuming your library project contains
add_library(MyLib ...)
Linking of executable in main project should be performed with
target_link_libraries(test MyLib)
First of all this doesn't work because variables set in a subdirectory are not set for the parent directory.
So to solve this properly you should define MyLib like:
add_library(MyLib ...)
target_include_directories(MyLib INTERFACE ${PROJECT_SOURCE_DIR}/include)
And for the ExternPro you just need to link to MyLib:
target_link_libraries(test MyLib)
This will automatically add the include directory to test and link MyLib properly.

gtest setup cmake to get it run

I want to include gtest to my C++ project. I am using Clion as IDE, which should work. Some tests are already working, but I cannot use any functions from B_RocChoice.h. It says that the function is not declared in this scope.
Can somebody tell me what I am doing wrong? How I must change my CMakeLists.txt files that it recogizes my methods?
This is my basic_tests.cpp, where my testcases will be written.
This is my Directory.
Here, the most outer CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(cli)
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
set(SOURCE_FILES
include/A_WowbaggerChoice.h
include/AbstractChoice.h
include/B_RocChoice.h
include/C_CnnChoice.h
include/D_DetectorChoice.h
include/E_LearningChoice.h
include/Help.h
include/MyException.h
include/StartScreen.h
include/tinyxml.h
include/types.h
src/A_WowbaggerChoice.cpp
src/AbstractChoice.cpp
src/B_RocChoice.cpp
src/C_CnnChoice.cpp
src/D_DetectorChoice.cpp
src/E_LearningChoice.cpp
src/Help.cpp
src/main.cpp
src/MyException.cpp
src/StartScreen.cpp
tinyxml/tinystr.cpp
tinyxml/tinystr.h
tinyxml/tinyxml.cpp
tinyxml/tinyxml.h)
add_subdirectory(googletest)
add_executable(cli ${SOURCE_FILES})
target_link_libraries( cli ${OpenCV_LIBS} )
CMakeLists.txt for gtest.
cmake_minimum_required(VERSION 2.6.2)
project( googletest-distribution )
enable_testing()
option(BUILD_GTEST "Builds the googletest subproject" ON)
#Note that googlemock target already builds googletest
option(BUILD_GMOCK "Builds the googlemock subproject" OFF)
if(BUILD_GMOCK)
add_subdirectory( googlemock )
elseif(BUILD_GTEST)
add_subdirectory( googletest )
endif()
add_subdirectory(basic_tests)
CMakeLists.txt for basic_tests
include_directories($(gtest_SOURCE_DIR}/include
${getest_SOURCE_DIR}))
#include_directories(../../src/)
include_directories(../../include/)
add_executable(runBasicCli
basic_check.cpp)
target_link_libraries(runBasicCli gtest gtest_main)
#target_link_libraries(cli)
I'm assuming your compiler is complaining it can't find the B_RocChoices.h header? Your question seems to imply the compiler error is about not finding a function, but B_RocChoices is a header and not a function in your basic_tests.cpp file.
Assuming your problem is that the compiler isn't finding the B_RocChoices.h header, I expect that when you include_directories(../../include) you are wanting to make the directory where B_RocChoices.h resides part of the header search path. This is a relative path, so it depends where the compiler is being run from as to what path it means (it wouldn't work if you were doing out of source builds, for example). Try using either CMAKE_SOURCE_DIR or CMAKE_CURRENT_SOURCE_DIR to define the path unambiguously. For example:
include_directories(${CMAKE_SOURCE_DIR}/include)
If you are using CMake 2.8.11 or later, I'd recommend you consider using target_include_directories() instead and probably also read up on target_link_libraries(). Together, these allow you to make the header search paths and linked libraries specific to a target rather than global to all targets. Lastly, if you prefer to download GoogleTest as part of your build rather than embedding it directly in your project sources, you may find the following link useful:
https://crascit.com/2015/07/25/cmake-gtest/

CMake third party library undefined reference

I already read and searched a lot (e.g. 1 2 3, several docs for CMake, similar projects, etc. to find a solution but I have not been able to solve my problem. I am relatively new to Cmake and Linux (Ubuntu 14.04).
I want to use libsbp (https://github.com/swift-nav/libsbp) to write a program in C++ to communicate with a GPS module. I cloned the repository and installed the C-Library. So now in /usr/local/lib there are two files: libsbp.so and libsbp-static.a and the headers are in /usr/local/include/libsbp
In my own project I include the headers with #include "libsbp/sbp.h" which also works.
Now the Problem: if I want to use a method from libsbp e.g. sbp_state_init(&s); I get undefined reference to "sbp_state_init(sbp_state_t*)"
The relevant part of my Cmake for my own project:
link_directories(/usr/local/lib)
add_executable(main ${QT_SOURCES} ${QT_HEADER_HPP})
target_link_libraries(main ${QT_LIBRARIES} ${catkin_LIBRARIES} sbp)
As I said before, I tried some things:
find_library(SBP_LIB sbp /usr/local/lib) -> same error
same goes for using libsbp in target_link_libraries or searching for it
link_directory(/usr/local/lib)
trying different paths, even moveing libsbp.so into the project directory and "finding" it with ${CMAKE_CURRENT_SOURCE_DIR}
Maybe you can help me!
edit:
this is the CMakeList.txt from the libsbp/c/src directory
if (NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON)
endif (NOT DEFINED BUILD_SHARED_LIBS)
file(GLOB libsbp_HEADERS "${PROJECT_SOURCE_DIR}/include/libsbp/*.h")
include_directories("${PROJECT_SOURCE_DIR}/CBLAS/include")
include_directories("${PROJECT_SOURCE_DIR}/clapack-3.2.1-CMAKE/INCLUDE")
include_directories("${PROJECT_SOURCE_DIR}/lapacke/include")
include_directories("${PROJECT_SOURCE_DIR}/include/libsbp")
set(libsbp_SRCS
edc.c
sbp.c
)
add_library(sbp-static STATIC ${libsbp_SRCS})
install(TARGETS sbp-static DESTINATION lib${LIB_SUFFIX})
if(BUILD_SHARED_LIBS)
add_library(sbp SHARED ${libsbp_SRCS})
install(TARGETS sbp DESTINATION lib${LIB_SUFFIX})
else(BUILD_SHARED_LIBS)
message(STATUS "Not building shared libraries")
endif(BUILD_SHARED_LIBS)
install(FILES ${libsbp_HEADERS} DESTINATION include/libsbp)
this is the CMakeList.txt from /libsbp/c/
cmake_minimum_required(VERSION 2.8.9)
project(libsbp)
# Setup flags for Code Coverage build mode
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} --coverage" CACHE STRING
"Flags used by the C++ compiler for building with code coverage."
FORCE )
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_DEBUG} --coverage" CACHE STRING
"Flags used by the C compiler for building with code coverage."
FORCE )
SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
"${CMAKE_EXE_LINKER_FLAGS_DEBUG} --coverage" CACHE STRING
"Flags used for linking binaries with code coverage."
FORCE )
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} --coverage" CACHE STRING
"Flags used by the shared libraries linker during builds with code coverage."
FORCE )
mark_as_advanced(
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
# Update the documentation string of CMAKE_BUILD_TYPE for GUIs
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage."
FORCE )
# Set project version using Git tag and hash.
execute_process(
COMMAND git describe --dirty --tags --always
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE GIT_VERSION_FOUND
ERROR_QUIET
OUTPUT_VARIABLE GIT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (GIT_VERSION_FOUND)
set(VERSION "unknown")
else (GIT_VERSION_FOUND)
set(VERSION ${GIT_VERSION})
endif (GIT_VERSION_FOUND)
# Set project version explicitly for release tarballs.
#set(VERSION foo)
message(STATUS "libsbp version: ${VERSION}")
cmake_minimum_required(VERSION 2.8)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# Some compiler options used globally
set(CMAKE_C_FLAGS "-Wall -Wextra -Wno-strict-prototypes -Wno-unknown-warning-option -Werror -std=gnu99 ${CMAKE_C_FLAGS}")
add_subdirectory(src)
add_subdirectory(docs)
add_subdirectory(test)
It seems that your program uses C++ and the library is written in C.
Symbols in C and C++ are encoded differently (mangled). When including C headers from C++ you need to tell the compiler. This can be done by declaring the symbols extern "C".
extern "C" {
#include <libsbp/sbp.h>
}
Some libraries already include this in their headers, but not sbp.
You have (at least) two possibilities:
Installing the library (this is what you did)
Integrating the library in your CMake project
When installing the library, the target_link_libraries command needs to be modified slightly:
find_library(SBP_LIB sbp /usr/local/lib)
target_link_libraries(main ${QT_LIBRARIES} ${catkin_LIBRARIES} ${SBP_LIB})
When you integrate the library in your CMake project, you can directly use the following command without using find_library. This works, because the library is known to CMake since it is built within the current project.
target_link_libraries(main ${QT_LIBRARIES} ${catkin_LIBRARIES} sbp)

how to include NTL using CMake

I use this line to compile a simple program:
g++ main.cc -lntl -lm -lgmp
How do you include this into CMake?
find_package(NTL REQUIRED)
find_package(GMP REQUIRED)
Doesn't work. And gives the following error:
CMake Error at CMakeLists.txt:30 (find_package):
Could not find module FindNTL.cmake or a configuration file for package
NTL.
...
.
and
SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=c++0x -lntl -lm -lgmp)
Doesn't work either (but I think it's just wrong in general).
Thank you!
If ntl, m, and gmp libraries are usually installed to somewhere in the default path (e.g. /usr/ or /usr/local/), you could simply do something like:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(Test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(test main.cc)
target_link_libraries(test ntl m gmp)
This is probably closest to your original g++ command, but it isn't very robust however; if any of the libraries aren't found, you won't know about it until you try linking. If you want to fail at configure time (i.e. while running CMake), you could add find_library calls for each of the required libs, e.g.
find_library(NTL_LIB ntl)
if(NOT NTL_LIB)
message(FATAL_ERROR "ntl library not found. Rerun cmake with -DCMAKE_PREFIX_PATH=\"<path to lib1>;<path to lib2>\"")
endif()
You'd then have to change your target_link_libraries command to
target_link_libraries(test ${NTL_LIB} ${M_LIB} ${GMP_LIB})
You'd probably also then have to do a find_file for one of each lib's header files to find out the appropriate path to add via the include_directories command (which translates to -I for g++).
Note, it's important to put quotes around the extra CXX_FLAGS arguments, or CMake treats them like separate values in a list and inserts a semi-colon between the flags.
For further information about find_library, find_file, etc. run:
cmake --help-command find_library
cmake --help-command find_file
Regarding your error:
It doesn't look like there's a FindNTL.cmake module included with CMake. That means you'll have to either:
Write your own FindNTL.cmake,
Find another that somebody else has written,
Hack together a solution that:
Checks if NTL is installed
Provides link targets, relevant flags, etc.
From a (rather quick) Google search, it appears somebody has an NTL module for CMake. Since NTL use GMP, you will probably need the associated GMP module for CMake. It doesn't look like a fully-featured CMake module, but it also appears to be the best thing out there (again, it was a quick Google search, and I don't use NTL).
To use, you'll want to add some things to your CMakeLists.txt:
# Let CMake know where you've put the FindNTL.cmake module.
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/CMake/Modules")
# Call the FindNTL module:
find_package(NTL REQUIRED)
SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=c++0x -lntl -lm -lgmp)
Yes, this is wrong. You don't want to be setting your CXX_FLAGS with linking directives. I would use:
SET ( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=cxx0x )
to set the Cxx standard you want to use. To actually link to libraries, you'll want to:
Ensure that you've found the libraries (with the relevant find_package ( FOO ) lines)
Link those against your target, like this:
# Build the Foo executable. (Or library, or whatever)
add_executable (FooEXE ${Foo_SOURCES} )
target_link_libraries (FooEXE
${bar_LIBRARIES}
${baz_LIBRARY}
)
Please note! ${bar_LIBRARIES} and ${baz_LIBRARY} is not a typo; there's no standard way of setting the relevant libraries in the FindFOO.cmake modules, which is, in my opinion, an annoyance. If one doesn't work, try the other, or, worst case, have a look in the relevant FindFOO.cmake file (there's a bunch installed with CMake by default) to see what each one uses. With the link i provided, you can use ${NTL_LIB} and ${GMP_LIB}.