undefined reference to ... when compiling ros node - c++

I'm trying to write a ROS-Node which uses OpenCV nonfree components (SURF). I have trouble compiling the package using catkin_make:
//usr/local/lib/libopencv_nonfree.so: undefined reference to `cv::ocl::integral(cv::ocl::oclMat const&, cv::ocl::oclMat&)'
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(homography_test)
## Find catkin macros and libraries
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
sensor_msgs
cv_bridge
image_transport
)
catkin_package(
)
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
# include_directories(include)
include_directories(
${catkin_INCLUDE_DIRS}
/usr/local/include
/usr/include
/usr/include/gstreamer-1.0
/usr/include/glib-2.0
/usr/lib/x86_64-linux-gnu/glib-2.0/include
)
## Declare a cpp executable
#add_executable(display_image src/display_image_node.cpp)
add_executable(homography src/sample.cpp)
## Add cmake target dependencies of the executable/library
## as an example, message headers may need to be generated before nodes
#add_dependencies(homography_test homography_test_generate_messages_cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(
homography
${catkin_LIBRARIES}
gstreamer-1.0
gobject-2.0
glib-2.0
opencv_nonfree
opencv_calib3d
opencv_contrib
opencv_core
opencv_features2d
opencv_flann
opencv_gpu
opencv_highgui
opencv_imgproc
opencv_legacy
opencv_ml
opencv_objdetect
opencv_ocl
opencv_photo
opencv_stitching
opencv_superres
opencv_ts
opencv_video
opencv_videostab
rt
pthread
m
dl
)
link_directories(/usr/local/lib)
But if I manually compile the same code, but not as ROS-node, everything works.

It seems that the opencv_ocl library is not being linked properly. Also, you can simplify your CMakeLists.txt file a lot by using find_package to get your OpenCV configuration. Try adding those lines to your CMakeLists.txt file:
find_package(OpenCV REQUIRED core ocl)
include_directories(SYSTEM ${OpenCV_INCLUDE_DIRS})
target_link_libraries(homography ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} )
You need to specify which OpenCV libraries you want to include in the find_package. I listed only core and ocl since ocl seems to be what you need, but others might be needed as well.

Related

ROS CPP Snap7 Linux - CMake does not link against lib

