我正在尝试包含一个静态库,我使用静态方法创建但在尝试调用方法时遇到以下错误在运行时:
[INFO] [1528271039.635221775]:使用4个工作线程初始化nodelet。 / opt / ros / kinetic / lib / nodelet / nodelet:符号查找错误:/catkin_ws/devel/lib//libmission_manager_nodelet.so:undefined symbol:_ZN14my_commons10ConsoleLog6ROSLogEiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6 _
静态库有2个文件: ConsoleLog.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(枚举)中头文件中的数据,当尝试添加cpp文件并调用其中的静态方法时会出现问题。
感谢您的帮助!
答案 0 :(得分:0)
请在下面找到正确CMake项目的工作示例:
目录结构:
ROOT
|
+--inc
| +--ConsoleLog.hpp
+--src
| +--ConsoleLog.cpp
| +--main.cpp
+CMakeLists.txt
你的源文件和头文件保持不变(我只用* .h改为* .hpp - &gt;用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评论)==============
好吧,我没有将此lib嵌入另一个项目结构中的任何问题。您获得的错误意味着您的目录结构不正确(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
被宣布为静态之前。