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

     2023-02-16     32

关键词:

【中文标题】静态库的c ++链接器错误【英文标题】:c++ Linker error with static library 【发布时间】:2018-06-06 08:02:49 【问题描述】:

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

[ INFO] [1528271039.635221775]:使用 4 个工作线程初始化 nodelet。 /opt/ros/kinetic/lib/nodelet/nodelet:符号查找错误:/catkin_ws/devel/lib//libmission_manager_nodelet.so:未定义符号:_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 文件并在其中调用静态方法时会出现问题。

感谢您的帮助!

【问题讨论】:

编译成功。它在运行时崩溃。 添加了一个缺失的行...你可以再试一次吗?感谢您的帮助。 当然不行,因为你没有为你的库提供任何源文件——因此你的项目甚至没有被编译——因此你缺少一个符号。 add_library(my_commons &lt;here you should put sth like MyCommons.cpp&gt;)set_target_properties(my_commons PROPERTIES LINKER_LANGUAGE CXX) 是一种 hack,不是一个好习惯。你的安装命令也有点老套。你到底想达到什么目标? 你说你有静态库,但我看不到你在哪里链接。 @Ptaq666 我不喜欢在这里复制它。添加了缺少的行... 【参考方案1】:

请在下面找到正确 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)

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

#include "ConsoleLog.hpp"

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

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

【讨论】:

嗨@Ptaq666,感谢您的回复!有必要在静态库中有一个 main 吗?重点是创建一类我可以在不同项目中使用的静态方法...此外,由于我有更多具有相同编译器标志的项目,我现在不想将其更改为较新的版本.. . 不不,当然没必要。我只包含了主要的可执行文件来证明该解决方案是有效的。您可以通过调用 add_subdirectorymy_commons 库嵌入到项目的 CMakeLists.txt 中。如果您想在系统上安装my_commons 并使用find_package 找到它 - 这更复杂,因为您需要创建my_commonsConfig.cmake,这会使您的任务进一步复杂化。如何适当地做到这一点是另一个话题(虽然不是那么难)。 问题是我能够使用来自 my_common 库中头文件的数据。仅当使用静态方法添加 cpp 时才会出现问题...尝试 add_subdirectory 时得到:CMake Error at my_mission_manager/CMakeLists.txt:27 (add_subdirectory): add_subdirectory given source "my_commons" which is not an existing directory. 表示my_commons 目录不存在。我编辑了答案并解释了你应该如何将你的库嵌入到项目中。 感谢您提供的所有帮助... 看来层次结构是正确的,但它仍然无法正常工作。但是,当我尝试将代码从 cpp 文件移动到头文件时,一切正常。所以现在我很困惑:)

c语言学习笔记--动态库和静态库的使用

