RViz throws "undefined symbol" exception when including from include folder
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 ...
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.
http://answers.ros.org/question/26561...
@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?