CLion - cmake undefined reference - c++

I would like to execute a working project with CLion.
So I was trying to emulate the Makefile through cmake but I'm not very good in it. I am sure that the error is inside cmake since the project is working with regular Makefile. Unfortunately, I cannot show a lot information on the project. I hope what I will show would be enough to receive your help.
The project directory structure ( without showing the files ) is shown in the following:
.
├── CMakeLists.txt
├── makefile
├── include
│ ├── data
│ ├── io
│ ├── learning
│ ├── metric
│ ├── scoring
│ └── io
└── src
├── data
├── io
├── learning
├── metric
├── scoring
├── utils
└── main.cc
./CMakeLists.txt
cmake_minimum_required(VERSION 3.3)
project(Project)
set(DCMAKE_CXX_COMPILER "g++-5")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
find_package(Boost 1.57.0 COMPONENTS program_options system filesystem REQUIRED)
find_package(OpenMP)
if (OPENMP_FOUND)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
include_directories(${Boost_INCLUDE_DIRS})
include_directories("include")
include_directories("src")
add_executable(Project src/main.cc)
target_link_libraries(Project ${Boost_LIBRARIES})
The project compiles without error, but fails during linking.
Part of the error is reported in the following:
[ 50%] Linking CXX executable Project
CMakeFiles/Project.dir/src/main.cc.o: in function "metric::ir::ir_metric_factory(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int)":
./include/metric/metricfactory.h:47: undefined reference to "metric::ir::Dcg::NAME_[abi:cxx11]"
./include/metric/metricfactory.h:49: undefined reference to "metric::ir::Ndcg::NAME_[abi:cxx11]"
./include/metric/metricfactory.h:51: undefined reference to "metric::ir::Tndcg::NAME_[abi:cxx11]"
./include/metric/metricfactory.h:53: undefined reference to "metric::ir::Map::NAME_[abi:cxx11]"
CMakeFiles/Project.dir/src/main.cc.o: in function "main":
./src/main.cc:130: undefined reference to "learning::forests::LambdaMart::NAME_[abi:cxx11]"
./src/main.cc:170: undefined reference to "learning::forests::Mart::NAME_[abi:cxx11]"
./src/main.cc:171: undefined reference to "learning::forests::LambdaMart::NAME_[abi:cxx11]"
./src/main.cc:172: undefined reference to "learning::forests::ObliviousMart::NAME_[abi:cxx11]"
./src/main.cc:173: undefined reference to "learning::forests::ObliviousLambdaMart::NAME_[abi:cxx11]"
./src/main.cc:174: undefined reference to "learning::linear::CoordinateAscent::NAME_[abi:cxx11]"
./src/main.cc:175: undefined reference to "learning::forests::Project::NAME_[abi:cxx11]"
./src/main.cc:176: undefined reference to "learning::CustomLTR::NAME_[abi:cxx11]"
./src/main.cc:181: undefined reference to "metric::ir::Dcg::NAME_[abi:cxx11]"
./src/main.cc:182: undefined reference to "metric::ir::Ndcg::NAME_[abi:cxx11]"
./src/main.cc:183: undefined reference to "metric::ir::Tndcg::NAME_[abi:cxx11]"
./src/main.cc:184: undefined reference to "metric::ir::Map::NAME_[abi:cxx11]"
./src/main.cc:247: undefined reference to "metric::ir::Dcg::NAME_[abi:cxx11]"
./src/main.cc:248: undefined reference to "metric::ir::Ndcg::NAME_[abi:cxx11]"
./src/main.cc:249: undefined reference to "metric::ir::Tndcg::NAME_[abi:cxx11]"
./src/main.cc:250: undefined reference to "metric::ir::Map::NAME_[abi:cxx11]"
./src/main.cc:319: undefined reference to "learning::forests::LambdaMart::NAME_[abi:cxx11]"
./src/main.cc:324: undefined reference to "learning::forests::Mart::NAME_[abi:cxx11]"
./src/main.cc:329: undefined reference to "learning::forests::ObliviousMart::NAME_[abi:cxx11]"
./src/main.cc:334: undefined reference to "learning::forests::ObliviousLambdaMart::NAME_[abi:cxx11]"
./src/main.cc:339: undefined reference to "learning::linear::CoordinateAscent::NAME_[abi:cxx11]"
./src/main.cc:346: undefined reference to "learning::linear::CoordinateAscent::CoordinateAscent(unsigned int, double, double, unsigned int, unsigned int)"
./src/main.cc:347: undefined reference to "learning::forests::Project::NAME_[abi:cxx11]"
./src/main.cc:351: undefined reference to "learning::CustomLTR::NAME_[abi:cxx11]"
./src/main.cc:352: undefined reference to "learning::CustomLTR::CustomLTR()"
( other errors lines )
collect2: error: ld returned 1 exit status
make[2]: *** [Project] Error 1
make[1]: *** [CMakeFiles/Project.dir/all] Error 2
make: *** [all] Error 2