I would like to use Snap7 ( Multi-platform Ethernet S7 PLC communication suite) to establish a communication between ROS and a Siemens S7 1500.
I encountered a linker problem - Although I can find the includes and the library .so file itself, using a custom FindLibSnap7.cmake, target_link_libraries is not linking against snap7 library. Here my approach and the outputs helping debugging:
(Note: Currently we are forced to use ROS Kinetic, so using the Snap7 Python wrapper seems like not an option cause its written in python3.)
I installed the library:
sudo add-apt-repository ppa:gijzelaar/snap7
sudo apt-get update
sudo apt-get install libsnap71 libsnap7-dev
Result:
$ ll /usr/lib/libsnap7.so
-rwxr-xr-x 1 root root 305944 Apr 24 22:18 /usr/lib/libsnap7.so*
$ ll /usr/include/snap7.h
-rw-r--r-- 1 root root 41954 Jun 2 2015 /usr/include/snap7.h
FindLibSnap7.cmake:
# find libsnap7
#
# exports:
#
# LibSNAP7_FOUND
# LibSNAP7_INCLUDE_DIRS
# LibSNAP7_LIBRARIES
#
find_package(PkgConfig REQUIRED)
# Use pkg-config to get hints about paths
#pkg_check_modules(LibSNAP7_PKGCONF REQUIRED libsnap7)
# Include dir
find_path(LibSNAP7_INCLUDE_DIR
NAMES snap7.h
PATHS ${LibSNAP7_PKGCONF_INCLUDE_DIRS}
)
find_library(
LibSNAP7_LIBRARY
NAMES snap7 libsnap7
PATHS /usr/lib
# PATH_SUFFIXES lib
# NO_DEFAULT_PATH
)
#FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSNAP7 DEFAULT_MSG LibSNAP7_LIBRARY LibSNAP7_INCLUDE_DIR)
message("LibSNAP7_INCLUDE_DIR ${LibSNAP7_INCLUDE_DIR}")
message("LibSNAP7_LIBRARY ${LibSNAP7_LIBRARY}")
set(LibSnap7_LIBRARIES ${LibSNAP7_LIBRARY})
set(LibSnap7_INCLUDE_DIRS ${LibSNAP7_INCLUDE_DIR})
set(LibSnap7_FOUND yes)
# Set the include dir variables and the libraries and let libfind_process do the rest.
# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
#set(LibSNAP7_PROCESS_INCLUDES LibSNAP7_INCLUDE_DIR)
#set(LibSNAP7_PROCESS_LIBS LibSNAP7_LIBRARY)
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.3)
project(agv_snap7_driver)
set(CMAKE_VERBOSE_MAKEFILE ON)
## Compile as C++11, supported in ROS Kinetic and newer
add_compile_options(-std=c++11)
##########################################################################################
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
MESSAGE( STATUS "CMAKE_MODULE_PATH: " ${CMAKE_MODULE_PATH} )
find_package(LibSnap7 REQUIRED)
include_directories(${LibSnap7_INCLUDE_DIRS})
message("LibSnap7_LIBRARIES ${LibSnap7_LIBRARIES}")
message("LibSnap7_INCLUDE_DIRS ${LibSnap7_INCLUDE_DIRS}")
##########################################################################################
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
roscpp
nodelet
agv_utils
agv_msgs
)
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS ${THIS_PACKAGE_ROS_DEPS}
DEPENDS LibSnap7
)
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
include
${catkin_INCLUDE_DIRS}
${LibSnap7_INCLUDE_DIRS}
)
## Declare a C++ library
add_library(${PROJECT_NAME}
src/agv_snap7_driver_config.cpp
src/agv_snap7_driver.cpp
)
## Add cmake target dependencies of the executable
add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
target_link_libraries( ${PROJECT_NAME} ${catkin_LIBRARIES} ${LibSnap7_LIBRARIES})
#############
## Install ##
#############
## Mark libraries for installation
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
)
## Mark cpp header files for installation
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
install(FILES nodelet.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
FILES_MATCHING PATTERN "*.launch"
PATTERN ".svn" EXCLUDE
)
install(DIRECTORY config/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/config
FILES_MATCHING PATTERN "*.yaml"
PATTERN ".svn" EXCLUDE
)
catkin_make output:
-- +++ processing catkin package: 'agv_snap7_driver'
-- ==> add_subdirectory(agv_base_hardware/agv_snap7_driver)
-- CMAKE_MODULE_PATH: /home/twobit/workspaces/bestvc_ws/branches/Gestamp_Amorebieta_01/base/src/agv_base_hardware/agv_snap7_driver/cmake
LibSNAP7_INCLUDE_DIR /usr/include
LibSNAP7_LIBRARY /usr/lib/libsnap7.so
LibSnap7_LIBRARIES /usr/lib/libsnap7.so
LibSnap7_INCLUDE_DIRS /usr/include
lld output
$ ldd libagv_snap7_driver.so | grep snap
libsnappy.so.1 => /usr/lib/x86_64-linux-gnu/libsnappy.so.1 (0x00007fe89c01e000)
So as you can see the includes are found, as well the library. Providing ${LibSnap7_LIBRARIES} to target_link_libraries is not linking agains libsnap7.so
After installing snap7 from source I found the example cpp's are linked correctly.
When anyone has an idea why this incorrect link is happening I would be happy for any help.
Thank you in advance!

Namespace error with ROS and OpenCV4's DNN module

