CMAKE: how to include and link alternative libraries? - boost

My project need four libraries including MPI, BOOST, VTK and SQLITE3. Since BOOST and SQLITE3 are too old, I installed new version of the two libraries and the old version are not uninstalled:
BOOST # alternative BOOST
|___include
|___lib
|
SQLITE # alternative SQLITE
|___bin
|___include
|___lib
|___share
|
Mypoject
|___src
| |___CMakeLists
| |___.cpp and .h file
|
|___CMakeLists
And I used FindSQLite3.cmake to find the alternative SQLite3:
# Look for the header file.
FIND_PATH(SQLITE3_INCLUDE_DIR sqlite3.h /export/home/hh/hh/sqlite/include)
# Look for the library.
FIND_LIBRARY(SQLITE3_LIBRARY sqlite3 /export/home/hh/hh/sqlite/lib)
# Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE.
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR)
# Copy the results to the output variables.
IF(SQLITE3_FOUND)
SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY})
SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR})
ELSE(SQLITE3_FOUND)
SET(SQLITE3_LIBRARIES)
SET(SQLITE3_INCLUDE_DIRS)
ENDIF(SQLITE3_FOUND)
MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES)
I am trying to link alternative libraries by following lines:
# CMake version
CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
SET(VERSION 0.1)
SET(SOVERSION 1)
# searching ENV{PATH} to find mpicc and
# store the path of mpicc to MPI_INTEL_C
FIND_PATH(MPI_INTEL_C mpicc $ENV{PATH})
# searching ENV{PATH} to find mpicxx and
# store the path of mpicc to MPI_INTEL_CXX
FIND_PATH(MPI_INTEL_CXX mpicxx $ENV{PATH})
IF(MPI_INTEL_C AND MPI_INTEL_CXX)
MESSAGE(STATUS "Intel MPI compiler is used.")
# set C++ complier as mpicxx, and set C complier as mpicc
SET(CMAKE_CXX_COMPILER mpicxx)
SET(CMAKE_C_COMPILER mpicc)
ENDIF(MPI_INTEL_C AND MPI_INTEL_CXX)
find_package(VTK REQUIRED NO_MODULE)
IF(VTK_FOUND)
MESSAGE(STATUS "VTK IS USED")
include(${VTK_USE_FILE})
ELSE()
MESSAGE("VTK IS NOT FOUND")
ENDIF(VTK_FOUND)
list(APPEND CMAKE_MODULE_PATH "/export/home/hh/hh/iRoot-make/cmake")
FIND_PACKAGE(SQLite3 REQUIRED)
MESSAGE(STATUS "${SQLITE3_INCLUDE_DIRS}")
MESSAGE(STATUS "${SQLITE3_LIBRARY}")
# try to link boost--error
INCLUDE_DIRECTORIES(/export/home/hh/hh/boost/include)
LINK_DIRECTORIES(/export/home/hh/hh/boost/lib)
find_package(MPI REQUIRED)
IF(MPI_FOUND)
MESSAGE(STATUS "MPI IS USED")
INCLUDE_DIRECTORIES(${MPI_INCLUDE_PATH})
ELSE()
MESSAGE("MPI IS NOT FOUND")
ENDIF(MPI_FOUND)
aux_source_directory(. DIR_SRCS)
ADD_EXECUTABLE(test ${DIR_SRCS})
#TARGET_LINK_LIBRARIES(iRoot)
# set location of binary generated by the program,
# here PROJECT_BINARY_DIR = DIR OF build
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# set location of lib generated by the program
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
install(TARGETS test DESTINATION bin)
CMake could not find the alternative SQLite3, and could find the old version:
-- /usr/include
-- /usr/lib64/libsqlite3.so
but the new version is located at:
/export/home/hh/hh/sqlite/include
/export/home/hh/hh/sqlite/lib/libsqlite3.so
I am very new to CMAKE, please help me, thank you in advance!

