Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;静态库的链接器错误_C++_Cmake_Static Libraries_Ros_Catkin - Fatal编程技术网

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

C++ c++;静态库的链接器错误,c++,cmake,static-libraries,ros,catkin,C++,Cmake,Static Libraries,Ros,Catkin,我正在尝试包含使用静态方法创建的静态库,但在尝试调用该方法时,在运行时出现以下错误: [信息][1528271039.635221775]:正在使用4个工作线程初始化nodelet。 /opt/ros/kinetic/lib/nodelet/nodelet:符号查找错误:/catkin\u ws/devel/lib//libmission\u manager\u nodelet.so:未定义的符号:_ZN14my\u commons 10consolog6roslogeinst7\u cx111

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

[信息][1528271039.635221775]:正在使用4个工作线程初始化nodelet。 /opt/ros/kinetic/lib/nodelet/nodelet:符号查找错误:/catkin\u ws/devel/lib//libmission\u manager\u nodelet.so:未定义的符号:_ZN14my\u commons 10consolog6roslogeinst7\u cx1112基本\u stringist11char\u traitssiceees 6_

静态库有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
编辑:

以下是客户端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}
)
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)
我错过了什么

顺便说一句,我可以使用my_commons(枚举)中头文件的数据,当尝试添加cpp文件并在其中调用静态方法时会出现问题


谢谢你的帮助

请在下面找到正确的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.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}
)
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版本来使用
目标目录
,因为我喜欢这个功能。我更改了编译器标志以包含C++11标准,因为显然您使用了它。我还删除了INSTALL-CMake规则,因为它们与问题无关。让我知道这个答案是否适合你

===================编辑(回答OP评论)==============

嗯,我在将这个库嵌入到另一个项目结构中时没有任何问题。您得到的错误意味着您的目录结构不正确(
my_commons
dir不存在)。您的项目树应如下所示:

ROOT
|
+--MyCommonsLib (this is the root of your my_commons library)
|
+--src
|   +--main.cpp
+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)
#include "ConsoleLog.hpp"

int main() {
    my_commons::ConsoleLog::ROSLog(1, "xxx", "yyy");
    return 0;
}
您的项目的
CMakeLists.txt
可能如下所示:

ROOT
|
+--MyCommonsLib (this is the root of your my_commons library)
|
+--src
|   +--main.cpp
+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)
#include "ConsoleLog.hpp"

int main() {
    my_commons::ConsoleLog::ROSLog(1, "xxx", "yyy");
    return 0;
}
请记住从您的
MyCommonLib/CMakeLists.txt
中删除
add_executable
指令。另外,
main.cpp
应该是这样的:

ROOT
|
+--MyCommonsLib (this is the root of your my_commons library)
|
+--src
|   +--main.cpp
+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)
#include "ConsoleLog.hpp"

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

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

正在成功编译它。它在运行时崩溃。添加了缺少的行。。。你能再试一次吗?感谢您的帮助。当然,它不起作用,因为您没有为lib提供任何源文件-因此您的项目甚至没有编译-因此您缺少一个符号<代码>添加库(我的共享空间)<代码>设置目标属性(my_commons properties LINKER\u LANGUAGE CXX)是一种黑客行为,不是一种好的做法。你的安装命令也有点粗糙。你们到底想实现什么?你们说你们有静态库,但我不知道你们在哪里链接到它。@Ptaq666我不喜欢在这里复制它。添加了缺少的行…您好@Ptaq666,感谢您的回复!静态库中是否需要有一个main?重点是创建一类静态方法,我可以在不同的项目中使用。。。此外,由于我有更多具有相同编译器标志的项目,我现在不想将此项目更改为较新版本…不,不,当然没有必要。我只包含了主可执行文件,以证明解决方案是有效的。通过调用
add_子目录
,您可以将
my_commons
库嵌入项目的
CMakeLists.txt
。如果您想在系统上安装
my_commons
并使用
find_package
查找它,这将更加复杂,因为您需要创建
my_commonconfig.cmake
,这将使您的任务更加复杂。如何恰当地执行它是另一个主题(虽然没有那么困难),问题是我能够使用my_公共库中头文件中的数据。只有在使用静态方法添加cpp时才会出现问题。。。尝试添加时,在my_mission_manager/CMakeLists.txt:27(添加子目录)中添加子目录得到:CMake错误:添加子目录给定源“my_commons”,它不是现有目录。这意味着
my_commons
目录不存在。我编辑了答案并解释了如何将库嵌入到项目中。感谢您的帮助。。。看来这个骗局是对的,但还是行不通。但是,当我尝试将代码从cpp文件移动到头文件时,一切都正常。所以现在我很困惑:)