I am encountering a namespace issue when using ROS, OpenCV's dnn module, and CLion. The issue seems to be exclusive to the DNN module, as the other ROS and OpenCV functions work fine. While my code seems to compile and build fine, I am getting the lint error: No member named readNetFromDarknet in namespace 'cv::dnn'. The error happens everywhere I am accessing anything in the DNN module.
Defined in my header file:
cv::dnn::Net net;
yields the error No type named Net in namespace 'cv::dnn'.
Defined in my class file:
void HumanDetector::setupNetwork() {
net = cv::dnn::readNetFromDarknet(MODEL_CONFIG, MODEL_WEIGHTS);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
}
yields a similar problem.
In CLion, however, I can Ctrl+Click any of the alleged undefined members or types and see the source code for them. I suspect that it might have something to do with my CMakeLists config or IDE setup. Here is my cmake file:
cmake_minimum_required(VERSION 2.8.3)
project(followbot)
## Compile as C++11, supported in ROS Kinetic and newer
add_compile_options(-std=c++11)
set(CATKIN_ENABLE_TESTING OFF)
set(OpenCV_LIBRARY_DIR /usr/local/lib)
set(OpenCV_DIR "/usr/local/lib")
## Find catkin macros and libraries
find_package(OpenCV 4.1.2 REQUIRED PATHS /usr/local NO_DEFAULT_PATH)
find_package(catkin REQUIRED COMPONENTS
roscpp
geometry_msgs
std_msgs
message_generation
teb_local_planner
)
add_message_files(
FILES
Point2.msg
)
generate_messages(
DEPENDENCIES
)
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
INCLUDE_DIRS include
CATKIN_DEPENDS
roscpp
message_generation
message_runtime
std_msgs
geometry_msgs
teb_local_planner
DEPENDS OpenCV
)
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
include
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
)
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(${PROJECT_NAME} src/node.cpp src/cloud.cpp src/human.cpp)
## Link the executable to the OpenCV libraries
link_directories(${OpenCV_LIBRARY_DIR})
target_link_libraries(followbot ${OpenCV_LIBRARIES} ${catkin_LIBRARIES})

ROS catkin build - cannot find shared library

I am trying to catkin build this ROS package https://github.com/toddhester/rl-texplore-ros-pkg but it fails to build 'rl_experiment' with the following error:
/usr/bin/ld: cannot find -lagentlib
/usr/bin/ld: cannot find -lenvlib
collect2: error: ld returned 1 exit status
I am using ROS Kinetic. The shared libraries does exist in the folders /texplore/devel/.private/rl_env/lib/ and /texplore/devel/.private/rl_agent/lib/ with symlinks at /texplore/devel/lib/
I tried the following:
(1) export /texplore/devel/lib/ to LD_LIBRARY_PATH
(2) adding symlinks to the libraries in /texplore/src/rl_experiment/src
(3) adding the library paths to target_link_libraries
target_link_libraries(experiment agentlib envlib ${catkin_LIBRARIES}
"/media/usr/texplore/devel/lib/libagentlib.so"
"/media/usr/texplore/devel/lib/libenvlib.so")
(4) set the search path for linker
SET(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,/media/usr/texplore/devel/lib/")
It didn't work. Lastly, I added the symlinks to /usr/local/lib and it worked. But I do not want the symlinks in this folder.
So the linker is simply not searching the build tree. My question is, why did catkin not add the linker path in catkin_LIBRARIES? I have built ROS packages before but can't wrap my head around why this particular package is not working.
I ran into the same issue. I made the following changes based on this post on ROS Answers and the below comment in the generic CMakeLists.txt file for the catkin_packages macro:
## LIBRARIES: libraries you create in this project that dependent projects also need
I did a few things to fix this...
Added
LIBRARIES agentlib to the catkin_packages macro in the rl_agent/CMakeLists.txt file. This makes the agentlib library available later to rl_experiment.
Added LIBRARIES envlib to the catkin_packages macro in the rl_env/CMakeLists.txt file. This makes the envlib library available later to rl_experiment.
Removed agentlib and envlib from the target_link_libraries macro in the rl_experiment/CMakeLists.txt file. These are not necessary.
Verified rl_agent and rl_env packages are listed in the find_package macro of the rl_experiment/CMakeLists.txt.
...then everything successfully compiled.
Adding snippets for further clarification...
rl_agent CMakeLists.TXT Changes (item 1 above):
...
## Declare a cpp library
# add_library(rgbd_tools
# src/${PROJECT_NAME}/
# )
add_library(agentlib
src/Agent/DiscretizationAgent.cc
src/Agent/QLearner.cc
...
src/newmat/newmatrm.cc
src/newmat/newmat9.cc
)
## Declare a cpp executable
# add_executable(rgbd_tools_node src/rgbd_tools_node.cpp)
...
rl_env CMakeLists.txt Changes (item 2 above):
...
###################################
## catkin specific configuration ##
###################################
...
catkin_package(
INCLUDE_DIRS include
LIBRARIES envlib
# CATKIN_DEPENDS roscpp rospy std_msgs
CATKIN_DEPENDS message_runtime
# DEPENDS system_lib
)
...
rl_experiment CMakeLists.txt Changes (items 3 & 4 above):
...
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
rl_common
rl_env
rl_agent
)
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
...
## Declare a cpp executable
# add_executable(rgbd_tools_node src/rgbd_tools_node.cpp)
add_executable(experiment src/rl.cc)
# target_link_libraries(experiment agentlib envlib ${catkin_LIBRARIES})
target_link_libraries(experiment ${catkin_LIBRARIES})
#add_executable(image_converter src/image_converter.cpp)
...