I will explain this using boost as an example. This is how I have it done in my setup.
Let's assume the newer boost version is installed in:
/export/home/hh/hh/Boost/boost-1_60/boost/include/
/export/home/hh/hh/Boost/lib
Now in CMakeLists.txt add these paths to CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH:
LIST (APPEND CMAKE_INCLUDE_PATH "/export/home/hh/hh/Boost/boost-1_60")
LIST (APPEND CMAKE_LIBRARY_PATH "/export/home/hh/hh/Boost/lib)
Then call FindPackage mentioning the minimum required version and optionally the required library components which are built into .so:
FIND_PACKAGE (Boost 1.60 COMPONENTS "program_options" "log" "system" "filesystem" "thread" "python" REQUIRED)
This should work similarly for other libraries too.
Update:
Add to CMakeLists.txt paths to your custom cmake modules, for example the path where FindSQLite3.cmake is located:
LIST (APPEND CMAKE_MODULE_PATH "${MAINFOLDER}/tools/share/cmake")
Then call: FIND_PACKAGE(SQLite3 REQUIRED)
Also remove: /export/home/hh/hh/sqlite/include and /export/home/hh/hh/sqlite/lib from FindSQLite3.cmake but have them added in a similar to boost way.

Instead of hardcoding these settings in the CMakeLists.txt you should change appropriate value in the cache (builddir/CMakeCache.txt). You can do this
manually
with cmake -D VARNAME=value .
with cmake GUI app

Related

How to link Folly in CLion on Mac OS

I installed folly by attempting both ways of installation.
brew install folly
./build/bootstrap-osx-homebrew.sh
I have verified that it's installed correctly at the location /usr/local/Cellar/folly/2017.10.23.00.
Now I'm trying to use it in a HelloWorld project in CLion. Here is my CMakeLists.txt file.
cmake_minimum_required(VERSION 3.7)
project(HelloWorld)
message(STATUS "start running cmake....")
set(folly_DIR /usr/local/Cellar/folly/2017.10.23.00)
find_package(Boost 1.66)
find_package(folly 2017.10.23.00)
set(CMAKE_CXX_STANDARD 14)
if(Boost_FOUND)
message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost_LIBRARIES: ${Boost_LIBRARIES}")
message(STATUS "Boost_VERSION: ${Boost_VERSION}")
include_directories(${Boost_INCLUDE_DIRS})
endif()
if(folly_FOUND)
message(STATUS "folly_INCLUDE_DIRS: ${folly_INCLUDE_DIRS}")
message(STATUS "folly_LIBRARIES: ${folly_LIBRARIES}")
message(STATUS "folly_VERSION: ${folly_VERSION}")
include_directories(${folly_INCLUDE_DIRS})
endif()
set(SOURCE_FILES main.cpp)
add_executable(HelloWorld ${SOURCE_FILES})
if(Boost_FOUND)
target_link_libraries(HelloWorld ${Boost_LIBRARIES})
endif()
if(folly_FOUND)
target_link_libraries(HelloWorld ${folly_LIBRARIES})
endif()
The error I get is:
By not providing "Findfolly.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "folly", but
CMake did not find one.
Could not find a package configuration file provided by "folly" (requested
version 2017.10.23.00) with any of the following names:
follyConfig.cmake
folly-config.cmake
Add the installation prefix of "folly" to CMAKE_PREFIX_PATH or set
"folly_DIR" to a directory containing one of the above files. If "folly"
provides a separate development package or SDK, be sure it has been
installed.
I'm setting folly_DIR right at the top but it's still unable to find. What am I doing wrong?
The phrase
or set "*_DIR" to a directory containing one of the above files.
in the CMake error message should be treated as setting the cached variable to appropriate value.
Normally, the variable is set via command-line option -D when execute cmake. If you want to set the variable in CMakeLists.txt, add CACHE option to the set command:
set(folly_DIR /usr/local/Cellar/folly/2017.10.23.00 CACHE PATH "")
Make sure that given path contain one of the config files noted in the error message.
Create you own FindFolly.cmake file as following (reference here):
# Usage of this module as follows:
#
# find_package(Folly)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# FOLLY_ROOT_DIR Set this variable to the root installation of
# folly if the module has problems finding
# the proper installation path.
#
# Variables defined by this module:
#
# FOLLY_FOUND System has folly libs/headers
# FOLLY_LIBRARIES The folly library/libraries
# FOLLY_INCLUDE_DIR The location of folly headers
find_path(FOLLY_ROOT_DIR
NAMES include/folly/folly-config.h
)
find_library(FOLLY_LIBRARIES
NAMES folly
HINTS ${FOLLY_ROOT_DIR}/lib
)
find_library(FOLLY_BENCHMARK_LIBRARIES
NAMES follybenchmark
HINTS ${FOLLY_ROOT_DIR}/lib
)
find_path(FOLLY_INCLUDE_DIR
NAMES folly/folly-config.h
HINTS ${FOLLY_ROOT_DIR}/include
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Folly DEFAULT_MSG
FOLLY_LIBRARIES
FOLLY_INCLUDE_DIR
)
mark_as_advanced(
FOLLY_ROOT_DIR
FOLLY_LIBRARIES
FOLLY_BENCHMARK_LIBRARIES
FOLLY_INCLUDE_DIR
)
Then, you need to put this file into your CMake module path (more detailes here), that means:
Create a folder named "cmake/Modules/" under your project root
Put the FindFolly.cmake file in the created folder
Add the following line to your cmake file:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")

How to properly link boost with cmake

The root directory of boost ($ENV{BOOST_ROOT}) is
C:\Boost\boost_1_64_0
All compiled libraries (.dll, .lib) are in
C:\Boost\boost_1_64_0\lib64-msvc-14.1
They have both boost_xxx and libboost_xxx.
My cmake file is
set(BOOST_ROOT "$ENV{BOOST_ROOT}")
set(BOOST_LIBRARYDIR "$ENV{BOOST_ROOT}/lib64-msvc-14.1")
message("${BOOST_ROOT}")
message("${BOOST_LIBRARYDIR}")
message("${Boost_INCLUDE_DIR}")
if(MSVC)
add_definitions(-DBOOST_ALL_NO_LIB)
add_definitions(-DBOOST_ALL_DYN_LINK)
endif()
find_package(Boost 1.64.0 COMPONENTS system filesystem program_options REQUIRED)
And the output is
C:\Boost\boost_1_64_0
C:\Boost\boost_1_64_0/lib64-msvc-14.1
C:/Boost/boost_1_64_0
CMake Error at C:/Program
Files/CMake/share/cmake-3.8/Modules/FindBoost.cmake:1842 (message):
Unable to find the requested Boost libraries.
Boost version: 1.64.0
Boost include path: C:/Boost/boost_1_64_0
Could not find the following Boost libraries:
boost_system
boost_filesystem
boost_program_options
No Boost libraries were found. You may need to set BOOST_LIBRARYDIR
to the directory containing Boost libraries or BOOST_ROOT to the
location of Boost. Call Stack (most recent call first):
CMakeLists.txt:78 (find_package)
CMake Error at CMakeLists.txt:84 (message): Boost not found
Could someone help please? I have spent hours on this but couldn't figure out why this doesn't work.
First of all, what CMake version do you use? Recently a regression fix was included into 3.8.1 release -- it was about backslashes in BOOST_ROOT.
Secondly, you don't need to specify anything else ('cept maybe the BOOST_ROOT) if you are using official prebuilt Windows binaries -- FindBoost.cmake would try to find them as well. (Unfortunately I can't recall since what version.)
Never do set(BOOST_ROOT...) in your CMakeLists.txt -- just pass this parameter to cmake run via -D option. A better way is the following:
if(NOT DEFINED BOOST_ROOT AND NOT "${ENV{BOOST_ROOT}" STREQUAL "")
set(BOOST_ROOT "$ENV{BOOST_ROOT}")
endif()
Use imported targets to link w/ needed Boost libraries and to modify compile/linker flags per taget. Please avoid to modify "global" compiler/linker options -- i.e. use corresponding target_xxx commands instead of add_definitions & etc.
I use the following script to load boost with CMake (working with Linux and Windows) :
set(BoostPath "${DefaultBoostPath}" CACHE PATH "Path to Boost")
message(STATUS "Path to Boost: ${BoostPath}")
set(BOOST_ROOT "${BoostPath}")
set(Boost_USE_MULTITHREAD ON)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_NO_SYSTEM_PATHS ON)
set(Boost_ADDITIONAL_VERSIONS "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59" "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64")
find_package(Boost ${RequiredBoostVersion} REQUIRED COMPONENTS ${RequiredBoostComponents})
mark_as_advanced(FORCE Boost_DIR)
set(BoostVersion "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
message(STATUS "Boost version: ${BoostVersion}")
if(CompilerName STREQUAL "gcc")
set(System_LIBRARIES ${System_LIBRARIES} pthread rt)
endif()
You can see I have to add some versions of Boost because my version of CMake doesn't know last versions.
What's your CMake version ? Maybe it's the same problem.
Where are your headers? I don't think it found the include directory (which is necessary for this to be successful).
Search for FindBoost.cmake in your cmake installation directory, there are lots of useful things in there for troubleshooting.
using set(Boost_DEBUG ON) can help you figure out which paths are searched and what the filenames of the libraries are searched. You can specify the include directory (directory where folder boost is stored) with set(Boost_INCLUDEDIRS ${BOOST_ROOT}/inc), though what I just showed is one of the places that FindBoost.cmake searches.
Also, you don't need set(BOOST_ROOT "$ENV{BOOST_ROOT}"). FindBoost.cmake does that for you if you don't set ${BOOST_ROOT}.
Note that if you just downloaded boost, extracted the archive to ${BOOST_ROOT} and compiled with b2, then all of your files are in ${BOOST_ROOT}/stage. This is also a good place for them to reside. If you manually copy files somewhere else, then FindBoost may have some troubles finding them.

cmake ClanLib i can't compile project

cmake_minimum_required(VERSION 3.1)
project(ClanLib)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
SET(ClanLib_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${ClanLib_INCLUDE_DIRS})
FIND_PACKAGE(ClanLib REQUIRED)
set(SOURCE_FILES main.cpp)
add_executable(ClanLib ${SOURCE_FILES} main.cpp)
TARGET_LINK_LIBRARIES(ClanLib ${ClanLib_LIBRARY})
and cmake give error:
Error:By not providing "FindClanLib.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "ClanLib", but CMake did not find one.
Could not find a package configuration file provided by "ClanLib" with any of the following names:
ClanLibConfig.cmake clanlib-config.cmake
Add the installation prefix of "ClanLib" to CMAKE_PREFIX_PATH or set "ClanLib_DIR" to a directory containing one of the above files. If "ClanLib" provides a separate development package or SDK, be sure it has been installed.
There is no FindClanLib.cmake provided by ClanLib project or CMake, so find_package will not work in your case.
For Linux you can use pkg-config facility from CMake.
Here the example for ClanLib usage on Linux.

How to use CMake RPath for boost.Python

I'm writing a Python extension module in C++ using Boost.Python. However, I
would like to use a newer version of the Boost library than the system
installation offers. This newer version of boost is contained in
BOOST_ROOT=$HOME/opt/boost/1.55.0.
Following this guide on how
to use RPath in CMake I came up with the following CMakeLists.txt.
cmake_minimum_required(VERSION 2.8)
project("test")
set(PROJECT_DESC "Test Boost.Python")
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
add_definitions(-std=c++11 -Wall -Wextra -pedantic)
find_package(PythonInterp REQUIRED)
find_package(PythonLibsNew REQUIRED)
find_package(Boost COMPONENTS python REQUIRED)
message(STATUS "Using Boost installation in:")
message(STATUS " INCLUDE: ${Boost_INCLUDE_DIRS}")
message(STATUS " LIB: ${Boost_LIBRARIES}")
include_directories(
${PROJECT_SOURCE_DIR}
${PYTHON_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
macro(add_python_module _name _srccpp)
PYTHON_ADD_MODULE(${_name} ${_srccpp})
target_link_libraries(${_name} ${Boost_LIBRARIES})
endmacro()
add_python_module(ownership ownership.cpp)
Then I run the following commands to build the module
mkdir build; cd build
cmake -DCMAKE_INSTALL_PATH="$BOOST_ROOT/lib" ..
make
The status message after running cmake points to the right boost
installation. (The CMake boost module picks up the environment variable
$BOOST_ROOT) I.e. the CMake variable Boost_LIBARIES points to
$BOOST_ROOT/lib/libboost_python.so.
But, if I check which libraries would actually be used, the system libraries
are listed:
$ ldd ownership.so
# ...
libboost_python.so.1.53.0 => /usr/lib64/libboost_python.so.1.53.0 (0x00007f09abfc1000)
# ...
This is version 1.53, even though the status message above explicitely pointed
to 1.55.
What am I doing wrong? How can I get ldd to pick the library in
$BOOST_ROOT/lib/libboost_python.so.1.55.0?
First of all as I already mentioned in commens you don't need to use CMake RPATH-manipulations
options. Example: http://pastebin.com/UDyYbQ1d, output: standard and custom
Do you know of a way of convincing CMake otherwise even if LIBRARY_PATH is set
This issue is not related to CMake, it's compiler responsibility. Read this discussion.
Solution
You can clear LIBRARY_PATH if you set BOOST_ROOT variable explicitly. And you can check
environment variable in CMakeLists.txt to avoid this problem in future:
string(COMPARE NOTEQUAL "$ENV{LIBRARY_PATH}" "" library_path_warning)
if(library_path_warning)
message(
WARNING
"LIBRARY_PATH environment variable is not empty ($ENV{LIBRARY_PATH}) "
"This may cause dynamic linking errors!"
)
endif()

How do you add Boost libraries in CMakeLists.txt?

I need to add Boost libraries into my CMakeLists.txt. How do you do it or how do you add it?
Put this in your CMakeLists.txt file (change any options from OFF to ON if you want):
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.45.0 COMPONENTS *boost libraries here*)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(progname file1.cxx file2.cxx)
target_link_libraries(progname ${Boost_LIBRARIES})
endif()
Obviously you need to put the libraries you want where I put *boost libraries here*. For example, if you're using the filesystem and regex library you'd write:
find_package(Boost 1.45.0 COMPONENTS filesystem regex)
You can use find_package to search for available boost libraries. It defers searching for Boost to FindBoost.cmake, which is default installed with CMake.
Upon finding Boost, the find_package() call will have filled many variables (check the reference for FindBoost.cmake). Among these are BOOST_INCLUDE_DIRS, Boost_LIBRARIES and Boost_XXX_LIBRARY variabels, with XXX replaced with specific Boost libraries. You can use these to specify include_directories and target_link_libraries.
For example, suppose you would need boost::program_options and boost::regex, you would do something like:
find_package( Boost REQUIRED COMPONENTS program_options regex )
include_directories( ${Boost_INCLUDE_DIRS} )
add_executable( run main.cpp ) # Example application based on main.cpp
# Alternatively you could use ${Boost_LIBRARIES} here.
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )
Some general tips:
When searching, FindBoost checks the environment variable $ENV{BOOST_ROOT}. You can set this variable before calling find_package if necessary.
When you have multiple build-versions of boost (multi-threaded, static, shared, etc.) you can specify you desired configuration before calling find_package. Do this by setting some of the following variables to On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED, Boost_USE_STATIC_RUNTIME
When searching for Boost on Windows, take care with the auto-linking. Read the "NOTE for Visual Studio Users" in the reference.
My advice is to disable auto-linking and use cmake's dependency handling: add_definitions( -DBOOST_ALL_NO_LIB )
In some cases, you may need to explicitly specify that a dynamic Boost is used: add_definitions( -DBOOST_ALL_DYN_LINK )
Adapting #LainIwakura's answer for modern CMake syntax with imported targets, this would be:
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.45.0 COMPONENTS filesystem regex)
if(Boost_FOUND)
add_executable(progname file1.cxx file2.cxx)
target_link_libraries(progname Boost::filesystem Boost::regex)
endif()
Note that it is not necessary anymore to specify the include directories manually, since it is already taken care of through the imported targets Boost::filesystem and Boost::regex.
regex and filesystem can be replaced by any boost libraries you need.
May this could helpful for some people. I had a naughty error:
undefined reference to symbol '_ZN5boost6system15system_categoryEv'
//usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: error adding symbols: DSO missing from command line
There were some issue of cmakeList.txt and somehow I was missing to explicitly include the "system" and "filesystem" libraries. So, I wrote these lines in CMakeLists.txt
These lines are written at the beginning before creating the executable of the project, as at this stage we don't need to link boost library to our project executable.
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_NO_SYSTEM_PATHS TRUE)
if (Boost_NO_SYSTEM_PATHS)
set(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../3p/boost")
set(BOOST_INCLUDE_DIRS "${BOOST_ROOT}/include")
set(BOOST_LIBRARY_DIRS "${BOOST_ROOT}/lib")
endif (Boost_NO_SYSTEM_PATHS)
find_package(Boost COMPONENTS regex date_time system filesystem thread graph program_options)
find_package(Boost REQUIRED regex date_time system filesystem thread graph program_options)
find_package(Boost COMPONENTS program_options REQUIRED)
Now at the end of the file, I wrote these lines by considering "KeyPointEvaluation" as my project executable.
if(Boost_FOUND)
include_directories(${BOOST_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
add_definitions(${Boost_DEFINITIONS})
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(KeyPointEvaluation ${Boost_LIBRARIES})
target_link_libraries( KeyPointEvaluation ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY})
endif()
Try as saying Boost documentation:
set(Boost_USE_STATIC_LIBS ON) # only find static libs
set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and
set(Boost_USE_RELEASE_LIBS ON) # only find release libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(foo foo.cc)
target_link_libraries(foo ${Boost_LIBRARIES})
endif()
Don't forget to replace foo to your project name and components to yours!
I agree with the answers 1 and 2. However, I prefer to specify each library separately. This makes the depencencies clearer in big projects.
Yet, there is the danger of mistyping the (case-sensitive) variable names.
In that case there is no direct cmake error but some undefined references linker issues later on, which may take some time to resolve. Therefore I use the following cmake function:
function(VerifyVarDefined)
foreach(lib ${ARGV})
if(DEFINED ${lib})
else(DEFINED ${lib})
message(SEND_ERROR "Variable ${lib} is not defined")
endif(DEFINED ${lib})
endforeach()
endfunction(VerifyVarDefined)
For the example mentioned above, this looks like:
VerifyVarDefined(Boost_PROGRAM_OPTIONS_LIBRARY Boost_REGEX_LIBRARY)
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )
If I had written "BOOST_PROGRAM_OPTIONS_LIBRARY" there would have been an error triggered by cmake and not much later triggered by the linker.
Additional information to answers above for those still having problems.
Last version of Cmake's FindBoost.cmake may not content last
version fo Boost. Add it if needed.
Use -DBoost_DEBUG=0 configuration flag to see info on problems.
See for library naming format. Use Boost_COMPILER and Boost_ARCHITECTURE suffix vars if needed.
If you are using custome boost path, set CMAKE_PREFIX_PATH firstly. So, cmake can find your custome boost.
list(FIND CMAKE_PREFIX_PATH ${CUSTOME_BOOST_DEP_PREFIX} _INDEX)
if (_INDEX EQUAL -1)
list(APPEND CMAKE_PREFIX_PATH ${CUSTOME_BOOST_DEP_PREFIX})
# set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
endif ()
By the way, if you run above code in sub cmake file, should set CMAKE_PREFIX_PATH back to parent scope.
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
If you want find all components of boost, using below code.
find_package(Boost 1.76 COMPONENTS ALL)

Resources