I am trying to create a simple example using the boost library. I can successfully use CMake for the initial setup and it finds boost.
using the following code in CMakeLists.txt:
cmake_minimum_required(VERSION 3.18)
project(edge_detector)
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(edge_detector main.cpp)
target_include_directories(edge_detector PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(edge_detector ${Boost_LIBRARIES})
However when I try to build the project using make or CMake --build . boost is not found and I am met with this error:
I am not sure what I am missing, I would be grateful for any help
Your include directive must include a file not a directory.
Replace
#include <boost/algorithm/string>
with
#include <boost/algorithm/string.hpp>
Related
I have the following main.cpp, very simple script, trying to re-produce the problem and isolate to it's most basic.
#include<iostream>
#include<fmt/core.h>
// #include "json/json.hpp"
// #include <json/json.hpp>
// #include <nlohmann/json.hpp>
// #include "json.hpp"
// #include "nlohmann/json.hpp"
int main(){
fmt::print("Hello, world!\n");
return 0;
}
The commented out include statements are all of the paths I have tried to get this into my program.
My CMakeLists.txt file looks like this
cmake_minimum_required(VERSION 3.24)
project(main)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-std=c++17")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
# include(FetchContent)
# FetchContent_Declare(
# json
# GIT_REPOSITORY https://github.com/nlohmann/json
# )
# FetchContent_MakeAvailable(json)
include(FetchContent)
FetchContent_Declare(fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt
GIT_TAG 9.0.0
)
FetchContent_MakeAvailable(fmt)
add_executable(main main.cpp)
# target_link_libraries(main json)
target_link_libraries(main fmt)
I've commented out the json part since it's not working obviously, I can also json-src and json-build in my _deps folder so I know for a fact that it is being downloaded into my local machine.
After running cmake CMakeLists.txt and make and then running the executable I get the error in the title 'nlohmann/json.hpp' file not found
Any help would be appreciated.
Tried to reproduce the example with another popular C++ package which worked fine. Tried changing the include statements to see if maybe I had something wrong since I don't fully understand all the nuance with CMake and am quite new to it.
You can either specifically use the interface target already included in the nlohmann library, which will automatically populate the correct include path for you, with:
target_link_libraries(main nlohmann_json::nlohmann_json)
Or you would need to specifically include the include path yourself:
include_directories(${json_SOURCE_DIR}/include)
With either way, you will be able to use #include <nlohmann/json.hpp> in your source.
I'm using CLion under pop_OS! 20.04 and am currently trying to get CMake to work with GLEW because I want to follow these tutorials to get started with OpenGL. I'm relatively new to C/C++ and completely new to CMake.
I installed the libgl1-mesa-dev,libglew-dev,libglfw3,libglfw3-dev packages with apt-get install and the glew.h is located alongside the other GL header files in /usr/include/GL.
When trying to compile a simple program:
#include <GL/glew.h>
int main() {
return 0;
}
cmake can't find the headerfile:
test/main.cpp:1:10: fatal error: GL/glew.h: No such file or directory
1 | #include <GL/glew.h>
| ^~~~~~~~~~~
Do I have to manually add these header files in CMakeLists.txt for cmake to find them? I tried like a dozen different suggestions but I didn't get it to work. For example, I tried
cmake_minimum_required(VERSION 3.17)
project(test)
set(CMAKE_CXX_STANDARD 14)
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
link_libraries(${GLEW_LIBRARIES})
target_link_libraries(test GLEW::GLEW)
but this results in
CMake Error at /app/extra/clion/bin/cmake/linux/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:164 (message):
Could NOT find GLEW (missing: GLEW_INCLUDE_DIRS GLEW_LIBRARIES)
Is this somehow a problem with CLion and I need to include libraries into my project in a different manner? Or am I using cmake in a wrong way?
Your last try was nearly right.
Forget about include_directories and link_libraries commands. All it needs when doing modern CMake is an add_executable(test main.cpp) followed by a target_link_libraries(test PRIVATE GLEW::glew) command. The target GLEW::glew (case matters here) bundles all compile definitions, include directories, libraries, and further settings that are needed to compile and link your example.
Your CMakeLists.txt would now look like this:
cmake_minimum_required(VERSION 3.17)
project(test)
set(CMAKE_CXX_STANDARD 14)
find_package(GLEW REQUIRED)
add_executable(myTest main.cpp)
target_link_libraries(myTest PRIVATE GLEW::glew)
Edit: Just noticed, that GLEW::GLEW can also be used.
The answer by #vre is OK. I only add how to find it yourself.
First, run
cmake --help-module-list
and look for GLEW. Under Linux, you can simplify this step to
cmake --help-module-list | grep -i Glew
where -i stands for "case insesitive match", as we usually don't remember if it's GLEW or perhaps Glew. Once you know the module name, you can ask for the specific help related to just this module:
cmake --help-module FindGLEW
The answer is there. Read and enjoy!
PS. There's no need to memorize this answer. All can be reduced to cmake --help.
I'm pretty sure I'm doing something stupid here but when I try to go install boost from Cygwin's installer, I only see the -debug and -build options.
Cygwin Screenshot
I'm using the http://mirrors.sonic.net mirror. I switch to this from the default mirror because I thought that might have been the problem.
I know the package isn't getting installed because when I try to load my CMAKE file in clion, it throws and an error saying "Could NOT find Boost (missing: Boost_INCLUDE_DIR graph)".
Heres my CMakeLists.txt code:
cmake_minimum_required(VERSION 3.15)
project(HW_9)
set(CMAKE_CXX_STANDARD 14)
add_executable(HW_9 main.cpp knuth.txt graph_1.h)
# see https://cmake.org/cmake/help/latest/module/FindBoost.html
find_package(Boost REQUIRED COMPONENTS graph)
include_directories(${Boost_INCLUDE_DIR})
# Note: a target should be already defined using 'add_executable' or 'add_library'
target_link_libraries(HW_9 ${Boost_LIBRARIES})
I have a minimal example of Boost serialization where I try to save an integer in a binary archive file
Here is main.cpp:
#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
int main() {
int t = 0;
std::ofstream file("Test.bin");
boost::archive::binary_oarchive archive(file);
archive << t;
file.close();
return 0;
}
and here is the CMake file:
cmake_minimum_required(VERSION 3.15)
project(Test)
set(CMAKE_CXX_STANDARD 17)
find_package(Boost REQUIRED serialization)
add_executable(Test main.cpp)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(Test ${Boost_LIBRARIES})
endif()
When I try to run this program in CLion, I get a large list of undefined reference errors as shown here:
https://pastebin.com/8uX9MZFf
I have setup Boost using vcpkg package manager. I'm compiling using Mingw-w64. The CMake file loads without errors (only a warning that says "New Boost version may have incorrect or missing dependencies and imported targets," though I've heard this warning isn't of concern, as it just means the current version of CMake isn't aware of the newest version of Boost).
I've tried to look for solutions to this everywhere, but I can't seem to find anything that works here. Any help would be appreciated.
I'm using cmake 3.15.3, boost 1.73.0 and mingw-w64 6.0.
EDIT
I uninstalled and reinstalled Boost without using the package manager, and tried getting the serialization library again. In this context, CMake runs into errors saying it can't find Boost with serialization (Though it can find Boost alone). I set Boost_DEBUG to ON and looked at the output, and noticed the following things:
_boost_COMPILER = "-mgw81" (guessed)
CMake seems to guess that the compiler I used to compile boost was mgw81. I'm guessing it got the 8.1 from my gcc version, which is correct.
Searching for SERIALIZATION_LIBRARY_RELEASE: boost_serialization-mgw81-mt-x64-1_73;boost_serialization-mgw81-mt-x64;...
As a result of that compiler selection, it searches for a file with "-mgw81" in the name. The problem is that the library files generated when I built boost are named like so:
libboost_serialization-mgw8-mt-x64-1_73.a
This says "-mgw8" instead of "-mgw81". I don't know how to correct CMake or build boost in such a way that this conflict doesn't happen. I've tried rebuilding boost with toolset=gcc-8.1 instead of toolset=gcc, but I still get "-mgw8" in the library file names.
EDIT 2
I found the solution to the above issue. I've posted it below.
After realizing that the issue was what I mentioned in EDIT, I looked further into how that issue could be resolved, and I found out you can manually set the compiler that is used to search through the variable Boost_COMPILER.
I changed my CMake file to the following:
cmake_minimum_required(VERSION 3.15)
project(Test)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "C:/boost_1_73_0")
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "C:/boost_1_73_0/libs")
set(Boost_DEBUG ON)
set(Boost_COMPILER -mgw8)
set(Boost_ARCHITECTURE -x64)
set(BOOST_ROOT C:/boost)
set(BOOST_INCLUDEDIR C:/boost/include/boost-1_73/boost)
set(BOOST_LIBRARYDIR C:/boost/lib)
set(BOOST_NO_SYSTEM_PATHS ON)
find_package(Boost REQUIRED serialization)
add_executable(Test main.cpp)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(Test ${Boost_LIBRARIES})
endif()
I believe the critical changes here were setting Boost_COMPILER and Boost_ARCHITECTURE. I realized Boost_ARCHITECTURE needed to be set from this question: Linking boost in CLion project.
With this CMake file, my main.cpp file from above ran properly.
I have the following setup for C++ development:
OS X Yosemite
CLion 140.2310.6 (a cross-plattform C/C++-IDE by JetBrains using CMake as build system)
installed boost via brew install boost into /usr/local/Cellar/boost/
Now, my goal is to setup a simple project and include the boost library. I defined just one test.cpp file that looks like this:
#include <iostream>
#include <boost>
using namespace std;
int test() {
cout << "Hello, World!" << endl;
return 0;
}
My CMakeLists.txt file looks like this:
cmake_minimum_required(VERSION 2.8.4)
project(MyProject)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories("/usr/local/Cellar/boost/1.57.0/include/boost")
set(SOURCE_FILES main.cpp ./test.cpp)
add_executable(MyProject ${SOURCE_FILES})
When I build the project, I get the following error:
/Users/nburk/Documents/uni/master/master_thesis/MyProject/test.cpp:2:10:
fatal error: 'boost' file not found
make[3]: *** [CMakeFiles/MyProject.dir/test.cpp.o] Error 1
make[2]: *** [CMakeFiles/MyProject.dir/all] Error 2
make[1]: *** [CMakeFiles/MyProject.dir/rule] Error 2
make: *** [MyProject] Error 2
I played around with adjusting paths here and there and also using add_library and target_link_libraries, none of which made the project build successfully.
Can someone point into the right direction how to make sure I can include boosts functionality into my CLion C++ project?
Update:
Thanks to #Waxo's answer I used the following code in my CMakeLists.txt file which:
set(Boost_INCLUDE_DIR /usr/local/Cellar/boost/1.57.0)
set(Boost_LIBRARY_DIR /usr/local/Cellar/boost/1.57.0/lib)
find_package(Boost COMPONENTS system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
I now got past the file not found-error, but instead I get the following:
CMake Error at /Applications/CLion
EAP.app/Contents/bin/cmake/share/cmake-3.1/Modules/FindBoost.cmake:685
(file):
file STRINGS file "/usr/local/Cellar/boost/1.57.0/boost/version.hpp" cannot be read.
Call Stack (most recent call first): CMakeLists.txt:11
(find_package)
Any ideas what I am still missing? The referred line (685) in FindBoost.cmake is:
file(STRINGS "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS REGEX "#define BOOST_(LIB_)?VERSION ")
After spending the whole afternoon on the issue, I solved it myself. It was a rather stupid mistake and all the hints in #Waxo's answer were really helpful.
The reason why it wasn't working for me that I wrote #include <boost> within my test.cpp-file, which apparently is just wrong. Instead, you need to refer directly to the header files that you actually want to include, so you should rather write e.g. #include <boost/thread.hpp>.
After all, a short sequence of statements should be enough to successfully (and platform-independently) include boost into a CMake project:
find_package(Boost 1.57.0 COMPONENTS system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(BoostTest main.cpp)
target_link_libraries(BoostTest ${Boost_LIBRARIES})
These lines are doing the magic here. For reference, here is a complete CMakeLists.txt file that I used for debugging in a separate command line project:
cmake_minimum_required(VERSION 2.8.4)
project(BoostTest)
message(STATUS "start running cmake...")
find_package(Boost 1.57.0 COMPONENTS system filesystem REQUIRED)
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()
add_executable(BoostTest main.cpp)
if(Boost_FOUND)
target_link_libraries(BoostTest ${Boost_LIBRARIES})
endif()
Try using CMake find_package(Boost)
src : http://www.cmake.org/cmake/help/v3.0/module/FindBoost.html
It works better and CMake is made for cross compilation and giving an absolute path is not good in a CMake project.
Edit:
Look at this one too : How to link C++ program with Boost using CMake
Because you don't link actually the boost library to your executable.
CMake with boost usually looks like that :
set(Boost_USE_STATIC_LIBS ON) # only find static libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.57.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()
I couldn't find boost library using find_package() of clion. So my solution is download to the latest version boost from the following site:
https://sourceforge.net/projects/boost/files/boost/
After that, extract it and navigate to that folder in CMakeList.txt to include boost library.
include_directories("/path_to_external_library")
In my case, I use linux and so I put it under /usr/share/.
include_directories("/usr/share/boost_1_66_0")