1.C语言中的链接器 (1)每个C语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件。 (2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接... 查看详情

为啥链接器链接了错误的函数?

】为啥链接器链接了错误的函数?【英文标题】:Whywrongfunctionwaslinkedbythelinker?为什么链接器链接了错误的函数?【发布时间】:2020-05-3114:11:50【问题描述】:我对以下情况感到很困惑:我有一个使用静态库A来获取可执行文件的L... 查看详情

qt creator qt5.1 vs2010 使用静态库时链接器错误

】qtcreatorqt5.1vs2010使用静态库时链接器错误【英文标题】:qtcreatorqt5.1vs2010linkererrorwhenusingstaticlibrary【发布时间】:2013-09-2320:23:29【问题描述】:当我尝试在带有qt5.1的qtcreater中使用使用vs2010编译的静态库时遇到问题。我正在使用... 查看详情

链接器错误 - 目标 C

】链接器错误-目标C【英文标题】:LinkerError-ObjectiveC【发布时间】:2013-03-2420:23:01【问题描述】:当我尝试从文件“VAMenuScreenViewController”导入文件“VARendererViewController.h”时发生此错误duplicatesymbol_gestureMinimumTranslationin:/Users/Sam/L... 查看详情

链接过程

链接器的意义链接器的主要作用是把各模块之间相互引用的部分处理好,使得各模块之间能够正确的衔接模块链接静态链接-由链接器在链接时将库的内容直接加入到可执行程序中Linux下静态库的创建和使用 -编译静态库源码... 查看详情

使用静态成员时的链接器错误

】使用静态成员时的链接器错误【英文标题】:Linkererrorwhenusingstaticmembers【发布时间】:2011-12-2304:20:14【问题描述】:我在MacOSX上使用Qt4.7和Cmake2.8.3以及g++4.2.1。在我的一个文件中使用静态或全局变量时,我遇到了一个奇怪的链... 查看详情

静态链接库时出现链接器错误

】静态链接库时出现链接器错误【英文标题】:Linkererrorwithglewwhenlibraryisstaticallylinked【发布时间】:2015-11-0809:07:41【问题描述】:我正在尝试在VisualStudio2012中构建一个opengl项目。我想静态包含​​glew库,所以我从源代码构建它... 查看详情

静态和共享库链接器错误

】静态和共享库链接器错误【英文标题】:Staticandsharedlibrarieslinkererror【发布时间】:2013-04-1317:31:42【问题描述】:我正在使用NDK(Android的原生编译器工具)。所以,情况是这样的:Staticboost→Sharedhelpers↓SharedGameHelpers是一些用... 查看详情

VC++ 链接器删除静态库的间接依赖

】VC++链接器删除静态库的间接依赖【英文标题】:VC++linkertoremoveindirectdependenciesforstaticlibraries【发布时间】:2016-05-1805:16:38【问题描述】:考虑这种情况(一切都处于发布模式):a.libincludesf1()andf2().a.libisbuiltusing/LTCGonVS2015.f1()isl... 查看详情

c 编程中 mysql.h 的链接器错误

】c编程中mysql.h的链接器错误【英文标题】:Linkererrorwithmysql.hincprogramming【发布时间】:2017-05-0314:09:43【问题描述】:您好,我想解决如何解决链接器错误。我想做的是从/usr/local/include中包含头文件mysql.h。(我正在使用macbook)... 查看详情

Apple Mach-O 链接器错误,目标 C

】AppleMach-O链接器错误,目标C【英文标题】:AppleMach-OLinkerError,ObjectiveC【发布时间】:2013-10-0108:41:34【问题描述】:我正在尝试编译我的应用程序,但它总是出现此错误“AppleMac-OLinkerErrorlinkercommandfailedwithexitcode1(use-vtoseeinvocation)... 查看详情

从头文件中定义方法时的c ++链接器错误[重复]

】从头文件中定义方法时的c++链接器错误[重复]【英文标题】:c++linkererrorwhenmethodisdefinedoutofheaderfile[duplicate]【发布时间】:2011-10-0114:22:54【问题描述】:可能重复:WheretodefineC++classmembertemplatefunctionandfunctorsthatinstantiateit?inclusionof... 查看详情

解决链接器错误 MySQL 连接器/C++

】解决链接器错误MySQL连接器/C++【英文标题】:ResolvingLinkererrorMySQLConnector/C++【发布时间】:2020-03-2816:17:26【问题描述】:我希望能够从我的c++程序连接到本地MySQL实例,但以下最小文件testfile.cpp无法编译并返回未定义的引用:#i... 查看详情

第20课链接过程简介

1.链接器的意义(1)每个C语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件。(2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接。 2.静... 查看详情

链接器错误 2019 C++,VS2008

】链接器错误2019C++,VS2008【英文标题】:LinkerError2019C++,VS2008【发布时间】:2012-01-2009:15:22【问题描述】:我正在使用VS2008。我有Library5Lib文件A.lib库C.libD.libE.libA.Lib包含B,C,D,E的所有头文件现在我正在尝试使用A。MFC应用程序示例中... 查看详情

C 库的 C++ 包装器作为共享库

...:21【问题描述】:我自己解决了这个问题问题是图书馆的链接。我将libmywrapper.so(我将其重命名)文件复制到/usr/lib并与-mywrapper链接就是这样:-)原帖:我正在编写一个允许从C代码调用C++函数的包装库。不幸的是它没有链接......... 查看详情

将 WRL 用于 C++/CX 函数 - 链接器错误 [重复]

】将WRL用于C++/CX函数-链接器错误[重复]【英文标题】:UsingWRLforC++/CXfunctions-linkererror[duplicate]【发布时间】:2012-10-2312:37:40【问题描述】:可能重复:Whatisanundefinedreference/unresolvedexternalsymbolerrorandhowdoIfixit?我正在尝试制作不使用CX... 查看详情

将 C 库与 Haskell 库静态链接

】将C库与Haskell库静态链接【英文标题】:StaticallylinkingaClibrarywithaHaskelllibrary【发布时间】:2013-09-0319:01:11【问题描述】:我有一个旨在创建一些C++绑定的Haskell项目。我已经编写了C包装器并将它们编译成一个独立的静态链接库... 查看详情