Linker error when using GRPC
Closed this issue · 5 comments
When I try to create a grpc service in an other catkin package, I have to manually add ".... /devel/lib/libgrpc++_unsecure.so" to target_link_libraries in the corresponding CMakeLists.txt. Otherwise I get a linker error when building the package.
That's very strange. This library should be automatically linked already: see
Do you have "GRPC" in your generate_proto
statement. Do you mind sharing your CMakeLists with us?
The proto files are generated in an other package.
package with service:
cmake_minimum_required(VERSION`
2.8.3)
project(corbslam_server)
IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Release)
ENDIF ()
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native ")
# Check C++11 or C++0x support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if (COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions(-DCOMPILEDWITHC11)
message(STATUS "Using flag -std=c++11.")
elseif (COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_definitions(-DCOMPILEDWITHC0X)
message(STATUS "Using flag -std=c++0x.")
else ()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif ()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules")
## 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
rospy
std_msgs
message_generation
tf
corbslam_client
grpc
)
find_package(OpenCV REQUIRED)
find_package(Eigen3 3.1.0 REQUIRED)
find_package(Pangolin REQUIRED)
find_package(Boost COMPONENTS serialization system filesystem REQUIRED)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES orbslam_server
# CATKIN_DEPENDS roscpp rospy std_msgs
# DEPENDS system_lib
CATKIN_DEPENDS message_runtime corbslam_client
)
include_directories(
${catkin_INCLUDE_DIRS}
${Boost_INCLUDE_DIR}
${EIGEN3_INCLUDE_DIR}
${Pangolin_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/include
)
set(corbslam_server_SOURCES
${PROJECT_SOURCE_DIR}/src/MapFusion.cpp
${PROJECT_SOURCE_DIR}/src/main.cpp
${PROJECT_SOURCE_DIR}/src/ServerMap.cpp
${PROJECT_SOURCE_DIR}/src/ServerMapView.cpp
${PROJECT_SOURCE_DIR}/src/PubToClient.cpp
${PROJECT_SOURCE_DIR}/src/GlobalOptimize.cpp
)
add_executable(corbslam_server
${corbslam_server_SOURCES}
)
target_link_libraries(corbslam_server
${catkin_LIBRARIES}
${Boost_LIBRARIES}
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
/home/fabian/SLAM/ws/devel/lib/libgrpc++_unsecure.so
)
client package with proto file:
cmake_minimum_required(VERSION 2.8)
project(corbslam_client)
IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Release)
ENDIF ()
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3 -march=native ")
# Check C++11 or C++0x support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if (COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions(-DCOMPILEDWITHC11)
message(STATUS "Using flag -std=c++11.")
elseif (COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_definitions(-DCOMPILEDWITHC0X)
message(STATUS "Using flag -std=c++0x.")
else ()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif ()
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
cv_bridge
std_msgs
tf
message_generation
genmsg
pcl_conversions
pcl_ros
grpc
)
find_package(OpenCV REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(Pangolin REQUIRED)
find_package(Boost COMPONENTS serialization system filesystem REQUIRED)
## Generate messages in the 'msg' folder
add_message_files(
DIRECTORY msg
FILES
corbslam_message.msg
)
## Generate services in the 'srv' folder
add_service_files(
DIRECTORY srv
FILES
corbslam_insert.srv
corbslam_update.srv
)
## Generate actions in the 'action' folder
# add_action_files(
# FILES
# Action1.action
# Action2.action
# )
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
)
generate_proto(corb_proto GRPC proto/corbslam.proto)
catkin_package(
INCLUDE_DIRS include
LIBRARIES corbslam_client corb_proto
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime grpc
)
include_directories(
${catkin_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/include
${EIGEN3_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
${Pangolin_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
## Declare a C++ library
LINK_DIRECTORIES(/usr/local/lib )
add_library(${PROJECT_NAME}
src/System.cc
src/Tracking.cc
src/LocalMapping.cc
src/LoopClosing.cc
src/ORBextractor.cc
src/ORBmatcher.cc
src/FrameDrawer.cc
src/Converter.cc
src/MapPoint.cc
src/KeyFrame.cc
src/Map.cc
src/MapDrawer.cc
src/Optimizer.cc
src/PnPsolver.cc
src/Frame.cc
src/KeyFrameDatabase.cc
src/Sim3Solver.cc
src/Initializer.cc
src/Viewer.cc
include/Cache.h
src/Cache.cc
include/LightKeyFrame.h
src/LightKeyFrame.cc
include/LightMapPoint.h
src/LightMapPoint.cc
include/SerializeObject.h
include/DataDriver.h
src/DataDriver.cc
include/TransPose.h
src/TransPose.cpp
src/ProtoConversions.cpp)
target_link_libraries(${PROJECT_NAME}
${OpenCV_LIBRARIES}
${catkin_LIBRARIES}
${EIGEN3_LIBRARIES}
${Pangolin_LIBRARIES}
${Boost_LIBRARIES}
corb_proto
)
add_dependencies(corbslam_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
Thank you. I was able to reproduce the issue. The problem is that when catkin_package exports libraries, it doesn't export the dependencies automatically. As a workaround, you can use the following code in your client package with proto:
find_package(catkin REQUIRED COMPONENTS grpc)
set(GRPC_LIB_DIR ${grpc_PREFIX}/${CATKIN_GLOBAL_LIB_DESTINATION})
find_library(
LIBPROTOBUF libprotobuf.a PATHS ${GRPC_LIB_DIR}/protobuf NO_DEFAULT_PATH)
find_library(LIBZ z PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
set(ALL_PROTOBUF_LIBS ${LIBPROTOBUF} ${LIBZ})
message(STATUS "Found protobuf libraries: ${ALL_PROTOBUF_LIBS}")
find_library(LIBARES ares PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBBORINGSSL boringssl PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGPR gpr PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPC grpc PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPCPP grpc++ PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPC_CRONET grpc_cronet PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPCPP_CORE_STATS grpc++_core_stats
PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPCPP_CRONET grpc++_cronet
PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPCPP_ERROR_DETAILS grpc++_error_details
PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPC_PLUGIN_SUPPORT grpc_plugin_support
PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPCPP_REFLECTION grpc++_reflection
PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPC_UNSECURE grpc_unsecure
PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
find_library(LIBGRPCPP_UNSECURE grpc++_unsecure
PATHS ${GRPC_LIB_DIR} NO_DEFAULT_PATH)
set(ALL_GRPC_LIBS ${LIBARES} ${LIBBORINGSSL} ${LIBGPR} ${LIBGRPC} ${LIBGRPCPP}
${LIBGRPC_CRONET} ${LIBGRPCPP_CRONET} ${LIBGRPCPP_CORE_STATS}
${LIBGRPCPP_ERROR_DETAILS} ${LIBGRPC_PLUGIN_SUPPORT} ${LIBGRPCPP_REFLECTION}
${LIBGRPC_UNSECURE} ${LIBGRPCPP_UNSECURE})
message(STATUS "Found grpc libraries: ${ALL_GRPC_LIBS}")
catkin_package(
CATKIN_DEPENDS grpc
LIBRARIES ${ALL_GRPC_LIBS} ${ALL_PROTOBUF_LIBS}
)
I will dig deeper into this to see what is the best way to handle this case.
Thank you very much for your prompt answers and the workaround!
In fact, all you need is
find_package(catkin REQUIRED COMPONENTS grpc)
catkin_package(
CATKIN_DEPENDS grpc
LIBRARIES ${ALL_GRPC_LIBS} ${ALL_PROTOBUF_LIBS}
)
I will update the README to reflect this.