How to use the c++ library gtsam in my project package? - c++

this is the first time I use an external c++ library aside from OpenCV. In the code I use quite a lot of ROS functionality, but I believe my issue is not related to ROS. I want to build a project with the GTSAM library.
Therefore I cloned the repository into my /usr/lib folder and installed it as instructed.
I then wrote the CMakeLists.txt,added two includes into my - otherwise functioning .h file - and tried to compile.
The beginning of my .h file, the compile error and my CMakeLists.txt are shown below. Interestingly, if I comment out the second include and just include Pose2.h, compilation works. That should mean that the compiler at least finds some headers from the library, ergo it is correctly installed. The part of my cmake code which is supposed to link the library is extracted from an example project given here. Any help is appreciated.
car_lib.h:
#ifndef CAR_LIB_H
#define CAR_LIB_H
// GTSAM headers
#include <gtsam/geometry/Pose2.h>
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
using namespace gtsam;
// rest of file follows....
When compiling, I get the following error:
...
[100%] Linking CXX executable /home/marc/catkin_ws/devel/lib/car/car_node
[100%] Linking CXX shared library /home/marc/catkin_ws/devel/lib/libcar_lib.so
[100%] Built target car_lib
CMakeFiles/car_node.dir/src/car_node.cpp.o: In function `__static_initialization_and_destruction_0(int, int)':
/usr/local/include/gtsam/inference/Key.h:41: undefined reference to `gtsam::_defaultKeyFormatter[abi:cxx11](unsigned long)'
/usr/local/include/gtsam/inference/Key.h:52: undefined reference to `gtsam::_multirobotKeyFormatter[abi:cxx11](unsigned long)'
collect2: error: ld returned 1 exit status
car/CMakeFiles/car_node.dir/build.make:113: recipe for target '/home/marc/catkin_ws/devel/lib/car/car_node' failed
make[2]: *** [/home/marc/catkin_ws/devel/lib/car/car_node] Error 1
CMakeFiles/Makefile2:384: recipe for target 'car/CMakeFiles/car_node.dir/all' failed
make[1]: *** [car/CMakeFiles/car_node.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j4 -l4" failed
My CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.3)
project(car)
## Compile as C++11, supported in ROS Kinetic and newer
add_compile_options(-std=c++11)
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
message_generation
nav_msgs
roscpp
sensor_msgs
std_msgs
)
###### GTSAM STUFF STARTS HERE
# Include GTSAM CMake tools
find_package(GTSAMCMakeTools)
#include(GtsamBuildTypes) # Load build type flags and default to Debug mode
#include(GtsamTesting) # Easy functions for creating unit tests and scripts
#include(GtsamMatlabWrap) # Automatic MATLAB wrapper generation
# Ensure that local folder is searched before library folders
#include_directories(BEFORE "${PROJECT_SOURCE_DIR}")
###################################################################################
# Find GTSAM components
find_package(GTSAM REQUIRED) # Uses installed package
include_directories(${GTSAM_INCLUDE_DIR})
###################################################################################
# Build static library from common sources
#set(CONVENIENCE_LIB_NAME ${PROJECT_NAME})
#add_library(${CONVENIENCE_LIB_NAME} STATIC include/car/car_lib.h src/car_lib.cpp)
#target_link_libraries(${CONVENIENCE_LIB_NAME} gtsam)
###### GTSAM STUFF ENDS HER
catkin_package(
INCLUDE_DIRS include
LIBRARIES car_lib
CATKIN_DEPENDS
geometry_msgs
message_runtime
nav_msgs
roscpp
sensor_msgs
std_msgs
)
include_directories(
include
${catkin_INCLUDE_DIRS}
)
## Declare a C++ library
add_library(car_lib
include/${PROJECT_NAME}/car_lib.h
src/car_lib.cpp
)
add_executable(car_node src/car_node)
target_link_libraries(car_node ${catkin_LIBRARIES})
target_link_libraries(car_lib
${catkin_LIBRARIES}
)

Try replacing the bit under ## Declare a C++ library with
## Declare a C++ library
add_library(car_lib src/car_lib.cpp)
target_link_libraries(car_lib
gtsam
${catkin_LIBRARIES}
)
add_executable(car_node src/car_node)
target_link_libraries(car_node
car_lib
gtsam
${catkin_LIBRARIES}
)

For those who are trying to do the same thing using makefile, Here is the solution. [ note this is for simple c++ program without ROS ].
all: main.cpp
#g++ main.cpp \
-std=c++11 \
-I /usr/include/eigen3 \
-lboost_system -lboost_filesystem \
-lgtsam \
-o main
clear:
#rm -rf main

Related

AirSim/Unity build on macOS ('boost/filesystem.hpp' file not found)

I am trying to install AirSim/Unity on MacOS Catalina. When I run Unity/build.sh I get a fatal error:
In file included from /Users/nfirbas/Documents/AirSim/Unity/AirLibWrapper/AirsimWrapper/Source/Logger.cpp:3:
/Users/nfirbas/Documents/AirSim/Unity/AirLibWrapper/AirsimWrapper/Source/Logger.h:6:11: fatal error: 'boost/filesystem.hpp' file not found
#include <boost/filesystem.hpp>
^~~~~~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
make[2]: *** [CMakeFiles/AirsimWrapper.dir/Source/Logger.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
I have installed boost with brew. It's my first time working with brew so I assume that I need to edit my CMakeList.txt. I tried changing it myself but I didn't get it working.
My CMakeLists.txt:
cmake_minimum_required(VERSION 3.5.0)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(MACOSX TRUE)
endif()
find_path(AIRSIM_ROOT NAMES AirSim.sln PATHS ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../..")
message(AirSim Root directory: ${AIRSIM_ROOT})
LIST(APPEND CMAKE_MODULE_PATH "${AIRSIM_ROOT}/cmake/cmake-modules")
LIST(APPEND CMAKE_MODULE_PATH "${RPC_SOURCE_DIR}/cmake")
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
INCLUDE("${AIRSIM_ROOT}/cmake/cmake-modules/CommonSetup.cmake")
INCLUDE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpc-setup.cmake")
INCLUDE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/mav-setup.cmake")
INCLUDE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/airlib-setup.cmake")
INCLUDE("${CMAKE_CURRENT_SOURCE_DIR}/cmake/airsimwrapper-setup.cmake")
IncludeEigen()
project(AirsimWrapper VERSION 0)
# RPC includes & source files
BuildRpc()
# MavLink source files
BuildMavLink()
#AirLib source files
BuildAirlib()
#AirsimWrapper source files
BuildAirsimWrapper()
###################### Link source files to library ######################################
if (${APPLE})
add_library(
${PROJECT_NAME} MODULE
${RPC_LIBRARY_SOURCE_FILES}
${MAVLINK_LIBRARY_SOURCE_FILES}
${AIRLIB_LIBRARY_SOURCE_FILES}
${AIRSIMWRAPPER_LIBRARY_SOURCE_FILES}
)
set_target_properties(${PROJECT_NAME} PROPERTIES BUNDLE TRUE)
else ()
add_library(
${PROJECT_NAME} SHARED
${RPC_LIBRARY_SOURCE_FILES}
${MAVLINK_LIBRARY_SOURCE_FILES}
${AIRLIB_LIBRARY_SOURCE_FILES}
${AIRSIMWRAPPER_LIBRARY_SOURCE_FILES}
)
endif ()
target_link_libraries(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT} -lstdc++ -lpthread -lboost_filesystem)
##################### Build Options #############################3
# Rpc
RpcCheckMSVN()
RpcCmakePkg()
RpcMSVNConfig()
You have told your library target to link against boost_filesystem, but you did not convey in your CMake where to find the Boost header files.
The idiomatic way to find Boost using CMake is to use the configuration files that now ship with Boost (e.g. BoostConfig.cmake), as of Boost version 1.70 and greater. You can make use of these by calling find_package(Boost ...), then linking with the imported target Boost::filesystem:
# Tell CMake to locate Boost on your machine, specifically
# looking for the filesystem library.
find_package(Boost REQUIRED COMPONENTS filesystem)
...
# Link the Boost::filesystem target, which includes the Boost headers.
target_link_libraries(${PROJECT_NAME} PUBLIC
${CMAKE_THREAD_LIBS_INIT}
-lstdc++
-lpthread
Boost::filesystem
)
This will pull in the Boost headers as well, so you don't need an explicit call to target_include_directories() to specify where the Boost headers are.
Note: To ensure the headers are installed on your system, you may need to install boost-devel, in addition to your boost installation.

CMake error: linker command failed with exit code 1 and cpp.o files

I am using CMake to compile a small project.
Here is what I have written in CMakeLists.txt:
cmake_minimum_required(VERSION 3.2)
set (CMAKE_CXX_STANDARD 11)
project(DAF)
find_package(OpenCV REQUIRED)
include_directories(include)
include_directories(${OpenCV_INCLUDE_DIRS} )
file(GLOB Src_Sources "src/*.cpp")
file(GLOB Test_Sources "test/*.cpp")
add_executable(executable ${Src_Sources} ${Test_Sources})
target_link_libraries( executable include ${OpenCV_LIBS} )
I have two directories src and test. The src directory contains only the files that hold the functions, whereas the test directory contains the main file.
Once I use the cmake command and then the make command I get this error:
Scanning dependencies of target executation
[ 25%] Building CXX object CMakeFiles/executation.dir/src/image.cpp.o
[ 50%] Building CXX object CMakeFiles/executation.dir/test/starter_1.cpp.o
[ 75%] Linking CXX executable executation
ld: library not found for -linclude
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [executation] Error 1
make[1]: *** [CMakeFiles/executation.dir/all] Error 2
make: *** [all] Error 2
So what I find strange is that it creates .cpp.o files. Is that normal?
And then how do I fix the error library not found for -linclude?
Yes, it is normal for CMake to take the name of the source file, and append a .o when compiling the respective object files. For example, the source file image.cpp will be compiled into image.cpp.o. The Makefiles generated by CMake will contain a unique target <someSourceFileName>.o for each source file, where <someSourceFileName> can be a .cc, .cpp, .c, etc.
The error:
ld: library not found for -linclude
indicates that you have tried to link a library called include to the executable. This is likely not what you intend. It appears include is actually your include directory, and you have already specified the include directories in your CMake with this line:
include_directories(include)
To remove the error, just take out the include from the target_link_libraries() command, like so:
target_link_libraries( executable ${OpenCV_LIBS} )

link path confusion after target_link_libraries call

I have a cmake project where I want to add a class containing the matlab engine. For compiling it I need to include two libraries eng and mx, which I do by adding
target_link_libraries( ${TARGET} /usr/local/MATLAB/R2013b/bin/glnxa64/libeng.so)
target_link_libraries( ${TARGET} /usr/local/MATLAB/R2013b/bin/glnxa64/libmx.so)
to my CMakeLists.txt file.
However there are also lots of other old versions of libraries in /usr/local/MATLAB/R2013b/bin/glnxa64/, which seem
to be automatically added to the path as well when calling the above command. I think this causes the compiler to not find my
normal libraries anymore and produces an error.
How can I include only the two above libraries, and not all the others in the glnxa64 folder?
The warning shown after running cmake . :
CMake Warning at CMakeLists.txt:23 (add_executable):
Cannot generate a safe runtime search path for target CCDWidget because
files in some directories may conflict with libraries in implicit
directories:
runtime library [libboost_program_options.so.1.49.0] in /usr/lib may be hidden by files in:
/usr/local/MATLAB/R2013b/bin/glnxa64
runtime library [libboost_system.so.1.49.0] in /usr/lib may be hidden by files in:
/usr/local/MATLAB/R2013b/bin/glnxa64
runtime library [libboost_filesystem.so.1.49.0] in /usr/lib may be hidden by files in:
/usr/local/MATLAB/R2013b/bin/glnxa64
runtime library [libboost_regex.so.1.49.0] in /usr/lib may be hidden by files in:
/usr/local/MATLAB/R2013b/bin/glnxa64
Some of these libraries may not be found correctly.
And the error message during linking:
Linking CXX executable CCDWidget
/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0: undefined reference to `FT_Face_GetCharVariantIndex'
/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0: undefined reference to `FT_Get_Advance'
collect2: error: ld returned 1 exit status
make[2]: *** [CCDWidget] Error 1
make[1]: *** [CMakeFiles/CCDWidget.dir/all] Error 2
make: *** [all] Error 2
Below is my full CMakeLists.txt file. Lines commented out with two ## are alternatives that I tried before and didn't solve my problem.
I also added LINK_PRIVATE to the target_link_libraries command as shown in the code below, which didn't make a difference.
The option PRIVATE alone seems to be not accepted by my cmake version, as it changed the error meassage to
/usr/bin/ld: cannot find -lPRIVATE
collect2: error: ld returned 1 exit status
When the #eng line is commented out, the compilation and linking works without errors
(when calling the matlab engine is also commented out in Readout.cpp), so the error must be produced by that line.
#Specify the version being used as well as the language
cmake_minimum_required(VERSION 2.6)
##cmake_policy(SET CMP0003 NEW)
#Name your project here
project(CCDWidget)
set(TARGET CCDWidget)
set(MAIN_SOURCES CCDWidget.cpp main.cc CCDControl.cpp VideoWindow.cpp ImageWindow.cpp ThisMeasurement.cpp KineticSeries.cpp FastKinetics.cpp Readout.cpp)
##SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
#set_source_files_properties(Readout.cpp PROPERTIES COMPILE_FLAGS "-I/usr/local/MATLAB/R2013b/extern/include -I/usr/local/MATLAB/R2013b/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE -I/usr/local/MATLAB/R2013b/extern/include/cpp -I/usr/local/MATLAB/R2013b/extern/include -DGLNXA64 -DGCC -DMX_COMPAT_32 -DNDEBUG -Wno-effc++")
find_package(Boost COMPONENTS program_options system filesystem regex REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTKMM gtkmm-3.0)
include_directories( ${GTKMM_INCLUDE_DIRS} )
include_directories( ${Boost_INCLUDE_DIR} )
include_directories( ${PROJECT_SOURCE_DIR} )
##link_directories(/usr/local/MATLAB/R2013b/bin/glnxa64)
##target_link_libraries( ${TARGET} eng)
##target_link_libraries( ${TARGET} mx)
set(CMAKE_CXX_FLAGS "--std=c++11")
add_executable( ${TARGET} ${MAIN_SOURCES} )
target_link_libraries( ${TARGET} ${GTKMM_LIBRARIES} )
target_link_libraries( ${TARGET} ${Boost_LIBRARIES} )
target_link_libraries( ${TARGET} LINK_PRIVATE /usr/local/MATLAB/R2013b/bin/glnxa64/libeng.so) # eng
#target_link_libraries( ${TARGET} LINK_PRIVATE /usr/local/MATLAB/R2013b/bin/glnxa64/libmx.so ) # mx
target_link_libraries( ${TARGET} andor )
You could try using an imported target:
add_library(eng SHARED IMPORTED)
set_property(TARGET eng PROPERTY IMPORTED_LOCATION /usr/local/MATLAB/R2013b/bin/glnxa64/libeng.so)
...
add_executable( ${TARGET} ${MAIN_SOURCES} )
...
target_link_libraries(${TARGET} eng)
For debugging you could try to build with "make VERBOSE=1".
This will show you the used gcc command line.
CMake probably transforms your target_link_libraries command to something like:
g++ ... -L/usr/local/MATLAB/R2013b/bin/glnxa64 -leng ...
gcc then finds some boost libraries in this folder.

Building library with cmake

I apologize for bothering you all, but I have a little compilation problem with cmake.
I have a CMakeLists.txt file I'm using to build a test executable, and a shared library. They both have dependency to another library (SFML).
I'm using cmake on window with MinGW.
I know the name of the lib I'm building is kinda confusing with the sfml one, but it's supposed to be a SFML wrapper, so, I didn't find a better name!
Here the CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(projectName)
set(EXECUTABLE_NAME testSFML)
set(LIBRARY_NAME SFMLwindow)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include /
${CMAKE_CURRENT_SOURCE_DIR}/../../include
)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/)
file(
GLOB_RECURSE
SRC_FILES
src/*
)
file(
GLOB_RECURSE
INCLUDE_FILES
include/*
)
add_executable(
${EXECUTABLE_NAME}
main.cpp
${SRC_FILES}
${INCLUDE_FILES}
)
target_link_libraries(
${EXECUTABLE_NAME}
sfml-main
sfml-system
sfml-window
)
add_library(
${LIBRARY_NAME}
SHARED
${SRC_FILES}
)
And what I get in the terminal :
"C:\MinGW\bin\mingw32-make.exe"
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/iksemel/docs/WorkBench/programming/projets/TestSFML/cmake
Linking CXX shared library libSFMLwindow.dll
Creating library file: libSFMLwindow.dll.a
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x59):undefined reference to `_imp___ZN2sf9VideoModeC1Ejjj'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0xda): undefined reference to `_imp___ZN2sf6WindowC1ENS_9VideoModeERKSsjRKNS_15ContextSettingsE'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x163): undefined reference to `_imp___ZN2sf6Window5closeEv'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1bd): undefined reference to `_imp___ZN2sf6Window9pollEventERNS_5EventE'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1d8): undefined reference to `_imp___ZN2sf6Window7displayEv'
collect2: ld a retourné 1 code d'état d'exécution
mingw32-make.exe[2]: *** [libSFMLwindow.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles/SFMLwindow.dir/all] Error 2
mingw32-make.exe: *** [all] Error 2
If anybody have a clue on what's happening, I'd be very gratefull!
At a guess, your SFMLwindow library needs linked to some or all of sfml-main, sfml-system, sfml-window.
You could try changing the end of your CMakeLists.txt to:
add_library(
${LIBRARY_NAME}
SHARED
${SRC_FILES}
${INCLUDE_FILES}
)
add_executable(
${EXECUTABLE_NAME}
main.cpp
)
target_link_libraries(
${LIBRARY_NAME}
sfml-main
sfml-system
sfml-window
)
target_link_libraries(
${EXECUTABLE_NAME}
${LIBRARY_NAME}
)
As an aside, file(GLOB_RECURSE... is generally frowned upon as a way to gather a list of sources. From the docs for file:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
Also, find_library should be preferred to link_directories in this case. From the docs for link_directories:
Note that this command is rarely necessary. Library locations returned by find_package() and find_library() are absolute paths. Pass these absolute library file paths directly to the target_link_libraries() command. CMake will ensure the linker finds them.

Cmake target_link_libraries not linking my library

I'll begin stating that I'm almost complete dumb in Cmake matter.
I have the following CMakeLists.txt for a Kdevelop 4.1 project:
project(uart)
find_package(KDE4 REQUIRED)
include (KDE4Defaults)
include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} src/include src/include/QSerialDevce )
add_subdirectory(doc)
add_subdirectory(src)
add_subdirectory(icons)
link_directories(/usr/lib)
find_library(SERIALDEVICE_LIB qserialdeviced)
add_executable(uart ${uart_SRCS})
target_link_libraries(uart ${SERIALDEVICE_LIB})
When I try to build my project I see:
uart/build> make -j2
-- Found Qt-Version 4.6.3 (using /usr/bin/qmake-qt4)
-- Found X11: /usr/lib64/libX11.so
-- Found KDE 4.5 include dir: /usr/include/kde4
-- Found KDE 4.5 library dir: /usr/lib64/kde4/devel
-- Found the KDE4 kconfig_compiler4 preprocessor: /usr/bin/kconfig_compiler4
-- Found automoc4: /usr/bin/automoc4
CMake Error at CMakeLists.txt:16 (add_executable):
add_executable called with incorrect number of arguments
CMake Error: Attempt to add link library "/usr/lib/libqserialdeviced.so" to target "uart" which is not built by this project.
-- Configuring incomplete, errors occurred!
make: *** [cmake_check_build_system] Error 1
*** Failed ***
Everything I read says that add_executable and target_link_libraries should look like the last two lines of my file:
add_executable(uart ${uart_SRCS})
target_link_libraries(uart ${SERIALDEVICE_LIB})
If I change those two lines of CMakeLists.txt leaving it as:
project(uart)
find_package(KDE4 REQUIRED)
include (KDE4Defaults)
include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} src/include src/include/QSerialDevce )
add_subdirectory(doc)
add_subdirectory(src)
add_subdirectory(icons)
link_directories(/usr/lib)
find_library(SERIALDEVICE_LIB qserialdeviced)
target_link_libraries(${SERIALDEVICE_LIB})
I see:
uart/build> make -j2
-- Found Qt-Version 4.6.3 (using /usr/bin/qmake-qt4)
-- Found X11: /usr/lib64/libX11.so
-- Found KDE 4.5 include dir: /usr/include/kde4
-- Found KDE 4.5 library dir: /usr/lib64/kde4/devel
-- Found the KDE4 kconfig_compiler4 preprocessor: /usr/bin/kconfig_compiler4
-- Found automoc4: /usr/bin/automoc4
-- Configuring done
-- Generating done
-- Build files have been written to: uart/build
[ 11%] Built target doc-handbook
[ 11%] Built target uart_automoc
Linking CXX executable uart
CMakeFiles/uart.dir/uart.o: In function `uart::setupSerial()':
uart/src/uart.cpp:126: undefined reference to `AbstractSerial::AbstractSerial(QObject*)'
CMakeFiles/uart.dir/uart.o: In function `uart::setupEnumerator()':
uart/src/uart.cpp:108: undefined reference to `SerialDeviceEnumerator::SerialDeviceEnumerator(QObject*)'
CMakeFiles/uart.dir/uart.o: In function `uart::setupSerial()':
uart_/uart/src/uart.cpp:136: undefined reference to `AbstractSerial::enableEmitStatus(bool)'
CMakeFiles/uart.dir/uart.o: In function `uart::setupEnumerator()':
uart_/uart/src/uart.cpp:112: undefined reference to `SerialDeviceEnumerator::setEnabled(bool)'
collect2: ld returned 1 exit status
make[2]: *** [src/uart] Error 1
make[1]: *** [src/CMakeFiles/uart.dir/all] Error 2
make: *** [all] Error 2
*** Failed ***
That clearly shows that target_link_libraries is not linking my qserialdeviced.
qserialdeviced is at /usr/lib/libqserialdeviced.so.1.0.0, correctly simlinked to /usr/lib/libqserialdeviced.so and easily found if I manually add it in the Makefile.
I obviously tried:
target_link_libraries(-lqserialdeviced)
with no change.
I also tried:
if ("${SERIALDEVICE_LIB}" STREQUAL "SERIALDEVICE_LIB-NOTFOUND")
message(FATAL_ERROR "'qserialdeviced' wasn't found!")
else()
message("'qserialdeviced' found: " ${SERIALDEVICE_LIB})
endif ()
But this test succeeds. The library is found:
'qserialdeviced' found: /usr/lib/libqserialdeviced.so
Can anybody please help me to understand what happens here?
I am using Linux Fedora 13, cmake version 2.8.0, gcc (GCC) 4.4.5 20101112 (Red Hat 4.4.5-2) and kdevelop-4.1.0-1.fc13.x86_64.
Thanks i advance.
EDIT:
As suggested by #DatChu, I split my CMakeLists.txt across my subdirectories and everything makes sense to me now.
Thanks everbody!
For the original CMakeLists.txt file, the problem is not with target_link_libraries but with add_executable
add_executable(uart ${uart_SRCS})
where did you set your uart_SRCS variable? Do you have
set(uart_SRCS src/blahblah.cpp src/somethingblahblah.cpp)
I think you might misunderstand what add_subdirectory does. It does not add the source files inside. It tells CMake to descend into that folder and look for another CMakeLists.txt. You typically use it when you have a sub-project inside of your project folder.
If you have many source files which you don't want to manually set, you can also do
file(GLOB uart_SRCS src/*.cpp src/*.c)
The downside is you need to manually re-run CMake in order for it to detect new files. See Jack's comment on why this might not be what you want to use.
Your CMakeLists.txt will most likely be
project(uart)
find_package(Qt4 REQUIRED)
include (${QT_USE_FILE})
find_package(KDE4 REQUIRED)
include (KDE4Defaults)
include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} src/include src/include/QSerialDevice )
link_directories(/usr/lib)
file(GLOB uart_SRCS src/*.cpp src/*.h)
file(GLOB uart_HDRS include/*.h include/QSerialDevice/*.h)
find_library(SERIALDEVICE_LIB qserialdeviced)
add_executable(uart ${uart_SRCS} ${uart_HDRS})
target_link_libraries(uart ${SERIALDEVICE_LIB} ${QT_LIBRARIES})
This isn't really a direct solution, but I was having such difficulty with "undefined reference" errors (solved previously by linking the appropriate libraries, but not in this case), until I just discovered something - an incompatibility with c vs cpp somehow. The files that defined these reference functions were in .c files (which would default cmake to compile with a C compiler.) and my file referencing these functions is a .cpp file (using g++ compiler or whatever your environment c++ compiler is). Once I changed the .c file to .cpp the "undefined reference" errors disappeared. Above it looks like your uart file is .cpp, but maybe check what the other files are and try this method. It's probably not the appropriate solution or even one at all, but this might get you through the day and moving forward.