I'm trying to add Boost to my C++ project using CMake but it refuses to find Boost libraries eventhough I am 100% sure they are there.
Error:Unable to find the requested Boost libraries.
Boost version: 1.61.0
Boost include path: C:/Program Files (x86)/boost_1_61_0
Could not find the following Boost libraries:
boost_system
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.
This is what my search looks like in CMake.
FIND_PACKAGE(Boost REQUIRED COMPONENTS system)
IF (Boost_FOUND)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ADD_DEFINITIONS( "-DHAS_BOOST" )
ENDIF()
I have tried to set all of the paths manually but nothing changes and it keeps telling me no libraries could be found.
EDIT:
To clarify, if I remove "COMPONENTS system" it will not error but crash on the build, giving
"undefined reference to `boost::system::generic_category()'"
, etc.
EDIT 2:
I want to clarify a bit more, I am able to use header only parts of boost, but I cannot use anything else, as it will give me the undefined reference error. I searched Stackoverflow for that error, and the solution was adding the "COMPONENTS system" part to find_package, and that's where it goes wrong.
Related
I want to use the Boost library on Windows but doing so has been troublesome. I downloaded the Windows package from here and extracted it to C:\Boost:
I added the following to my CMake file:
find_package(Boost 1.68 REQUIRED COMPONENTS filesystem)
# ...
target_link_libraries(MyExecutable ${Boost_LIBRARIES})
I'm getting the following CMake error:
C:\Users\User\AppData\Local\JetBrains\Toolbox\apps\CLion\ch-0\183.4284.104\bin\cmake\win\bin\cmake.exe -DCMAKE_BUILD_TYPE=Debug "-DCMAKE_MAKE_PROGRAM=C:/Program Files/mingw-w64/x86_64-8.1.0-win32-seh-rt_v6-rev0/mingw64/bin/mingw32-make.exe" "-DCMAKE_C_COMPILER=C:/Program Files/mingw-w64/x86_64-8.1.0-win32-seh-rt_v6-rev0/mingw64/bin/x86_64-w64-mingw32-gcc.exe" "-DCMAKE_CXX_COMPILER=C:/Program Files/mingw-w64/x86_64-8.1.0-win32-seh-rt_v6-rev0/mingw64/bin/x86_64-w64-mingw32-g++.exe" -G "CodeBlocks - MinGW Makefiles" D:\Cpp\MyProject
CMake Error at C:/Users/User/AppData/Local/JetBrains/Toolbox/apps/CLion/ch-0/183.4284.104/bin/cmake/win/share/cmake-3.12/Modules/FindBoost.cmake:2048 (message):
Unable to find the requested Boost libraries.
Boost version: 1.68.0
Boost include path: C:/Boost
Could not find the following Boost libraries:
boost_filesystem
Some (but not all) of the required Boost libraries were found. You may
need to install these additional Boost libraries. Alternatively, 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:6 (find_package)
-- Configuring incomplete, errors occurred!
See also "D:/Cpp/MyProject/cmake-build-debug/CMakeFiles/CMakeOutput.log".
[Failed to reload]
It apparently cannot find filesystem but it's there in C:\Boost\boost\filesystem (here is the documentation on FindBoost).
How do I setup my CMake file to use Boost properly? I tried setting the Boost environment variables as well but it still didn't work:
SET (BOOST_ROOT "c:/Boost")
SET (BOOST_INCLUDEDIR "c:/Boost/boost")
SET (BOOST_LIBRARYDIR "c:/Boost/libs")
FIND_PACKAGE(Boost 1.68.0 REQUIRED COMPONENTS filesystem)
Also, Boost says that most things don't have to be compiled so I didn't do that.
It cannot find the library boost::filesystem. Because boost::filesystem is one of the few libraries that need to be compiled (all the ones that you have to specify in the find package command have to be compiled).
You need to build boost first:
./booststrap.sh
And then:
bjam
It picks up whatever compiler is available, so you may have to set the proper toolset manually.
Not completely related, but I think your link line is incorrect, instead of:
target_link_libraries(MyExecutable Boost::filesystem)
it should say:
target_link_libraries(MyExecutable ${Boost_LIBRARIES})
Boost_LIBRARIES is automatically defined once Boost is found, so it's for free.
The CMake FindBoost macro only fills Boost_Libraries if the find_package contains a COMPONENTS section and the macro actually finds those libraries on disk.
So here I'd be saying I need Boost to be found AND it must have filesystem
find_package(Boost 1.66.0 REQUIRED COMPONENTS filesystem)
The macro then tries to construct a bunch of potential filenames for the filesystem (taking into account if I want shared version, debug, multi-threaded etc.) and searches for those names under Boost_ROOT. If it doesn't find the file it may error and won't fill out Boost_Libraries.
If in doubt, add a line like this to your CMake prior to find_packages() to see what libs the macro is looking for and compare to what you actually have:
set (Boost_DEBUG ON)
For me I discovered that I had a Boost that placed an -x32 and -x64 architecture version of the libs, e.g. "libboost_system-mgw92-mt-x64-1_66.a". The macro wasn't filling in the architecture prefix into the filename it was looking for and failed.
I had to add a line like this to give the macro a clue which version I wanted:
set (Boost_ARCHITECTURE "-x64")
After that ${Boost_Libraries} expanded correctly and I was able to correctly use it to link.
For building my C++ project statically with Boost, I can use the following cmake command:
set(Boost_USE_STATIC_LIBS ON)
Is there a same function for POCO libraries?
Boost_USE_STATIC_LIBS is an option of the boost find module. This is a file which contains informations for cmake on where to find all of the boost components (headers and libs, but not only). When you call find_package cmake search for this file, and based on the options you set perform a couple more operation, as for the example storing the names of the dynamic libraries or the static ones for linking.
I suppose you are searching POCO components in the same way you search for boost, so maybe POCO has the same informations. In this case I suggest you to check the <somenamerelatedtoPOCO>.cmake file.
I have built Boost 1.68 (using instructions from https://gist.github.com/sim642/29caef3cc8afaa273ce6, and adding link=static,shared to the b2 command line to also build shared libraries.)
The libraries appear to build correctly, and I have set the BOOST_INCLUDEDIR and BOOST_LIBRARYDIR environment variables correctly.
However, when I add the following to a CMakeLists.txt:
find_package(Boost REQUIRED COMPONENTS system context coroutine thread random REQUIRED)
and generate with MinGW Makefiles, I get the following error:
CMake Error at C:/Users/pbelanger/AppData/Local/JetBrains/Toolbox/apps/CLion/ch-0/182.4129.15/bin/cmake/win/share/cmake-3.12/Modules/FindBoost.cmake:2044 (message):
Unable to find the requested Boost libraries.
Boost version: 1.68.0
Boost include path: C:/boost/install/include/boost-1_68
Could not find the following static Boost libraries:
boost_system
boost_context
boost_coroutine
boost_thread
boost_random
Some (but not all) of the required Boost libraries were found. You may
need to install these additional Boost libraries. Alternatively, set
BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT
to the location of Boost.
I have placed the output of adding set(Boost_DEBUG ON) before the find_package line here: https://pastebin.com/yRd5DPt4
According to the debug output, the find script is searching in the correct directory (c:\boost\install\lib), but is not finding the boost libraries since they have a different naming scheme. For example, the system library is named libboost_system-mgw81-mt-x64-1_68.dll, but the find script is passing he library name boost_system-mgw81-mt-1_68 to CMake's find_library. Notice that the addressing model (-x64)is not listed in the latter name.
My question is whether this is an issue with Boost, or the findCMake script? Can this be fixed by setting a specific cmake variable before the findCMake script?
After hours of research, the answer given by Paul Belanger saved my day.
Digging a bit more in the codebase, they added a new option to manage exactly this case, so with the latest version of CMAKE you can add the following option:
set (Boost_ARCHITECTURE "-x64")
Source: https://github.com/Kitware/CMake/commit/1e08b625c291e0bb57d253b6656e812dc8848bd8#diff-555801259d7df67368f7deab1f9deacd
Looking at the source of FindBoost.cmake, line 1478,
the script looks at the value of CMAKE_CXX_COMPILER_ARCHITECTURE_ID in order
to build the correct architecture tag. However, on my compiler (MinGW-W64 8.1
64-bit), this string is empty. Therefore, the architecture tag is omitted.
I have to set the value of this variable manually by putting the following
before my find_package line:
if(WIN32 AND "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x")
message(WARNING "WIN32 compiler does not specify CMAKE_CXX_COMPILER_ARCHITECTURE_ID -- filling in manually")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "x64")
else()
set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "x86")
endif()
message(STATUS "Compiler architecture: ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}")
endif()
# now we should be able to find boost correctly.
find_package(Boost REQUIRED COMPONENTS system context coroutine thread random REQUIRED)
This makes the find_package work correctly.
Lately, I have been using cmake as a generator for my projects. I have successfully generated many vtk and other application projects. However, I now face a problem when trying to link both dynamic and static precompiled libraries. In particular, I have been given some dynamic precompiled third party dlls along with their respective .lib files. Furthermore, I am trying to link some static precompiled libraries (only .lib files) to my project so as to check the software licences.
Let say that my project is called test_example and I have some precompiled dynamic libraries in libs directory. The structure of my project directory is:
Test_example
-/include
-/libs
-/build
-CMakeLists.txt
The CMakeLists.txt for linking the dynamic libaries has the following content:
cmake_minimum_required(VERSION 2.8.9)
project (test_example)
set(CMAKE_BUILD_TYPE Release)
#For the shared libraries:
set (PROJECT_LINK_LIBS dynamic_1.dll dynamic_2.dll )
set (PROJECT_LINK_DIR ${test_example_SOURCE_DIR}/libs/)
set (PROJECT_INCLUDE_DIR ${test_example_SOURCE_DIR}/include/)
link_directories(${PROJECT_LINK_DIR})
include_directories(${PROJECT_INCLUDE_DIR})
add_executable(test_example test_example.cpp)
target_link_libraries(test_example ${PROJECT_LINK_LIBS})
When I generate the project with this cmake lists, I can successfully use methods from the precompiled dlls. However, I have not found a way to link against my static libraries, as well. Let say I have one static library which is called test_licence.lib. Should I drop it in the libs folder as well and simply refer to it like I do with the dynamic? When I do so and when opening my project solution in Visual Studio, I can see that both dynamic and static libraries have been added to Linker-->Input-->Additional DEpendencies. However, when I am trying to build the project, I have unresolved external dependencies which are methods from the static lib.
Does any of you have any idea what would be the most efficient way to accomplish that? Many thanks in advance!
There is a couple of issues here.
Unlike to what you may be used to from VS, CMake prefers absolute paths for linking, instead of setting a link directory and giving the relative path.
Also, you do not link against .dll files. Dlls are loaded at runtime, not at link time. Many dlls are shipped with import libraries (with a .lib ending), that handle the runtime loading automatically for you. These are the ones you should link against.
Also try not to hardcode libraries in CMake code. The problem here is that if something goes wrong, you end up with a cryptic linker error. You should use find_library instead, which will usually make CMake complain early if something is off.
A cleaner version of your CMake script would be something like
cmake_minimum_required(VERSION 2.8.9)
project (test_example)
# note setting the build type does nothing on a visual studio build
# and should probably be left to the user for other generators
set(CMAKE_BUILD_TYPE Release)
#For the shared libraries:
# this call will succeed if it finds a dynamic_1.lib file
find_library(DYNAMIC_LIB1 dynamic_1 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT DYNAMIC_LIB1)
message(FATAL_ERROR "Library dynamic_1 was not found!")
endif()
find_library(DYNAMIC_LIB2 dynamic_2 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT DYNAMIC_LIB2)
message(FATAL_ERROR "Library dynamic_2 was not found!")
endif()
# for the static libraries:
# basically the same; again this looks for a static_1.lib file
find_library(STATIC_LIB1 static1 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT STATIC_LIB1)
message(FATAL_ERROR "Library static_1 was not found!")
endif()
set (PROJECT_INCLUDE_DIR ${test_example_SOURCE_DIR}/include/)
include_directories(${PROJECT_INCLUDE_DIR})
add_executable(test_example test_example.cpp)
target_link_libraries(test_example ${DYNAMIC_LIB1} ${DYNAMIC_LIB2} ${STATIC_LIB1})
Double check in Visual Studio that all libraries were added as linker inputs, as expected. If you still get linker errors, it means that something is wrong with your third-party .lib file. Open a new question with the exact linker error that you get.
Here is how we are doing it:
Firstly, use add_library with final arguments STATIC IMPORTED. Then subsequently use set_property to set the IMPORTED_LOCATION property, which is a path to the built library. For example, we pull in gtest like so:
add_library(gtest UNKNOWN IMPORTED)
set_property(TARGET gtest PROPERTY IMPORTED_LOCATION ${binary_dir}/googlemock/gtest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a)
Then, gtest is a known library in your build system and you can link with it normally later on by just doing
target_link_libraries(target-name gtest)
See also: Cmake imported libraries documenation
I am trying to build my project using CMake. Iam also using boost.
The find package statement in my CMakeLists.txt file is:
find_package(Boost 1.42 REQUIRED COMPONENTS
python
system
filesystem
serialization
thread
program_options
regex
test_exec_monitor
)
The build fails and the error message i get is:
The following Boost libraries could not be found:
boost_system
boost_filesystem
boost_serialization
boost_thread
boost_program_options
When i check my lib directories i find that the libraries are by name:
libboost< library_name >-vc100-mt.lib and not by boost_< Library_name >
Infact when i rename a single library in my lib files to fit according the boost_< LibraryName > Prefix, it doesn't complain for that library.
I see 2 solutions for the same:
1.Make changes in the CMakeLists.txt file so that it searches for libraries with correct Prefix( and suffix ).
2.Others
What could be the best one.
From the FindBoost.cmake
These last three variables are available also as environment variables:
Also, note they are completely UPPERCASE, except Boost_DIR.
Boost_DIR or The preferred installation prefix for searching for
BOOST_ROOT or BOOSTROOT Boost. Set this if the module has problems finding the proper Boost installation.
Use these variables to point on folder where your boost libs installed. For example
cmake .. -DBOOST_ROOT=C:/Boost