Ошибка компоновщика c ++ со статической библиотекой - PullRequest
0 голосов
/ 06 июня 2018

Я пытаюсь включить статическую библиотеку, созданную мной статическим методом, но при попытке вызвать метод во время выполнения при попытке вызвать метод:

[INFO] [1528271039.635221775]: Инициализация нодлета с 4 рабочими потоками./ opt / ros / kinetic / lib / nodelet / nodelet: ошибка поиска символа: /catkin_ws/devel/lib//libmission_manager_nodelet.so: неопределенный символ: _ZN14my_commons10ConsoleLog6ROSLogEiNSt7__cxx1112basic_stringIcSt11ES_ogS * 100 * * 100 * * 100 * * 100 * * 100.h:

#ifndef CONSOLE_LOG_H
#define CONSOLE_LOG_H

#include "ros/ros.h"
namespace my_commons
{
class ConsoleLog
{
  public:
    static void ROSLog(int type, std::string message,std::string taskName);
    static void STDLog(int logType, std::string msg,std::string taskName);
};
} // namespace my_commons
#endif //CONSOLE_LOG_H

и ConsoleLog.cpp:

#include "ConsoleLog.h"
namespace my_commons
{
void ConsoleLog::ROSLog(int type, std::string message, std::string task)
{
    switch (type)
    {
    case (0):
        ROS_DEBUG_STREAM("########## " << task << " DEBUG: " << message << " ##########");
        break;
    case (1):
        ROS_INFO_STREAM("########## " << task << " " << message << " ##########");
        break;
    case (2):
        ROS_WARN_STREAM("##########  " << task << " WARNNING: " << message << " ##########");
        break;
    case (3):
        ROS_ERROR_STREAM("########## " << task << " ERROR: " << message << " ##########");
        break;
    }
}

void ConsoleLog::STDLog(int logType, std::string msg, std::string task)
{
    std::cout << msg << std::endl;
}
} // namespace my_commons

CMakelist.txt:

cmake_minimum_required(VERSION 2.8.3)
project(my_commons)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")

find_package(catkin REQUIRED COMPONENTS
roscpp
)

catkin_package(CATKIN_DEPENDS
               INCLUDE_DIRS include)


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


add_library(my_commons
src/ConsoleLog.cpp
)



## Specify libraries to link a library or executable target against

set_target_properties(my_commons PROPERTIES LINKER_LANGUAGE CXX)

target_link_libraries(my_commons
                        ${catkin_LIBRARIES} 
                        ${roscpp_LIBRARIES}                         
)

#add_dependencies(name_of_package_nodelet)

install(DIRECTORY include/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.h"
  PATTERN ".svn" EXCLUDE)

# Install library
install(TARGETS my_commons
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Редактировать:

Здеськлиенты CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.3)
project(my_mission_manager)

set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")

find_package(catkin REQUIRED COMPONENTS
    roscpp
    nodelet
  std_msgs 
    my_commons
  message_runtime
  std_srvs
)

catkin_package(
  CATKIN_DEPENDS 
  message_runtime 
  std_msgs 
  my_commons
)

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


add_library(my_mission_manager_nodelet
                src/my_mission_manager_nodelet.cpp
)

## Specify libraries to link a library or executable target against


target_link_libraries( my_mission_manager_nodelet
                        ${catkin_LIBRARIES} 
                        ${roscpp_LIBRARIES}                         
)

#add_dependencies(my_mission_manager_nodelet)


# Install library
install(TARGETS my_mission_manager_nodelet
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

# Install header files
install(DIRECTORY src/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
)

# Install launch files
install(DIRECTORY launch/
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
)

# Install xml files
install(FILES nodelet_plugins.xml
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)

Что мне здесь не хватает?

Кстати, я могу использовать данные из заголовочных файлов в my_commons (enums), проблема возникает, когдаПри попытке добавить файл cpp вызывается статический метод.

Спасибо за помощь!

1 Ответ

0 голосов
/ 06 июня 2018

Ниже приведен рабочий пример правильного проекта CMake:

Структура каталогов:

ROOT
|
+--inc
|   +--ConsoleLog.hpp
+--src
|   +--ConsoleLog.cpp
|   +--main.cpp
+CMakeLists.txt

Ваши исходные файлы и файлы заголовков остаются неизменными (я только изменил * .h на * .hpp-> после всего, что вы пишете на C ++, а не на C).

main.cpp:

#include "ConsoleLog.hpp"

int main() {
    my_commons::ConsoleLog log;
    log.ROSLog(1, "xxx", "yyy");
    return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.11)
project(my_commons)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")

find_package(catkin REQUIRED COMPONENTS roscpp)

add_library(my_commons STATIC src/ConsoleLog.cpp)
target_include_directories(my_commons PUBLIC inc ${roscpp_INCLUDE_DIRS})
target_link_libraries(my_commons ${catkin_LIBRARIES} ${roscpp_LIBRARIES})

add_executable(MyExec src/main.cpp)
target_link_libraries(MyExec my_commons)

Результат выполнения:

./MyExec 
[ INFO] [1528280295.971205050]: ########## yyy xxx ##########

Я использую более новую версию CMake, чтобы использовать target_include_directories, потому что мне нравится эта функция.Я изменил флаги вашего компилятора, чтобы включить стандарт C ++ 11, потому что, очевидно, вы используете его.Я также удалил правила INSTALL CMake, потому что они не имеют отношения к вопросу.Дайте мне знать, если этот ответ вам подходит.

=============== РЕДАКТИРОВАТЬ (ответить на комментарий OP) ==============

Что ж, у меня нет проблем с встраиванием этой библиотеки в другую структуру проекта.Полученная ошибка означает, что ваша структура каталогов неверна (my_commons dir не существует).Дерево вашего проекта должно выглядеть следующим образом:

ROOT
|
+--MyCommonsLib (this is the root of your my_commons library)
|
+--src
|   +--main.cpp
+CMakeLists.txt

И CMakeLists.txt вашего проекта может выглядеть так:

cmake_minimum_required(VERSION 2.8.11)

project(SomeSimpleProjectUsingMyCommonsLib)

add_subdirectory(MyCommonsLib)

add_executable(MyExec src/main.cpp)
target_link_libraries(MyExec my_commons)

Просто не забудьте удалить инструкцию add_executable из вашего MyCommonLib/CMakeLists.txt.Также main.cpp должно быть таким:

#include "ConsoleLog.hpp"

int main() {
    my_commons::ConsoleLog::ROSLog(1, "xxx", "yyy");
    return 0;
}

Извините, пока я не заметил, что ROSLog объявлен как статический.

...