Ok, I solve it thanks to the help of Tsyvarev.
./CMakeLists.txt
cmake_minimum_required(VERSION 3.3)
project(Project)
set(DCMAKE_CXX_COMPILER "g++-5")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
find_package(Boost 1.57.0 COMPONENTS program_options system filesystem REQUIRED)
find_package(OpenMP)
if (OPENMP_FOUND)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
include_directories(${Boost_INCLUDE_DIRS})
include_directories("include")
file(GLOB_RECURSE SOURCES src/*.cc) #*/
add_executable(Project ${SOURCES})
target_link_libraries(Project ${Boost_LIBRARIES})
where I used file(GLOB_RECURSE SOURCES src/*.cc) to add sources instead of include_directories("src").

Related

CMake with Qt UI file not found

I have a C++ project using Qt with CMAKE that is organized in the following folders:
├── app
│   ├── CMakeLists.txt
│   └── main.cpp
├── CMakeLists.txt
├── include
│   └── MainWindow
│   └── MainWindow.h
└── src
├── CMakeLists.txt
├── MainWindow.cpp
└── MainWindow.ui
In the different CMakeLists.txt I have the following information:
CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(prj VERSION 0.0.1 LANGUAGES CXX)
add_subdirectory(app)
add_subdirectory(src)
app/CMakeLists.txt
add_executable(app main.cpp)
target_link_libraries(app PRIVATE MainWindow)
src/CMakeLists.txt
# Configure AUTO
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
# Generar librería para la interfaz gráfica.
add_library(MainWindow MainWindow.cpp MainWindow.ui)
target_include_directories(MainWindow PUBLIC ../include)
target_compile_features(MainWindow PUBLIC cxx_std_14)
# Load QT files
set(CMAKE_PREFIX_PATH "/opt/Qt/5.15.2/gcc_64/lib/cmake")
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
target_link_libraries(MainWindow Qt5::Core Qt5::Gui Qt5::Widgets)
What modifications or additions do I have to make in the different CMake files so that with a similar folder distribution I can get the application to work correctly without having errors?
The exact error, after all the modificications, is the following one:
FAILED: app/app
: && /usr/bin/c++ -g app/CMakeFiles/app.dir/main.cpp.o -o app/app -Wl,-rpath,/opt/Qt/5.15.2/gcc_64/lib src/libMainWindow.a /opt/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5.15.2 /opt/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5.15.2 /opt/Qt/5.15.2/gcc_64/lib/libQt5Core.so.5.15.2 && :
/usr/bin/ld: src/libMainWindow.a(MainWindow.cpp.o): in function `MainWindow::MainWindow(QWidget*)':
/home/developer/CLionProjects/qtTest_v0/src/MainWindow.cpp:12: undefined reference to `vtable for MainWindow'
/usr/bin/ld: /home/developer/CLionProjects/qtTest_v0/src/MainWindow.cpp:12: undefined reference to `vtable for MainWindow'
/usr/bin/ld: src/libMainWindow.a(MainWindow.cpp.o): in function `MainWindow::~MainWindow()':
/home/developer/CLionProjects/qtTest_v0/src/MainWindow.cpp:16: undefined reference to `vtable for MainWindow'
/usr/bin/ld: /home/developer/CLionProjects/qtTest_v0/src/MainWindow.cpp:16: undefined reference to `vtable for MainWindow'

ImGui can't find any definitions

OS: Windows10
Editor: VScode
Build: CMake
Compiler: GCC(actually MinGW)
ImGui branch: master (I didn't use the release tag branch), GLFW+OpenGL3 implementations
Here is the situation, I'm rewriting my learnOpenGL project with some more features added to it, like using yaml to do the initialization config. Now I want to add a visual config window when I run my opengl demo, so I could adjust colors or shader options or whatever.
I choose ImGui and followed many tutorials from other sites, when I add ImGui cpp files and compile them into a static library, the imgui_gui.cpp(not only this one) can't find any definitions of functions it contains(nearly all).
Below is the structure of my demo's workspace(simplified):
I:.
├───.vscode
├───CMakeLists.txt
├───app
│ ├───CMakeLists.txt
│ └───ImGui_test.cpp
├───bin
├───build
├───config
├───images
├───include
│ ├───glad
│ ├───GLFW
│ ├───glm
│ ├───ImGui
│ │ ├───imconfig.h
│ │ ├───imgui.h
│ │ ├───imgui_impl_glfw.h
│ │ ├───imgui_impl_opengl3.h
│ │ ├───imgui_impl_opengl3_loader.h
│ │ ├───imgui_internal.h
│ │ ├───imstb_rectpack.h
│ │ ├───imstb_textedit.h
│ │ └───imstb_truetype.h
│ ├───KHR
│ ├───myImplement
│ ├───stb_image
│ └───yaml-cpp
├───lib
│ ├───libglfw3.a
│ ├───libimgui.a
│ ├───libmysrc.a
│ └───libyaml-cpp.dll
├───model
├───shader
│ ├───shader_fragment
│ └───shader_vertex
└───src
├───CMakeLists.txt
├───config.cpp
├───glad.c
├───shader.cpp
├───stb_image.cpp
└───ImGui
├───imgui.cpp
├───imgui_demo.cpp
├───imgui_draw.cpp
├───imgui_impl_glfw.cpp
├───imgui_impl_opengl3.cpp
└───imgui_widgets.cpp
The problem is, when I compile other opengl demos, this build system works fine, all static and dynamic libraries can be found and linked properly(glfw, yaml, opengl32, and the lib made of cpp files from the 'src' dir except for the cpp files in the 'ImGui' dir), but adding libimgui.a seems not providing correct definitions for demos that contains any imgui function.
// a piece of error in cmd
// undefined reference of imgui.cpp(part of)
I:/VScode_projects/shader_toy/src/ImGui/imgui.cpp:2557: undefined reference to `ImGui::TableEndRow(ImGuiTable*)'
../../lib/libimgui.a(imgui.cpp.obj): In function `ImGuiListClipper::Begin(int, float)':
I:/VScode_projects/shader_toy/src/ImGui/imgui.cpp:2595: undefined reference to `ImGui::TableEndRow(ImGuiTable*)'
../../lib/libimgui.a(imgui.cpp.obj): In function `ImGuiListClipper::Step()':
I:/VScode_projects/shader_toy/src/ImGui/imgui.cpp:2652: undefined reference to `ImGui::TableEndRow(ImGuiTable*)'
../../lib/libimgui.a(imgui.cpp.obj): In function `ImGui::GcCompactTransientMiscBuffers()':
I:/VScode_projects/shader_toy/src/ImGui/imgui.cpp:3357: undefined reference to `ImGui::TableGcCompactSettings()'
../../lib/libimgui.a(imgui.cpp.obj): In function `ImGui::NewFrame()':
I:/VScode_projects/shader_toy/src/ImGui/imgui.cpp:4516: undefined reference to `ImGui::TableGcCompactTransientBuffers(ImGuiTable*)'
I:/VScode_projects/shader_toy/src/ImGui/imgui.cpp:4519: undefined reference to `ImGui::TableGcCompactTransientBuffers(ImGuiTableTempData*)'
../../lib/libimgui.a(imgui.cpp.obj): In function `ImGui::Initialize()':
// undefined reference in imgui_demo.cpp(part of)
../../lib/libimgui.a(imgui_demo.cpp.obj): In function `ShowPlaceholderObject':
I:/VScode_projects/shader_toy/src/ImGui/imgui_demo.cpp:7096: undefined reference to `ImGui::TableNextRow(int, float)'
I:/VScode_projects/shader_toy/src/ImGui/imgui_demo.cpp:7097: undefined reference to `ImGui::TableSetColumnIndex(int)'
I:/VScode_projects/shader_toy/src/ImGui/imgui_demo.cpp:7100: undefined reference to `ImGui::TableSetColumnIndex(int)'
I:/VScode_projects/shader_toy/src/ImGui/imgui_demo.cpp:7116: undefined reference to `ImGui::TableNextRow(int, float)'
I:/VScode_projects/shader_toy/src/ImGui/imgui_demo.cpp:7117: undefined reference to `ImGui::TableSetColumnIndex(int)'
I:/VScode_projects/shader_toy/src/ImGui/imgui_demo.cpp:7122: undefined reference to `ImGui::TableSetColumnIndex(int)'
I:/VScode_projects/shader_toy/src/ImGui/imgui_demo.cpp:7128: undefined reference to `ImGui::NextColumn()'
Also, three CMakeLists.txt in root directory, src and app:
// CMakeLists.txt in root directory
CMAKE_MINIMUM_REQUIRED(VERSION 3.19)
PROJECT(shader_toy)
SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_CXX_STANDARD 14)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)
SET(GL_LIB opengl32)
OPTION(DEBUG "debug switch" OFF)
OPTION(GEN_SHARED_LIB "generate shared lib .so" OFF)
OPTION(GEN_STATIC_LIB "generate static lib .a" ON)
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/src)
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/app)
//CMakeLists.txt in src directory
AUX_SOURCE_DIRECTORY(. SRC_LIST)
AUX_SOURCE_DIRECTORY(ImGui IMGUI_LIST)
IF(DEBUG)
ADD_DEFINITIONS(-DDEBUG)
ENDIF()
IF(SRC_LIST)
ADD_LIBRARY(mysrc STATIC ${SRC_LIST})
ENDIF()
IF(IMGUI_LIST)
ADD_LIBRARY(imgui STATIC ${IMGUI_LIST})
ENDIF()
MESSAGE("following source files will be linked into library:")
MESSAGE("------------------- SRC LIST -------------------")
FOREACH(src ${SRC_LIST})
MESSAGE("${src}")
ENDFOREACH()
MESSAGE("------------------- LIST END -------------------")
// CMakeLists.txt in app directory
AUX_SOURCE_DIRECTORY(. APP_LIST)
IF (DEBUG)
ADD_DEFINITIONS(-DDEBUG)
MESSAGE("DEBUG set to ON")
ENDIF()
FILE(GLOB LIB_LIST ${PROJECT_SOURCE_DIR}/lib/*.dll ${PROJECT_SOURCE_DIR}/lib/*.a)
IF (LIB_LIST)
FOREACH (lib ${LIB_LIST})
MESSAGE("lib found: ${lib}")
ENDFOREACH ()
ENDIF()
FOREACH (app ${APP_LIST})
GET_FILENAME_COMPONENT(output ${app} NAME_WE)
ADD_EXECUTABLE(${output} ${app})
IF (LIB_LIST)
FOREACH (lib ${LIB_LIST})
GET_FILENAME_COMPONENT(lib_name ${lib} NAME_WE)
GET_FILENAME_COMPONENT(lib_post ${lib} LAST_EXT)
IF (NOT lib_post)
MESSAGE(FATAL_ERROR "lib format not recognized\n")
ENDIF()
IF (NOT(lib_post STREQUAL ".a" OR lib_post STREQUAL ".so" OR lib_post STREQUAL ".lib" OR lib_post STREQUAL ".dll"))
MESSAGE(FATAL_ERROR "lib format not recognized: ${lib_post}\n")
ENDIF()
STRING(SUBSTRING ${lib_name} 3 -1 lib_name_without_prefix)
MESSAGE("${output} will be linked with: ${lib_name_without_prefix}")
TARGET_LINK_LIBRARIES(${output} ${lib_name_without_prefix})
ENDFOREACH()
MESSAGE("${output} will be linked with: ${GL_LIB}")
TARGET_LINK_LIBRARIES(${output} ${GL_LIB})
ENDIF()
ENDFOREACH()
I know 'undefined reference' is a common linking error in cpp projects, I have fixed many similar problems in my previous cpp projects, but I can't figure out what goes wrong in this one, actually, I have used global search(Ctrl+Shift+f) on these undefined reference functions in VScode, they do don't have formal definitions in any file! All references in search results is the usage or declaration, but no definitions! I don't understand, may be definitions will be generated in compiling???
Will it be the problem in:
wrong platform
missed steps in compiling / incorrect compile methods
wrong OpenGL version(as I don't know which version the opengl32.lib from Windows10 implements)
wrong repo, I should download the release tag instead of master branch
missing definition files, I forget to copy them into my workspace
If you have used the ImGui library, any advice would be appreciate! Thank you!

libVLC|make: undefined reference to `libvlc_new'

For a small project, I decided to use libvlc hence C/C++.
Using different references I somehow installed opencv and libvlc libraries and also wrote the following CMake file:
cmake_minimum_required(VERSION 3.10)
project(untitled1)
set(CMAKE_CXX_STANDARD 14)
SET(CMAKE_MODULE_PATH
${CMAKE_SOURCE_DIR}/cmake
${CMAKE_SOURCE_DIR}/config
${CMAKE_SOURCE_DIR}/config/platform
)
find_package(OpenCV REQUIRED)
find_package(LIBVLC REQUIRED)
file(GLOB SOURCE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
)
add_executable(untitled1 ${SOURCE_FILES})
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
if(CMAKE_VERSION VERSION_LESS "2.8.11")
# Add OpenCV headers location to your include paths
include_directories(${OpenCV_INCLUDE_DIRS})
endif()
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${LIBVLC_INCLUDE_DIRS})
set(LIBS ${LIBS} ${OpenCV_LIBS})
set(LIBS ${LIBS} ${LIBVLC_LIBRARIES} )
target_link_libraries( untitled1 ${LIBS})
But when I do, cmake and then make I get the following error:
[100%] Linking CXX executable untitled1
CMakeFiles/untitled1.dir/VLCReader.cpp.o: In function `VLCReader::VLCReader(char*)':
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:17: undefined reference to `libvlc_new'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:18: undefined reference to `libvlc_media_player_new'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:21: undefined reference to `libvlc_video_set_callbacks'
CMakeFiles/untitled1.dir/VLCReader.cpp.o: In function `VLCReader::~VLCReader()':
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:26: undefined reference to `libvlc_media_player_stop'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:27: undefined reference to `libvlc_media_player_release'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:28: undefined reference to `libvlc_release'
CMakeFiles/untitled1.dir/VLCReader.cpp.o: In function `VLCReader::start(int, int)':
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:33: undefined reference to `libvlc_media_player_pause'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:34: undefined reference to `libvlc_media_new_location'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:35: undefined reference to `libvlc_media_player_set_media'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:36: undefined reference to `libvlc_media_release'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:38: undefined reference to `libvlc_video_set_format'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:39: undefined reference to `libvlc_media_player_play'
CMakeFiles/untitled1.dir/VLCReader.cpp.o: In function `VLCReader::pause(bool)':
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:45: undefined reference to `libvlc_media_player_set_pause'
CMakeFiles/untitled1.dir/VLCReader.cpp.o: In function `VLCReader::updataSize()':
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:51: undefined reference to `libvlc_video_get_width'
/home/ravinder/CLionProjects/untitled1/VLCReader.cpp:52: undefined reference to `libvlc_video_get_height'
collect2: error: ld returned 1 exit status
CMakeFiles/untitled1.dir/build.make:166: recipe for target 'untitled1' failed
Please help me in going ahead. I am really new to C/C++ cmake based world.
Thanks #Tsyvarev and other people who pinted me in right direction.
My mistake in the CMake file is that I am using wrong variable names or say usng variables whihc are not defined.
LIBVLC_INCLUDE_DIRS to LIBVLC_INCLUDE_DIR
LIBVLC_LIBRARIES to LIBVLC_LIBRARY
Thanks all!

linking to a custom library using cmake

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?

CMake linking error (collect2: ld returned 1 exit status)

The project structure below is a simplified example.
├── CMakeLists.txt
├── debug
├── CommBase
│ ├── Task.h
│ ├── Task.cpp
│ ├── Thread.h
│ ├── Thread.cpp
│ └── CMakeLists.txt
├── NetWork
│ ├── TSocket.h
│ ├── TSocket.cpp
│ ├── Stream_Channel.h
│ ├── Stream_Channel.cpp
│ └── CMakeLists.txt
├── MessageDispatch
│ ├── Channel_Manager.h
│ ├── Channel_Manager.cpp
│ ├── Message_Facade.h
│ ├── Message_Facade.cpp
│ └── CMakeLists.txt
└── DemoServer
├── CMakeLists.txt
└── main.cpp
./CMakeLists.txt
PROJECT(DDLIB)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
MESSAGE(STATUS "This is PROJECT_BINARY_DIR dir "${PROJECT_BINARY_DIR})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
ADD_SUBDIRECTORY(CommBase)
ADD_SUBDIRECTORY(NetWork)
ADD_SUBDIRECTORY(DemoServer)
CommBase/CMakeLists.txt
AUX_SOURCE_DIRECTORY(. LIB_SRC_LIST)
ADD_LIBRARY(CommBase SHARED STATIC ${LIB_SRC_LIST})
INCLUDE_DIRECTORIES(../boost)
INSTALL(TARGETS CommBase CommBase
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
SET( CMAKE_BUILD_TYPE Debug )
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
NetWork/CMakeLists.txt
AUX_SOURCE_DIRECTORY(. LIB_SRC_LIST)
ADD_LIBRARY(NetWork SHARED STATIC ${LIB_SRC_LIST})
INCLUDE_DIRECTORIES(../boost)
INSTALL(TARGETS NetWork NetWork
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
TARGET_LINK_LIBRARIES(NetWork CommBase)
SET( CMAKE_BUILD_TYPE Debug )
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
MessageDispatch/CMakeLists.txt
AUX_SOURCE_DIRECTORY(. LIB_SRC_LIST)
ADD_LIBRARY(MessageDispatch SHARED STATIC ${LIB_SRC_LIST})
INCLUDE_DIRECTORIES(../boost)
INCLUDE_DIRECTORIES(../CommBase)
INCLUDE_DIRECTORIES(../NetWork)
ADD_DEPENDENCIES(MessageDispatch CommBase NetWork)
LINK_DIRECTORIES(/home/cl/server/ddsvn/debug)
TARGET_LINK_LIBRARIES(MessageDispatch CommBase NetWork)
INSTALL(TARGETS MessageDispatch MessageDispatch
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
DemoServer/CMakeLists.txt
PROJECT(DDLIB)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
MESSAGE(STATUS "This is PROJECT_BINARY_DIR dir "${PROJECT_BINARY_DIR})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
AUX_SOURCE_DIRECTORY(. SRC_LIST)
ADD_EXECUTABLE(DemoServer ${SRC_LIST})
INCLUDE_DIRECTORIES(../boost)
INCLUDE_DIRECTORIES(../CommBase)
INCLUDE_DIRECTORIES(../NetWork)
INCLUDE_DIRECTORIES(../MessageDispatch)
ADD_DEPENDENCIES(DemoServer CommBase NetWork MessageDispatch)
LINK_DIRECTORIES(/home/cl/server/ddsvn/debug)
TARGET_LINK_LIBRARIES(DemoServer CommBase NetWork MessageDispatch)
Linking CXX executable DemoServer
/usr/bin/cmake -E cmake_link_script CMakeFiles/DemoServer.dir/link.txt --verbose=1
/usr/bin/c++ -fPIC CMakeFiles/DemoServer.dir/stdafx.cpp.o CMakeFiles/DemoServer.dir/DemoServer.cpp.o -o DemoServer -rdynamic -lCommBase -lNetWork -lMessageDispatch
/usr/local/lib/libMessageDispatch.a(Message_Facade.cpp.o): In function `Message_Facade::stop()':
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:80: undefined reference to `Timer_Queue::instance()'
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:80: undefined reference to `Timer_Queue::stop()'
/usr/local/lib/libMessageDispatch.a(Message_Facade.cpp.o): In function `Message_Facade::wait()':
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:87: undefined reference to `Task::wait()'
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:88: undefined reference to `Task::wait()'
/usr/local/lib/libMessageDispatch.a(Acceptor_Manager.cpp.o): In function `Stream_Acceptor':
/home/cl/server/ddsvn/MessageDispatch/../NetWork/Stream_Accecptor.h:40: undefined reference to `vtable for Stream_Acceptor'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o): In function `Channel_Manager':
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:81: undefined reference to `Channel_Handler::~Channel_Handler()'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o): In function `~Channel_Manager':
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:86: undefined reference to `Channel_Handler::~Channel_Handler()'
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:86: undefined reference to `Channel_Handler::~Channel_Handler()'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o): In function `Channel_Handler':
/home/cl/server/ddsvn/MessageDispatch/../NetWork/Channel_Handler.h:14: undefined reference to `vtable for Channel_Handler'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o):(.rodata._ZTI15Channel_Manager[typeinfo for Channel_Manager]+0x28): undefined reference to `typeinfo for Channel_Handler'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o): In function `Message':
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:49: undefined reference to `Binary_Stream::Binary_Stream(int)'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:98: undefined reference to `Binary_Stream::~Binary_Stream()'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:100: undefined reference to `Binary_Stream::Binary_Stream(int)'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o): In function `Message::resize(int)':
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:187: undefined reference to `Stream_Base::resize(int)'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:196: undefined reference to `Stream_Base::resize(int)'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o): In function `~Message':
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:203: undefined reference to `Binary_Stream::~Binary_Stream()'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:203: undefined reference to `Binary_Stream::~Binary_Stream()'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o):(.rodata._ZTV7Message[vtable for Message]+0x20): undefined reference to `Stream_Base::clone_stream()'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o):(.rodata._ZTI7Message[typeinfo for Message]+0x10): undefined reference to `typeinfo for Binary_Stream'
/usr/local/lib/libMessageDispatch.a(Connector_Manager.cpp.o): In function `Stream_Connector':
/home/cl/server/ddsvn/MessageDispatch/../NetWork/Stream_Connector.h:42: undefined reference to `vtable for Stream_Connector'
/usr/local/lib/libMessageDispatch.a(Context.cpp.o): In function `Context':
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:15: undefined reference to `Dispatch_Thread::Dispatch_Thread()'
/usr/local/lib/libMessageDispatch.a(Context.cpp.o): In function `Context::initialize()':
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:113: undefined reference to `Timer_Queue::instance()'
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:113: undefined reference to `Timer_Queue::start()'
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:116: undefined reference to `Task::activate(int, int*)'
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:121: undefined reference to `Task::activate(int, int*)'
/usr/local/lib/libMessageDispatch.a(Re_Connect_Handler.cpp.o): In function `Re_Connect_Handler::process_re_connect(Context&, int)':
/home/cl/server/ddsvn/MessageDispatch/Re_Connect_Handler.cpp:23: undefined reference to `Timer_Queue::instance()'
/home/cl/server/ddsvn/MessageDispatch/Re_Connect_Handler.cpp:23: undefined reference to `Timer_Queue::schedule_timer(Smart_Ptr<Timer_Handler>, Time_Value const&, Smart_Ptr<Ref_Object>, EDispatchType, Dispatch_Thread*)'
/usr/local/lib/libMessageDispatch.a(IO_Thread.cpp.o): In function `IO_Thread':
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:4: undefined reference to `Task::Task()'
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:7: undefined reference to `Task::~Task()'
/usr/local/lib/libMessageDispatch.a(IO_Thread.cpp.o): In function `~IO_Thread':
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:12: undefined reference to `Task::~Task()'
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:12: undefined reference to `Task::~Task()'
/usr/local/lib/libMessageDispatch.a(IO_Thread.cpp.o):(.rodata._ZTI9IO_Thread[typeinfo for IO_Thread]+0x10): undefined reference to `typeinfo for Task'
collect2: ld returned 1 exit status
make[2]: *** [DemoServer] Error 1
make[2]: Leaving directory `/home/cl/server/ddsvn/DemoServer/Debug'
make[1]: *** [CMakeFiles/DemoServer.dir/all] Error 2
make[1]: Leaving directory `/home/cl/server/ddsvn/DemoServer/Debug'
make: *** [all] Error 2
I'm hoping this is a really simple lack of understanding of how CMake handles dependencies. This compiles without error, but fails during linking
NetWork is dependent on CommBase, MessageDispatch dependent on NetWork and CommBase,how can i specify in DemoServer
There are a few issues here, some more critical than others. Roughly in order of importance:
add_library allows you to define the library as either STATIC or SHARED, but not both.
target_link_libraries links the dependencies in the order they appear in the command. You should specify them from most-dependent to least. So, in your DemoServer CMakeLists.txt, it should be
TARGET_LINK_LIBRARIES(DemoServer MessageDispatch NetWork CommBase)
However, from the docs:
Library dependencies are transitive by default. When this target is linked into another target then the libraries linked to this target will appear on the link line for the other target too.
In other words, you should have TARGET_LINK_LIBRARIES(NetWork CommBase) in NetWork (you already do), TARGET_LINK_LIBRARIES(MessageDispatch NetWork) in MessageDispatch, and just TARGET_LINK_LIBRARIES(DemoServer MessageDispatch) for the Demo.
CMAKE_BUILD_TYPE would normally be set by the user via the command line (or CMake GUI). It should probably only be set inside the CMakeLists.txt if the user hasn't already done so, or if it's set to an invalid value. If you set or change the value, it would be good to tell the user via a message. You probably shouldn't be setting it in 2 different places.
aux_source_directory is not recommended as a means to gather lists of source files. The recommended way is to hard-code the file paths into your CMakeLists.txt, so if the source list changes, CMake automatically re-runs.
link_directories is rarely required, and shouldn't contain a hard-coded absolute path.
LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH are deprecated.
add_dependencies is not required if you have already specified these dependencies via a target_link_libraries call.