静态库的c++链接器错误

标签 c++ cmake static-libraries ros catkin

我试图包含一个我用静态方法创建的静态库,但在尝试调用该方法时在运行时出现以下错误:

[ INFO] [1528271039.635221775]: Initializing nodelet with 4 worker threads. /opt/ros/kinetic/lib/nodelet/nodelet: symbol lookup error:/catkin_ws/devel/lib//libmission_manager_nodelet.so: undefined symbol: _ZN14my_commons10ConsoleLog6ROSLogEiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_

静态库有2个文件: 控制台日志.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 文件并在其中调用静态方法时会出现问题。

感谢您的帮助!

最佳答案

请在下面找到正确的 CMake 项目的工作示例:

目录结构:

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

您的源文件和头文件保持不变(我只将 *.h 更改为 *.hpp --> 毕竟您是用 C++ 编写的,而不是 C)。

主要.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 目录不存在)。您的项目树应如下所示:

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)

请记住从您的 MyCommonLib/CMakeLists.txt 中删除 add_executable 指令。另外 main.cpp 应该是这样的:

#include "ConsoleLog.hpp"

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

抱歉,之前我没有注意到 ROSLog 被声明为静态的。

关于静态库的c++链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50715194/

相关文章:

c++ - 接口(interface)的helpstring应该包含什么?

c++ - PARITY_NONE C++ Windows 中的关键字?

linux - "In-source builds are not allowed"在 cmake

android - 使用用于分发的静态库构建 Android NDK 应用程序

C++:引用静态库的静态库

c++ - 使用可变模板的维度无关类

cmake - 是否可以绕过 add_subdirectory() 命令的新范围创建?

opencv - 适用于Pandaboard Ubuntu的CMake与OpenCV交叉编译

swift - 创建一个带有 React 依赖的静态库

c++ - 数组显示比正常情况更多的结果