Add lib*.so to cmake

I've my package with CMakeLists.txt and I have a libNewLib.so compiled from another package from another library (NewLib). I've also the header files of that library that I include like so:
set(LIB_MANUALLY "${CMAKE_CURRENT_SOURCE_DIR}/lib/") #I put the file libNewLib.so here
include_directories(
include/NewLib
)
LINK_DIRECTORIES(${LIB_MANUALLY})
target_link_libraries(estimation libNewLib.so)
But I still get the error:
/usr/bin/ld: cannot find -lNewLib
Is it the correct way to do it?
I tried a couple of solutions but it didn't work.
I'm using Ros kinetic catkin package
make VERSION 2.8.3
Full CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.3)
project(localization)
add_compile_options(-std=c++11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Ofast -march=native")
set(LIB_MANUALLY "${CMAKE_CURRENT_SOURCE_DIR}/lib/")
message(STATUS "LIB_MANUALLY : ${LIB_MANUALLY}")
find_package(catkin REQUIRED COMPONENTS
cv_bridge
image_transport
roscpp
rospy
std_msgs
)
find_package(OpenCV REQUIRED
NO_MODULE # should be optional, tells CMake to use config mode
PATHS /usr/local # look here
NO_DEFAULT_PATH) # and don't look anywhere else
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES localization
CATKIN_DEPENDS cv_bridge image_transport roscpp rospy std_msgs
# DEPENDS system_lib
)
include_directories(
include
include/NewLib
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
)
add_executable(estimation
src/pose_map_estimation.cpp
src/pose_map_estimation_main.cpp
)
target_link_libraries(estimation ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} libNewLib.so)
LINK_DIRECTORIES(${LIB_MANUALLY})
In https://cmake.org/cmake/help/v3.0/command/link_directories.html it says:
Specify the paths in which the linker should search for libraries. The command will apply only to targets created after it is called.
So, try if it works if you create the target AFTER the link_directories command.
You could also consider to write a proper cmake file for locating your library and use find_package to find it.

Linking to boost

