Undefined reference errors in simple boost serialization - c++

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.

Related

Linking GSL using CMake, undefined symbols

I'm attempting to link GSL to my C++ code using cmake, and all goes well until I attempt to build. CMakeLists.txt:
cmake_minimum_required(VERSION 3.9)
include_directories(${project_SOURCE_DIR}/src)
link_directories(${project_BINARY_DIR}/src)
FIND_PACKAGE(Boost COMPONENTS system filesystem unit_test_framework REQUIRED )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
find_package(GSL REQUIRED)
set(CMAKE_CXX_STANDARD 14)
set (lib_SOURCES
../src/file.h
../src/file.cpp
# etc
)
target_include_directories(project PRIVATE ${PROJECT_SOURCE_DIR} ${GSL_INCLUDE_DIR})
target_link_libraries(sigma OpenMP::OpenMP_CXX GSL::gsl GSL:gslcblas)
When I add #include <gsl/gsl_integration.h> and call something from the library in the C++, e.g. a gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);, at the make I get an Undefined symbols for architecture x86_64:..., so the library isn't linking, but I don't know why. CMake clearly recognises GSL, but isn't liking to it.
I'm on Big Sur 11.3.1, GSL 2.6 installed via homebrew.
Fixed this by removing my CMakeCache.txt files and running cmake again.
I realized this as I was preparing minimal working example in response to Tsyvarev's comment. I hope this can help somebody.

CMake not finding GL/glew.h

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.

Installing boost on macos

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>

translate g++ code to clion environment

I am new in clion. on gcc i always use:
g++ bin/obj/main.o -o bin/main -lboost_filesystem -lboost_system -lcrypto
How to do it in clion?
It seems my CMakeList does not work:
cmake_minimum_required(VERSION 3.1)
project(motion_simulation)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(motion_simulation ${SOURCE_FILES})
link_libraries(lboost_filesystem)
link_libraries(lboost_system)
link_libraries(lcrypto)
Try including the keyword "CMake" into your search next time. This question is actually not CLion specific because CLion actually uses CMake as buildsystem.
CMake is very well documented, and you should be able to find a lot of answers regarding your problem.
You could first try to get rid of that "l":
link_libraries(boost_filesystem)
If that doesn't work you should take a look how the find_package() command works. http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
And here is a detailed explanation how to find Boost libs and include directory.
http://www.cmake.org/cmake/help/v3.0/module/FindBoost.html
As you are using CMake 3.1 you can use some more advanced features of CMake.
With CMAKE_CXX_STANDARD you can select which C++ version you want to use and CMake will select the corresponding compiler flags (see docs).
link_libraries is one possibility, but it has to be called before add_executable or add_library. The alternative is target_link_libraries which links only to a single target, but can also manage transitive dependencies (docs).
CMake comes with find_package modules for OpenSSL and Boost to find dependencies and with the option REQUIRED, you can ensure that they are found on the system. Boost also supports COMPONENTS to select which libraries you need.
In case you ever work on a system, where OpenSSL and Boost are not installed in /usr/, you can already use target_include_directories to specify where the headers for your executable is found. Like target_link_libraries, target_include_directories can work with transitive dependencies, in this case PRIVATE.
cmake_minimum_required(VERSION 3.1)
project(motion_simulation)
set(CMAKE_CXX_STANDARD 11)
find_package(Boost REQUIRED COMPONENTS filesystem system)
find_package(OpenSSL REQUIRED)
set(SOURCE_FILES main.cpp)
add_executable(motion_simulation ${SOURCE_FILES})
target_include_directories(motion_simulation PRIVATE ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR})
target_link_libraries( motion_simulation PRIVATE ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES})

How to include external library (boost) into CLion C++ project with CMake?

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")