0

I'll try to describe this issue the best I can. I'm trying to catkin_make a multi-package c++ project, but I'm getting a couple linker issues when its trying to build executables for 2 of the packages.

The error:

forge/devel/lib/libforge_features.so: undefined reference to `ErrorClientKeeper::addError(ForgeError::Severity, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)'
collect2: error: ld returned 1 exit status
forge_feature_identification/CMakeFiles/feature_identification_service_node.dir/build.make:224: recipe for target '/home/brian-pc/forge/devel/lib/forge_feature_identification/feature_identification_service_node' failed
make[2]: *** [/home/brian-pc/forge/devel/lib/forge_feature_identification/feature_identification_service_node] Error 1
CMakeFiles/Makefile2:8322: recipe for target 'forge_feature_identification/CMakeFiles/feature_identification_service_node.dir/all' failed
make[1]: *** [forge_feature_identification/CMakeFiles/feature_identification_service_node.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
CMakeFiles/part_manager_node.dir/src/part.cpp.o: In function `Part::read(int)':
part.cpp:(.text+0x88f): undefined reference to `ErrorClientKeeper::addError(ForgeError::Severity, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)'
part.cpp:(.text+0x102b): undefined reference to `ErrorClientKeeper::addError(ForgeError::Severity, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)'
CMakeFiles/part_manager_node.dir/src/part.cpp.o: In function `Part::createFromTemplate(int)':
part.cpp:(.text+0x137d): undefined reference to `ErrorClientKeeper::addError(ForgeError::Severity, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)'
part.cpp:(.text+0x1a21): undefined reference to `ErrorClientKeeper::addError(ForgeError::Severity, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool)'
collect2: error: ld returned 1 exit status
forge_part_manager/CMakeFiles/part_manager_node.dir/build.make:172: recipe for target '/home/brian-pc/forge/devel/lib/forge_part_manager/part_manager_node' failed
make[2]: *** [/home/brian-pc/forge/devel/lib/forge_part_manager/part_manager_node] Error 1
CMakeFiles/Makefile2:9105: recipe for target 'forge_part_manager/CMakeFiles/part_manager_node.dir/all' failed
make[1]: *** [forge_part_manager/CMakeFiles/part_manager_node.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2

feature_identification_service_node and part_manager_node are the exes its trying to build. The function its trying to reference is a static function is a package called forge_errors declared in file error_client_keeper.h. Here is the header file for that:

#ifndef __ERROR_CLIENT_KEEPER_H_INCLUDED__
#define __ERROR_CLIENT_KEEPER_H_INCLUDED__

#include <ros/ros.h>

#include <forge_errors/Error.h>
#include <forge_errors/forge_error.h>
#include <forge_errors/alert_service.h>
#include <forge_errors/error_client.h>

class ErrorClientKeeper
{
public:

  static bool addError(ForgeError err);
  static bool addError(ForgeError::Severity severity, std::string msg, std::string caller = "", bool display = true);

private:
  ErrorClientKeeper();
  ~ErrorClientKeeper(){};

};

#endif

The .cpp file:

#include <forge_errors/error_client_keeper.h>

bool addError(ForgeError err)
{
  ros::NodeHandle nh;

  ErrorClient client(nh);

  bool success = client.addError(err);

  ros::spinOnce();

  return success;
}
bool addError(ForgeError::Severity severity, std::string msg, std::string caller = "", bool display = true)
{
  ros::NodeHandle nh;

  ErrorClient client(nh);

  bool success = client.addError(severity, msg, caller, display);

  ros::spinOnce();

  return success;
}

forge error is a class also in the forge_errors package, in forge_error.h

Here's the feature_identification package's cmakelists.txt

cmake_minimum_required(VERSION 2.8.3)
project(forge_feature_identification)

find_package(catkin REQUIRED COMPONENTS
  forge_msgs
  forge_features
  roscpp
  rospy
  actionlib
  actionlib_msgs
)

###################################
## catkin specific configuration ##
###################################

catkin_package(
 CATKIN_DEPENDS
  forge_msgs
  forge_features
  roscpp
  rospy
  actionlib
  actionlib_msgs
)

###########
## Build ##
###########

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

add_executable(
  feature_identification_service_node
  src/feature_identification_service_node.cpp
  src/feature_identification_service.cpp
  src/feature_identifier.cpp
  src/seam_identifier.cpp
  src/part_model_identifier.cpp
)
target_link_libraries(
  feature_identification_service_node
  ${catkin_LIBRARIES}
)
 add_dependencies(
  feature_identification_service_node
  ${catkin_EXPORTED_TARGETS}
)

#############
## Install ##
#############

# Mark cpp header files for installation
install(DIRECTORY include/${PROJECT_NAME}/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.h"
  PATTERN ".svn" EXCLUDE
)

Here's part_manager_node's cmakelist.txt

project(forge_part_manager)

## Find catkin macros and libraries
find_package(catkin REQUIRED COMPONENTS
  forge_db_manager
  forge_utils
  forge_msgs
  forge_features
  forge_feature_identification
  actionlib
  roscpp
  forge_errors
  rospy
  std_msgs
)

###################################
## catkin specific configuration ##
###################################
catkin_package(
 # INCLUDE_DIRS include
 # LIBRARIES forge_part_manager
 CATKIN_DEPENDS
  forge_db_manager
  forge_utils
  forge_features
  forge_feature_identification
  roscpp
  rospy
  std_msgs
  forge_errors
  actionlib
#  DEPENDS system_lib
)

###########
## Build ##
###########
include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

add_executable(
  part_manager_node
  src/part_manager_node.cpp
  src/part_manager.cpp
  src/part.cpp
)
target_link_libraries(
  part_manager_node
  ${catkin_LIBRARIES}
)

#############
## Install ##
#############

There's more relevant files I can show, but this is already getting pretty long. The forge_features package depends on forge_errors, and the files in it all

#include <forge_errors/error_client_keeper.h>
#include <forge_errors/forge_error.h>

in the header files. And in the cmakelists for forge_features they're listed under find_package and catkin_package( CATKIN_DEPENDS, as well as in the package.xml for build and exec dependencies

part.h also includes those two files.

here's the relevant section of the errors package cmakelists:

catkin_package(
 INCLUDE_DIRS
  include
 LIBRARIES
  forge_errors
 CATKIN_DEPENDS
  forge_msgs
  forge_db_manager
  forge_utils
  roscpp
)

###########
## Build ##
###########

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

add_library(
  forge_errors
  src/forge_error.cpp
  src/error_service.cpp
  src/error_service_node.cpp
  src/error_client.cpp
  src/alert_service.cpp
  src/error_client_keeper.cpp
)
target_link_libraries(
  forge_errors
  ${catkin_LIBRARIES}
)
add_dependencies(
  forge_errors
  ${PROJECT_NAME}_generate_messages_cpp
  ${catkin_EXPORTED_TARGETS}
)

add_executable(
  error_service_node
  src/error_service_node.cpp
  src/error_service.cpp
  src/forge_error.cpp
  src/alert_service.cpp
)
target_link_libraries(
  error_service_node
  ${catkin_LIBRARIES}
)
add_dependencies(
  error_service_node
  ${PROJECT_NAME}_generate_messages_cpp
  ${catkin_EXPORTED_TARGETS}
) 

#############
## Install ##
#############

# Mark cpp header files for installation
install(DIRECTORY include/${PROJECT_NAME}/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.h"
  PATTERN ".svn" EXCLUDE
)

I can provide any other files it would help to see, but this post is too long already, so hopefully someone is able to wade through it and knows what the issue is, because I don't. forge_errors should be a complete and correctly building library, and I don't know why it can't link it to these executables.

codechao
  • 67
  • 9
  • You have missing symbols in your shared library. Check `ErrorClientKeeper` implementation, as the errors tells you to. – Matthieu Brucher Mar 13 '19 at 16:28
  • 1
    Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Matthieu Brucher Mar 13 '19 at 16:28
  • You're saying I should check the ErrorClientKeeper class file? – codechao Mar 13 '19 at 16:40
  • That's what the error says, yes. – Matthieu Brucher Mar 13 '19 at 16:40
  • I can't see any error with it. Would it help if I added that to my question? I should be including in the class everything the class needs – codechao Mar 13 '19 at 16:43
  • part.cpp:(.text+0x88f): undefined reference to `ErrorClientKeeper::addError(ForgeError::Severity, std::__cxx11::basic_string, std::allocator >, std::__cxx11::basic_string, std::allocator >, bool)' – Matthieu Brucher Mar 13 '19 at 16:46
  • I saw that. I posted the class file in my question if that helps. I've looked over part and part's use of errorclientkeeper seems to match the file. – codechao Mar 13 '19 at 16:49
  • Are the two compiled with the same compiler? May be a gcc ABI difference if you are using a more recent compiler for your project and the library is using the system gcc. – Matthieu Brucher Mar 13 '19 at 17:01
  • they should be getting built with the same compiler. They're all made with one catkin_make command – codechao Mar 13 '19 at 17:09
  • 1
    You `.cpp` file defines a **global function** `addError`, but the missed symbol is a **class method** `ErrorClientKeeper::addError`. They are not interchangeable. – Tsyvarev Mar 13 '19 at 19:54
  • ahhh, that must be the issue. either way, I went around the issue, but thank you. – codechao Mar 15 '19 at 20:50

0 Answers0