I am trying to link to the boost libraries for a ros node, in connection I found the following links: "How to include external library (boost) into CLion C++ project with CMake?" and "How to link C++ program with Boost using CMake" and "problem building in groovy with catkin and boost".
As a result I create my CMakelists.txt as follows which needs to use OpenCV and Boost:
cmake_minimum_required(VERSION 2.8.3)
project(image_listener_rosbag)
#set(Boost_USE_STATIC_LIBS OFF)
#set(Boost_USE_MULTITHREADED ON)
#set(Boost_USE_STATIC_RUNTIME OFF)
## Find catkin macros and libraries
find_package(catkin REQUIRED COMPONENTS
cv_bridge
image_transport
message_generation
roscpp
sensor_msgs
std_msgs
)
add_message_files(
FILES
)
generate_messages(
DEPENDENCIES
std_msgs
sensor_msgs
)
catkin_package(
CATKIN_DEPENDS message_runtime
)
find_package(catkin REQUIRED)
find_package(OpenCV REQUIRED)
find_package( Boost REQUIRED COMPONENTS serialization archive ) # is this correct?
# The components included are chosen because I need to use the following usings:
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/split_free.hpp>
include_directories(
${OpenCV_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
)
link_directories(${Boost_LIBRARY_DIR})
add_library(image_listener_rosbag src/image_listener.cpp)
add_dependencies(image_listener_rosbag ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_executable(image_listener_rosbag_node src/image_listener.cpp)
target_link_libraries(image_listener_rosbag_node ${OpenCV_LIBRARIES} ${catkin_LIBRARIES} ${Boost_LIBRARIES})#
When I try to build it suddenly another package relying on PCL crashes with:
-- Configuring incomplete, errors occurred!
See also "/home/johann/catkin_ws/build/CMakeFiles/CMakeOutput.log".
See also "/home/johann/catkin_ws/build/CMakeFiles/CMakeError.log".
make: *** [cmake_check_build_system] Error 1
Looking into the CMakeError.log Complains about not finding pthread_create. The PCL package that crashes has no reference to boost other than what PCL has inside. Should I add boost explicitly in the failing package as above? Tried: adding the information about boost from above to the PCL node, I get the same error log referencing the missing pthread_create.
As a test I have tried editing the code above in several ways if remove all the boost references from the code above, both packages are build and runs with no issue.
If I remove find_package(Boost ... I receive a lot of issues like: undefined reference to boost::archive::detail::basic_oarchive::~basic_oarchive()` But the PCL node compiles fine with no issue.
Question: Am I adding boost correctly and the libraries?
If so is there some issue when including PCL in another package that you need a special reference?
System: For reference I am implementing it using ros indigo full, with the included opencv(2.4) and pcl(looks like 1.54 libraries), everything is on Ubuntu 14.04.
Extra
This question, "PCL install links directly to boost installation directory somehow", seems to have some of the same issues I have however not been able to transfer the suggestions yet.
PCL node
The below node is the one exhibiting the error when the boost includes are added above.
cmake_minimum_required(VERSION 2.8.3)
project(pointcloudlistener)
find_package(PCL REQUIRED)
find_package(catkin REQUIRED COMPONENTS
cv_bridge
image_transport
PCL
pcl_ros
roscpp
sensor_msgs
std_msgs
)
add_message_files(
FILES
)
generate_messages(
DEPENDENCIES
std_msgs
sensor_msgs
)
catkin_package(
CATKIN_DEPENDS message_runtime
)
find_package(catkin REQUIRED)
find_package(OpenCV REQUIRED)
find_package(PCL REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS} ${PCL_INCLUDE_DIRS})
link_directories(
${PCL_LIBRARY_DIRS}
)
add_library(pointcloudlistener src/pcl_listener.cpp src/matPclConverter.cpp src/Image_Safety.cpp)
add_dependencies(pointcloudlistener ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_executable(pointcloudlistener_node src/pcl_listener.cpp src/matPclConverter.cpp src/Image_Safety.cpp)
target_link_libraries(pointcloudlistener_node ${OpenCV_LIBRARIES} ${catkin_LIBRARIES} ${PCL_LIBRARIES})