ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

RViz throws "undefined symbol" exception when including from include folder

asked 2017-07-27 14:31:19 -0500

G gravatar image

updated 2017-07-30 08:38:07 -0500

Rough Description: (intro / tl;dr)

The Problem is that when i move my header files for an RViz panel plugin to a dedicated include folder, the project will compile, but rviz will throw a "Poco exception = ...my_panel.so: undefined symbol: _ZTVN16my_panel14MyPanelE" Exception.

more precisely, this happens when i change the folder structure from:

meta_package/my_panel/my_panel.h
meta_package/my_panel/my_panel.cpp (including the header with "#include my_panel.h")

to:

meta_package/my_panel/include/meta_package/my_panel.h
meta_package/my_panel/src/my_panel.cpp (including the header with "#include <my_panel/my_panel.h>")

Project in Detail:

meta_package/my_panel/include/meta_package/my_panel.h , former @ meta_package/my_panel/my_panel.h

#ifndef MY_PANEL_H
#define MY_PANEL_H

#ifndef Q_MOC_RUN
#include <ros/ros.h>

#include <rviz/panel.h>
#endif //Q_MOC_RUN

class QLineEdit;

namespace my_panel
{

class MyPanel: public rviz::Panel
{

Q_OBJECT
public:

    MyPanel(QWidget *parent = 0);

    virtual void load( const rviz::Config& config);
    virtual void save( rviz::Config config ) const;

public Q_SLOTS:

    void savePathFile (const QString& save_file_name);
    void loadPathFile (const QString& load_file_name); //"const QString& " ?


protected Q_SLOTS:

    void dumpParamServer();
    void clearParamServer();

protected:

    QString open_file;
    QString save_file_name;
    QString load_file_name;
    QLineEdit* save_file_editor;
    QLineEdit* load_file_editor;
    ros::NodeHandle nh;

};
} //end namespace my_panel

#endif //MY_PANEL_H

meta_package/panel/src/my_panel.cpp , former @ meta_package/my_panel/my_panel.cpp

#include <stdio.h>
#include <QPainter>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>

#include <my_panel/my_panel.h> //former #include "my_panel.h"

namespace my_panel 
{

MyPanel::MyPanel( QWidget *parent )
  : rviz::Panel( parent )
 {

  QHBoxLayout* save_file_layout = new QHBoxLayout;
  save_file_layout->addWidget( new QLabel( "Save File with Name:" ));
  save_file_editor = new QLineEdit;
  save_file_layout->addWidget( save_file_editor );

  QHBoxLayout* load_file_layout = new QHBoxLayout;
  load_file_layout->addWidget( new QLabel( "Load File with Name:" ));
  load_file_editor = new QLineEdit;
  load_file_layout->addWidget( load_file_editor );

  QVBoxLayout* layout = new QVBoxLayout;
  layout->addLayout( load_file_layout );
  layout->addLayout( save_file_layout );
  setLayout( layout );
 }

void MyPanel::savePathFile(const QString& save_file_name)
{
  //TODO
}

void MyPanel::loadPathFile(const QString& load_file_name)
{
  //TODO
}

void MyPanel::dumpParamServer()
{
  //TODO
}

void MyPanel::clearParamServer()
{
  //TODO   
}

void MyPanel::save( rviz::Config config ) const
{
  rviz::Panel::save( config );
  //config.mapSetValue( "String", suff );
}

// Load all configuration data for this panel from the given Config object.
void MyPanel::load( const rviz::Config& config )
{
  rviz::Panel::load( config );
  /*  if( config.mapGetString( "String", &stuff ))
  {
    updateStuff();
  }*/
}

} //end namespace my_panel
#include <pluginlib/class_list_macros.h>
PLUGINLIB_EXPORT_CLASS(my_panel::MyPanel,rviz::Panel )

meta_package/my_panel/CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(my_panel)

find_package(catkin REQUIRED COMPONENTS rviz)
catkin_package()
include_directories(${catkin_INCLUDE_DIRS} include)
link_directories(${catkin_LIBRARY_DIRS})

## This setting causes Qt's "MOC" generation to happen automatically.
set(CMAKE_AUTOMOC ON)

## This plugin includes Qt widgets, so we must include Qt.
## We'll use the version that rviz used so they are compatible.
if(rviz_QT_VERSION VERSION_LESS "5")
  message(STATUS "Using Qt4 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
  find_package(Qt4 ${rviz_QT_VERSION} EXACT REQUIRED QtCore QtGui)
  ## pull in all required include dirs, define QT_LIBRARIES, etc.
  include(${QT_USE_FILE})
else()
  message(STATUS "Using Qt5 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
  find_package(Qt5 ${rviz_QT_VERSION} EXACT REQUIRED Core Widgets)
  ## make target_link_libraries(${QT_LIBRARIES}) pull in all required dependencies
  set(QT_LIBRARIES Qt5::Widgets)
endif()

## The tutorial prefers the Qt signals and slots to avoid defining "emit",
##"slots", etc because they can conflict with boost signals, so define 
## QT_NO_KEYWORDS here.
add_definitions(-DQT_NO_KEYWORDS)

set(HDR_FILES
    include ...
(more)
edit retag flag offensive close merge delete

Comments

1

I remember seeing a similar question recently, and I think it ended up being a problem with cmake's automoc no longer running MOC on the headers when they were in a different directory.

ahendrix gravatar image ahendrix  ( 2017-07-29 19:36:35 -0500 )edit
1

@ahendrix thanks for the suggestion! followed your link and their answers, so i added this to the CMakeLists.txt: "qt_wrap_cpp(${PROJECT_NAME} ${SRC_FILES} ${HDR_FILES})". pittily didn't work, and was the only suggestion except putting headers into the src folder. am i doing it wrong?

G gravatar image G  ( 2017-07-30 08:25:34 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
2

answered 2017-08-06 08:30:56 -0500

G gravatar image

I simply needed to add my new "HDR" macro to the add_library function!

in total:

set(HDR_FILES
    include/heika_panel_beta/heika_panel_beta.h
)

set(SRC_FILES
  src/heika_panel_beta.cpp
)

add_library(${PROJECT_NAME} ${SRC_FILES} ${HDR_FILES})

Works now! Thanks to everyone!

edit flag offensive delete link more

Comments

If this solved your problem, you should mark it as the correct answer.

jayess gravatar image jayess  ( 2017-08-07 06:12:42 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2017-07-27 14:31:19 -0500

Seen: 682 times

Last updated: Aug 06 '17