linking to a custom library using cmake - c++

I have two cmake files that build a directory and then try to compile an example that uses that library. The content of the first CMakeLists.txt file stored at the project root ${CMAKE_SOURCE_DIR} is:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project("lsd_point_pair")
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
#Note: Eclipse automatically picks up include paths with this on!
SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(CMAKE_CXX_FLAGS "-g")
find_package(PCL 1.7 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
set(BOOST_LIBS program_options)
find_package(Boost COMPONENTS ${BOOST_LIBS} REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
MESSAGE(" Boost_LIBRARIES: ${Boost_LIBRARIES}")
include_directories(${PROJECT_BINARY_DIR})
link_directories(${PROJECT_BINARY_DIR}/lib})
add_library(lsd_obj_rec_ransac lsd_obj_rec_ransac.cpp lsd_obj_rec_ransac.h lsd_point_pair_model_library.cpp lsd_point_pair_model_library.h ndim_voxel_structure.h orr_octree_cloud.h orr_octree_cloud.cpp)
target_link_libraries(lsd_obj_rec_ransac ${PCL_LIBRARIES} ${Boost_LIBRARIES})
######## subdirectories #########
add_subdirectory(examples)
In ${CMAKE_SOURCE_DIR}/examples I have the following CMakeLists.txt file:
add_executable(example_pcl_lsd_point_pair example_pcl_lsd_point_pair.cpp)
target_link_libraries(example_pcl_lsd_point_pair lsd_obj_rec_ransac ${Boost_LIBRARIES} ${PCL_LIBRARIES})
After successfully running cmake I run make and I get the linking errors:
CMakeFiles/example_pcl_lsd_point_pair.dir/example_pcl_lsd_point_pair.cpp.o: In function `~LSDObjRecRANSAC':
make[2]: Leaving directory `/media/Data/Documents/Grad/research/Projects/LSDPointPairs/qtcreator-build'
make[1]: Leaving directory `/media/Data/Documents/Grad/research/Projects/LSDPointPairs/qtcreator-build'
/home/mustafa/projects/LSDPointPairs/examples/../lsd_obj_rec_ransac.h:44: undefined reference to `pcl::recognition::ORROctreeCloud::~ORROctreeCloud()'
/home/mustafa/projects/LSDPointPairs/examples/../lsd_obj_rec_ransac.h:44: undefined reference to `pcl::recognition::ORROctreeCloud::~ORROctreeCloud()'
../lib/liblsd_obj_rec_ransac.a(lsd_obj_rec_ransac.cpp.o): In function `LSDObjRecRANSAC':
/home/mustafa/projects/LSDPointPairs/lsd_obj_rec_ransac.cpp:18: undefined reference to `pcl::recognition::LSDPointPairModelLibrary::LSDPointPairModelLibrary(float, float, float)'
/home/mustafa/projects/LSDPointPairs/lsd_obj_rec_ransac.cpp:18: undefined reference to `pcl::recognition::ORROctreeCloud::ORROctreeCloud()'
/home/mustafa/projects/LSDPointPairs/lsd_obj_rec_ransac.cpp:18: undefined reference to `pcl::recognition::ORROctreeCloud::~ORROctreeCloud()'
../lib/liblsd_obj_rec_ransac.a(lsd_point_pair_model_library.cpp.o): In function `LSDPointPairModel':
/home/mustafa/projects/LSDPointPairs/lsd_point_pair_model_library.h:36: undefined reference to `pcl::recognition::ORROctreeCloud::ORROctreeCloud()'
/home/mustafa/projects/LSDPointPairs/lsd_point_pair_model_library.h:36: undefined reference to `pcl::recognition::ORROctreeCloud::~ORROctreeCloud()'
../lib/liblsd_obj_rec_ransac.a(lsd_point_pair_model_library.cpp.o): In function `~LSDPointPairModel':
/home/mustafa/projects/LSDPointPairs/lsd_point_pair_model_library.h:27: undefined reference to `pcl::recognition::ORROctreeCloud::~ORROctreeCloud()'
/home/mustafa/projects/LSDPointPairs/lsd_point_pair_model_library.h:27: undefined reference to `pcl::recognition::ORROctreeCloud::~ORROctreeCloud()'
collect2: ld returned 1 exit status
make[2]: *** [bin/example_pcl_lsd_point_pair] Error 1
make[1]: *** [examples/CMakeFiles/example_pcl_lsd_point_pair.dir/all] Error 2
make: *** [all] Error 2
The library successfully gets built because I see the liblsd_obj_rec_ransac.a file gets generated. But the problem happens when trying to compile the example. What am I doing wrong?

Related

Can not link yaml-cpp with my cmake project

My CMakeLists.txt
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(test_includes)
#find_package(Boost COMPONENTS system filesystem REQUIRED)
#include_directories( ${Boost_INCLUDE_DIRS} )
set(Torch_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libtorch/share/cmake/Torch")
find_package(Boost COMPONENTS system filesystem REQUIRED)
find_package(Threads REQUIRED)
find_package(Torch REQUIRED)
find_package(yaml-cpp REQUIRED)
include_directories( ${Boost_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIR}
${yaml-cpp_INCLUDE_DIR}
${Torch_INCLUDE_DIRS}
include)
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g3 -gdwarf -fno-omit-frame-pointer -DNDEBUG")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
add_subdirectory(include)
#link_directories(libraries)
set( LIBS_TO_LINK
Domains
Agents
Planning
yaml-cpp
${TORCH_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT})# -llapack)
add_executable(testWarehouse testWarehouse.cpp)
target_link_libraries(testWarehouse ${LIBS_TO_LINK})
The error message i am getting:
...
[100%] Linking CXX executable testWarehouse
/usr/bin/ld: CMakeFiles/testWarehouse.dir/testWarehouse.cpp.o: in function `WarehouseSimulation(std::string const&, unsigned long)':
testWarehouse.cpp:(.text+0x13af): undefined reference to `YAML::LoadFile(std::string const&)'
/usr/bin/ld: CMakeFiles/testWarehouse.dir/testWarehouse.cpp.o: in function `YAML::detail::node_ref::set_scalar(std::string const&)':
testWarehouse.cpp:(.text._ZN4YAML6detail8node_ref10set_scalarERKSs[_ZN4YAML6detail8node_ref10set_scalarERKSs]+0x2a): undefined reference to `YAML::detail::node_data::set_scalar(std::string const&)'
/usr/bin/ld: CMakeFiles/testWarehouse.dir/testWarehouse.cpp.o: in function `YAML::Node::Scalar() const':
testWarehouse.cpp:(.text._ZNK4YAML4Node6ScalarEv[_ZNK4YAML4Node6ScalarEv]+0x79): undefined reference to `YAML::detail::node_data::empty_scalar()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/testWarehouse.dir/build.make:109: testWarehouse] Error 1
make[1]: *** [CMakeFiles/Makefile2:152: CMakeFiles/testWarehouse.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
note: i do have yamp-cpp installed
my full project:
i have tried manually adding -lyaml-cpp to the compile commands, with no effect.
can someone please check my CMakeLists.txt and tell my if am linking yaml-cpp properly, Thanks. (i am 99% sure that it is correct)
i have tried yaml-cpp versions 7.0, 6.3, 5.3 all with the same result
looking at .../build/CMakeCache.txt it includes:
//The directory containing a CMake configuration file for yaml-cpp.
yaml-cpp_DIR:PATH=/usr/share/cmake/yaml-cpp
which looks correct to me
if you need any more info please ask
Thank you
it was pre C++11 ABI issue
the solution can be found at:
https://github.com/pytorch/pytorch/issues/19353#issuecomment-652314883

Link SDL and Glut in CMake

I have a project (on linux) where I require glut and SDL.
I already managed to properly link glut, but I still cant get SDL linked.
My CMake file looks like this:
cmake_minimum_required(VERSION 3.7)
project(ObjLoader)
add_executable(testas main.cpp)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
include_directories( ${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS} )
target_link_libraries(testas ${OPENGL_LIBRARIES} ${GLUT_LIBRARY})
When building the following exception is error occurs:
/opt/JetBrains/apps/CLion/ch-0/181.4668.70/bin/cmake/bin/cmake --build /home/void/Documents/Projects/ObjLoader/cmake-build-debug --target testas -- -j 2
[ 50%] Linking CXX executable testas
CMakeFiles/testas.dir/main.cpp.o: In function `main':
/home/user/Documents/Projects/ObjLoader/main.cpp:165: undefined reference to `SDL_Init'
/home/user/Documents/Projects/ObjLoader/main.cpp:166: undefined reference to `SDL_SetVideoMode'
/home/user/Documents/Projects/ObjLoader/main.cpp:173: undefined reference to `SDL_GetTicks'
/home/user/Documents/Projects/ObjLoader/main.cpp:174: undefined reference to `SDL_PollEvent'
/home/user/Documents/Projects/ObjLoader/main.cpp:184: undefined reference to `SDL_GL_SwapBuffers'
/home/user/Documents/Projects/ObjLoader/main.cpp:188: undefined reference to `SDL_GetTicks'
/home/user/Documents/Projects/ObjLoader/main.cpp:189: undefined reference to `SDL_GetTicks'
/home/user/Documents/Projects/ObjLoader/main.cpp:189: undefined reference to `SDL_Delay'
/home/user/Documents/Projects/ObjLoader/main.cpp:191: undefined reference to `SDL_Quit'
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/testas.dir/build.make:100: testas] Error 1
make[2]: *** [CMakeFiles/Makefile2:68: CMakeFiles/testas.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:80: CMakeFiles/testas.dir/rule] Error 2
make: *** [Makefile:118: testas] Error 2
but the same problem persists,
When I try to link it as described here: How to use SDL2 and SDL_image with cmake
the same problem persists. How can I properly include and link SDL in the CMake file above?
My attempt was this:
cmake_minimum_required(VERSION 3.7)
project(ObjLoader)
add_executable(testas main.cpp)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
find_package(SDL2 REQUIRED)
include_directories( ${OPENGL_INCLUDE_DIRS} ${GLUT_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
target_link_libraries(testas ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${SDL2_LIBRARIES})
Doesnt change anything, same problem.

Why I cannot use boost correctly with CMake?

I will try to explain in detail the difficulties I encountered.
Recently I want to use boost libraries in Ubuntu Mint 18 x64. So I download the newest version of it which is 1.62.0. Sha256sum is fine. Then I started compiled it with "./bootstrap.sh" and "./b2". Finally copied then to "/usr/local" with "sudo ./b2 install". So far so good.
I am using Clion right now, so new job is to add libraries in Cmakelist.txt. Code below is what I have added.
set(BOOST_ROOT /usr/local)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.62.0)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(BoostTest main.cpp)
target_link_libraries(BoostTest ${Boost_LIBRARIES})
endif()
First thing I want to explain is that I know it is not good to set up a specific location in CMake, but without it Cmake cannot find it. So I just do that. And, at this moment, CMake did not post any error info. Here is my hello_world demo.
#include <iostream>
#include <boost/thread/testable_mutex.hpp>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
I just include a .hpp for test, nothing else. When I attemped to run it. I got these.
-- Boost version: 1.62.0
-- Configuring done
-- Generating done
-- Build files have been written to: /home/vita-nove/ClionProjects/BoostTest/cmake-build-debug
[ 50%] Building CXX object CMakeFiles/BoostTest.dir/main.cpp.o
[100%] Linking CXX executable BoostTest
CMakeFiles/BoostTest.dir/main.cpp.o: In function `__static_initialization_and_destruction_0(int, int)':
/usr/local/include/boost/system/error_code.hpp:221: undefined reference to `boost::system::generic_category()'
/usr/local/include/boost/system/error_code.hpp:222: undefined reference to `boost::system::generic_category()'
/usr/local/include/boost/system/error_code.hpp:223: undefined reference to `boost::system::system_category()'
collect2: error: ld returned 1 exit status
CMakeFiles/BoostTest.dir/build.make:94: recipe for target 'BoostTest' failed
make[3]: *** [BoostTest] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/BoostTest.dir/all' failed
make[2]: *** [CMakeFiles/BoostTest.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/BoostTest.dir/rule' failed
make[1]: *** [CMakeFiles/BoostTest.dir/rule] Error 2
Makefile:118: recipe for target 'BoostTest' failed
make: *** [BoostTest] Error 2
Wired thing is that I do find some .hpp file in External Libraries. They are all located in /include/boost. In /usr/local/lib and /usr/local/include/boost everything shows up as I expect.
Sorry for my bad English. After spending nearly whole day searching and testing I cannot solve it. I don't know what dependencies I have missed or something else. Anyway, Thank you for reading this, hope someone will help.
You have to tell cmake that you need the thread library
set(BOOST_ROOT /usr/local)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.62.0 COMPONENTS thread system) # <-- here
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(BoostTest main.cpp)
target_link_libraries(BoostTest ${Boost_LIBRARIES})
endif()

Create a CMakeFiles.txt file for newbies

I have a project with the following structure
/cmake_modules/
FindSFML.cmake
/includes/
car.hpp
motor.hpp
tires.hpp
/sources/
car.cpp
motor.cpp
tires.cpp
/main.cpp
/main.hpp
I have the following CMakeFiles.txt file:
cmake_minimum_required(VERSION 2.8)
project (MYGAME)
set (MYGAME_VERSION_MAJOR 1)
set (MYGAME_VERSION_MINOR 0)
set (EXECUTABLE_NAME "mygame")
include_directories ("${MYGAME_BINARY_DIR}")
include_directories ("${MYGAME_BINARY_DIR}/includes")
link_directories ("${MYGAME_BINARY_DIR}/sources")
add_executable(${EXECUTABLE_NAME} main.cpp)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
find_package(SFML 2.0 REQUIRED system window graphics network audio)
target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
When I try to execute make I get this:
[100%] Building CXX object CMakeFiles/mygame.dir/main.cpp.o
Linking CXX executable mygame
CMakeFiles/mygame.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x11): undefined reference to `mynamespace::Car::Instance()'
main.cpp:(.text+0x21): undefined reference to `mynamespace::Car::start()'
collect2: error: ld returned 1 exit status
make[2]: *** [mygame] Error 1
make[1]: *** [CMakeFiles/mygame.dir/all] Error 2
make: *** [all] Error 2
How do I fix it?
You need to include the rest of your sources (car.cpp, motor.cpp and tires.cpp) in the build in some way.
You can either add them along with main.cpp in the executable directly:
set(MySources sources/car.cpp sources/motor.cpp sources/tires.cpp main.cpp)
add_executable(${EXECUTABLE_NAME} ${MySources})
or you can make these into a library and link that:
set(MyLibSources sources/car.cpp sources/motor.cpp sources/tires.cpp)
add_library(MyLib ${MyLibSources})
add_executable(${EXECUTABLE_NAME} main.cpp)
...
target_link_libraries(${EXECUTABLE_NAME} MyLib ${SFML_LIBRARIES})
A couple of other points to note:
You should avoid the use of link_directories if possible (its own documentation discourages its use), and it's often helpful to include the headers in the list of files added via add_executable or add_library since these then show up in IDEs like MS Visual Studio.

OpenGL hello.c fails to build using CMake

I am trying to build the hello.c example from http://www.glprogramming.com/red/chapter01.html (look for "Example 1-2").
My CMakeLists.txt is as follows:
cmake_minimum_required (VERSION 2.8)
project (GLUTEX)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
include_directories(${GLUT_INCLUDE_DIRS})
include_directories(${OpenGL_INCLUDE_DIRS})
add_executable (glutex glutex.c)
target_link_libraries (glutex ${OpenGL_LIBRARIES})
target_link_libraries (glutex ${GLUT_LIBRARIES})
The CMake call succeeds in generating the required Makefile. But when I call make, I encounter the following:
Scanning dependencies of target glutex
[100%] Building C object CMakeFiles/glutex.dir/glutex.c.o
Linking C executable glutex
/usr/bin/ld: CMakeFiles/glutex.dir/glutex.c.o: undefined reference to symbol 'glOrtho'
/usr/bin/ld: note: 'glOrtho' is defined in DSO /usr/lib64/libGL.so.1 so try adding it to the linker command line
/usr/lib64/libGL.so.1: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
make[2]: *** [glutex] Error 1
make[1]: *** [CMakeFiles/glutex.dir/all] Error 2
make: *** [all] Error 2
How do I fix this?
Try changing
target_link_libraries (glutex ${OpenGL_LIBRARIES})
to
target_link_libraries (glutex ${OPENGL_LIBRARIES})