CMakeList静态库多层嵌套问题 undefined reference to

2023-05-16

前言

	被一个问题缠绕了很长时间,这两天花精力好好研究了一下,总算解决了,翻过来看,就是自己不注意造的很多小问题。我的想法是把一些代码封装起来,但是有些部分要求能让现场工作同事有一定的改动空间,比如接口部分、协议部分、都是可以改动的,但是有些地方怕他们改错,所以需要封装起来。

问题描述

	我的工程是ROS工程,用CmakeLists.txt,基于上述想法,把一部分类封装成库,另外一部分暴露出来,在封装库的时候涉及到了静态库的多层嵌套问题。我的CmakeLists.txt架构是这样的:

CmakeLists.txt架构

		

find_package(Boost REQUIRED COMPONENTS system) #需要的第三方库find_package,这里只是用boost示意一下
#可以放到 THIRD_PARTY_LIBS
set( THIRD_PARTY_LIBS
        ${catkin_LIBRARIES}
        ${Boost_LIBRARIES}
        ${PCL_LIBRARIES} 
        )
link_directories(${PROJECT_SOURCE_DIR}/lib  #自己封装的库的位置

               ) 
#------------------------------本工程生成的库----------------------------------------               
#封装库filter ,会生成 libfiter.a
add_library(filter STATIC ${PROJECT_SOURCE_DIR}/src/filter.cpp)

target_link_libraries(filter
                                     ${PCL_LIBRARIES}
                                     ${THIRD_PARTY_LIBS})

#封装库segment ,会生成 libsegment.a
add_library( segment STATIC ${PROJECT_SOURCE_DIR}/src/segment.cpp)
target_link_libraries(segment
                                     ${PCL_LIBRARIES}
                                     ${THIRD_PARTY_LIBS})

#-----------------------------------调用的库-----------------------------------


#***注意*** 这里的object依赖自己生成的其他静态库:libbuild.a ,libtracking.a,就是这里出现的问题
add_library( object STATIC ${PROJECT_SOURCE_DIR}/src/object.cpp)
target_link_libraries(object 
																	build
																	tracking																	
                                 
                                     ${THIRD_PARTY_LIBS})


#--------------------------------------最后生成的库libprocess.a--------------------------------

#利用本工程生成的libfiter.a 、 libsegment.a 以及自己封装的libobject.a 还有第三方库生成的libprocess.a

add_library(process STATIC ${PROJECT_SOURCE_DIR}/src/process.cpp)

target_link_libraries(process 
                                        filter  #   本工程生成的                          		  
                                        segment # 本工程生成的                             
                                        object  #之前封装的,主要要把.h文件添加到本工程
                                        ${THIRD_PARTY_LIBS})# 需要的第三方库

#--------------------------------------生成可执行程序--------------------------------
add_executable(${PROJECT_NAME}_node src/${PROJECT_NAME}_node.cpp src/${PROJECT_NAME}.cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}_node			
				 				  ${catkin_LIBRARIES}

                                  process 
                                 #
                                 # filter
                                 # segment
                                  
                                 # object                                
                                                                    
                                  ${THIRD_PARTY_LIBS}                                 
                                )


问题

step 1

	按照上面的CmakeLists.txt 是可以编译过的,这里编译一下。

step 2

	但是因为我想把object部分也封装成库,所以要把下面这部分屏蔽,把生成的库object 都放在目录${PROJECT_SOURCE_DIR}/lib下。
#-----------------------------------调用的库-----------------------------------
#***注意*** 这里的object依赖自己生成的其他静态库:libbuild.a ,libtracking.a,就是这里出现的问题
add_library( object STATIC ${PROJECT_SOURCE_DIR}/src/object.cpp)
target_link_libraries(object 
									build
									tracking
							        ${THIRD_PARTY_LIBS})
							       
**这部分全部屏蔽掉**

step 3

	然后再编译,可以通过。

step 4

	删掉build和devel,不更改CmakeLists.txt ,再次编译,报错 `undefined reference to` 此类问题。

step 5

	然后,去找论坛,发现可能是有些依赖库没有加进来,所以我在最后 可执行程序这里添加了所有的库。
#--------------------------------------生成可执行删掉build和devel,不更改CmakeLists.txt ,再次编译,报错程序--------------------------------
add_executable(${PROJECT_NAME}_node src/${PROJECT_NAME}_node.cpp src/${PROJECT_NAME}.cpp)
 ## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}_node			
				 				  ${catkin_LIBRARIES}

                                  process 
                                 # 下面之前是屏蔽的.....
                                  filter
                                  segment
                                                                    
                                  object                   
                                                                    
                                  ${THIRD_PARTY_LIBS}                                 
                                )
		

step 6

	再次编译,还是出错,检查过链接次序,依赖库等,都没有问题。
	奇怪的是我把step 2部分注释去掉,编译通过,再屏蔽该部分,编译通过,然后删掉build和devel,不更改CmakeLists.txt ,再次编译,报错。
	就是这个问题,虐我千百遍,虐我好几年。

解决办法

库的依赖关系

	这里要特别感谢这篇文章:[“undefined reference to“ 问题汇总及解决方法 ------非常非常好的一篇文章](https://blog.csdn.net/stpeace/article/details/73302833)
	这篇文章说了“undefined reference to“的三个问题:
	1.依赖的库没有 找到/添加,这里就是没有设置存放你自己封装库的位置,或者没有添加依赖,通常要在CmakeLists.txt中添加:	
link_directories(${PROJECT_SOURCE_DIR}/lib  #自己封装的库的位置

               ) 
target_link_libraries(object 
									build
									tracking
							        ${THIRD_PARTY_LIBS})							        
	2.依赖顺序有问题,库的依赖是有次序的,这个次序是从头开始,提纲切领。可以见上面的文章。
	3.定义与实现不一致。这个就需要检测代码。

静态库的理解

	undefined reference to 的几个问题都处理了,但是还是出问题。就去研究静态库,这里参照了多个静态库生成一个静态库。[CMake应用:合并静态库的最佳实践](https://zhuanlan.zhihu.com/p/389448385) 。在这篇文章中发现了静态库其实就是 .o文件的集合,可以用ar -x *.a来查看,但是发现,只是当前cpp文件的,o,依赖的静态库并没有被一并打包到这个库里面。
	一度怀疑上面的问题是以为.o文件没有被生成,就按照合并静态库的做法好一顿捣鼓,最后没啥效果。忽然想到既然.a是有的对应的输出文件.o的,那么就不是因为需要编译生成.o文件,那为什么不屏蔽object是可以的,屏蔽了就不行?另外先放开编译,再屏蔽编译确实能通过?
	为什么?
	1.不屏蔽CmakeLists.txt的object生成过程是可以的,屏蔽了就不行  
	2.先不屏蔽,编译,再屏蔽编译确实能通过
	??????????????????
	把这两个操作的build文件拿出来,去对比了半天也没定位到。

解决

	想一下,库既然都存在,那么素材是都有的。并且先不屏蔽,编译,再屏蔽编译确实能通过,说明是,依赖也是没有问题的。因为CmakeLists.txt 要转成cmake,cmake比较麻烦,所以这个中间过程是不可见的。

想一下自己的架构,包含下面几种库:

	1.本工程生成的库,无嵌套
	2.调用的库,嵌套了其他调用库,2层嵌套
	3.用1 2 以及本地cpp生成的库,3层嵌套
	4.调用3生成的库,生成可执行程序。

库都可以生成

	库生成没有问题,并且编译有通过的情况,那么这个路就是可以走通的。那是不是链接关系的问题呢?并且发现是2这个库在报错误。
	通过对静态库的理解,发现上层的静态库并没有把下层静态库打包到一块,所以在最终的可执行程序,必须要列出所有可以依赖的库。最终:
   add_executable(${PROJECT_NAME}_node src/${PROJECT_NAME}_node.cpp src/${PROJECT_NAME}.cpp)
 ## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}_node			
				 				  ${catkin_LIBRARIES}

                                  process 
                                 # 下面之前是屏蔽的.....
                                  filter
                                  segment
                                  
                                  object
                                  build  #添加了最底层的静态库
                                  tracking #添加了最底层的静态库                          
                                                                    
                                  ${THIRD_PARTY_LIBS}  #添加了需要的第三方库                                 
                                )
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMakeList静态库多层嵌套问题 undefined reference to 的相关文章

  • JavaScript 通过引用与通过值 [重复]

    这个问题在这里已经有答案了 我正在寻找一些很好的综合阅读材料 了解 JavaScript 何时按值传递内容 何时通过引用传递内容 何时修改传递的项目影响函数外部的值以及何时不影响函数外部的值 我还感兴趣的是 何时通过引用与通过值分配给另一个
  • “基础 - ReferenceError:启动基础 zurb 项目时未定义原始值。”

    创建 Foundation Zurb 项目时出现错误 尝试使用之前针对其他应用程序显示的建议来解决问题 但没有一个有效 一篇文章引用了更新 elm 我这样做了 但是 它不起作用 此外 我查看了 Gulp 3 的已关闭问题 我正在使用 gul
  • “ref”和“out”关键字有什么区别?

    我正在创建一个函数 我需要在其中传递一个对象 以便该函数可以修改它 有什么区别 public void myFunction ref MyClass someClass and public void myFunction out MyCl
  • 添加引用对话框中缺少 GAC 程序集

    我有一个 Interop 程序集位于 GAC 中 Windows 资源管理器清楚地显示它列在C WINDOWS assembly文件夹 然而 当我尝试从 Visual Studio 添加对它的引用时 我在 添加引用 对话框中的任何位置都看不
  • “&”和 std::reference_wrapper 之间的区别?

    我有以下代码 include
  • nullptr 引用在 C++ 中是未定义的行为吗? [复制]

    这个问题在这里已经有答案了 下面的代码愚弄了nullptr指针和参考 include
  • 类 VS 引用结构

    我正在使用 C 编写游戏 因此 我非常关心性能 我想知道主要区别是什么 如果可能的话 使用类传递数据或通过引用传递结构的性能考虑因素 出于性能原因 我希望不要复制数据 我假设通过 ref 传递比这里通过值传递要快得多 我知道类始终通过引用传
  • 如何在独立的 .vbs 文件中从 VBScript 调用 DotNetFactory?

    我一直在探索扩展 QuickTest Professional 脚本编写功能的选项 并发现今天早上 所以我决定尝试一下 下面的代码在 QTP 环境中执行时工作正常 但我也可以看到它在 QTP 环境之外的用途 不幸的是 从独立的 vbs 文件
  • 如何在 C++ 中调用不同项目的方法?

    使用 Visual Studio 时 我通常使用 C 工作 因此 C 中的某些内容让我感到困惑 概念看起来如此不同 但名称几乎相同 我创建了一个控制台项目 我想在其中运行另一个项目以进行测试 我将该项目添加为控制台应用程序的引用 然后陷入困
  • 引用的项目在编译时“丢失”

    我有一个包含两个项目的 C 解决方案 一个服务 主项目 和一个记录器 该服务使用记录器中的类 我在服务项目中添加了对记录器项目的引用 在设计时 自动完成工作正常 记录器的类是可见的 我使用的引用具有适当的颜色 我重建解决方案 但出现问题 不
  • 通过引用调用原型函数时,类失去“this”范围

    谁能向我解释为什么 b 返回未定义以及如何解决这个问题 当我通过引用调用原型函数时 为什么 this 范围会丢失 MyClass function test this test test MyClass prototype myfunc f
  • 循环时,.iter() 与引用 (&) 有何不同?

    在玩 Rust 时 我发现你可以循环Vecs and HashMaps 可能还有其他 通过引用 而不是使用 iter let xs vec 1 2 3 4 5 for x in xs println x x The iter 函数似乎具有相
  • 是否可以在执行时查看对对象的所有引用?

    有没有办法查看执行时对某个对象的所有引用 我正在使用 Netbeans 其中是否存在此功能 编辑 使用探查器来执行此操作没有问题 我只需要知道引用 无论如何 好的 Netbeans 显示了对一个对象的所有引用 首先 以调试模式运行项目CTR
  • java hashmaps 的 get() 函数

    我声明了以下哈希图 HashMap
  • 每次加载解决方案时,所有项目引用都有黄色三角形

    我的所有项目 来自同一解决方案 引用都标有黄色三角形 这些项目都设置为相同的 NET 版本 4 5 1 错误日志说 无法引用项目 CommonLibrary 暂时解决该问题的方法是 删除并重新添加引用 右键单击并选择 添加服务引用 并立即取
  • 为什么链接生命周期仅与可变引用相关?

    前几天 有一个问题 https stackoverflow com questions 32089410 lifetimes and references to objects containing references有人对包含借用数据本
  • next.js 环境变量未定义(Next.js 10.0.5)

    我正在使用 Next js 编写一个网站 并尝试添加谷歌标签管理器 我按照 Next js Github 示例上的教程进行操作 但由于某些原因我无法访问我的环境变量 它说我的变量未定义 我在项目文件夹中创建了一个文件 env local 与
  • static_cast 和对指针的引用

    谁能告诉我为什么这不能编译 struct A struct B public A int main B b A a b B b1 static cast
  • 即使在 Excel 2007 中插入行时也保持绝对引用

    我有一个电子表格 我希望单元格公式始终查看特定单元格 即使插入行或列并且特定单元格移动也是如此 实际上 我总是想查看表格的 顶部 单元格 即使在表格顶部插入了新行 例如 单元格 A2 的公式为 E 2 现在我突出显示第 1 行并执行 插入行
  • C++ 在 std::map 中存储对值的引用

    我是否正确地假设向 std map 添加 删除元素不会影响其他元素 即导致它们在内存中重新定位 因此以下内容是安全的 我查看了各个网站上有关容器的信息 但只发现了迭代器无效的情况 这是我已经知道的 std map

随机推荐

  • 计算机,会是下一个土木专业吗?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 大家好 xff0c 我是麦叔 最近看到一个热门问题 xff1a 计算机专业是否会成为下一个土木工程 xff1f 这个问题我想大多数准备学习计算机方向
  • 改变世界的数学公式,yyds

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 数学一直是我认为非常神奇的学科 上学期间不知数学有何用 xff0c 甚至觉得数学专业连工作都找不到 xff0c 才知道自己原来的认知简直太渺小了 x
  • 你们都开工了,我才刚开始复盘

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 大家好 xff0c 我是小麦 自从阳康之后已经连续忙了快一个月 甚至春节都没有休息 xff0c 大年初一还工作到凌晨 地球不爆炸 xff0c 我们不
  • 卖网红饮品喜茶配方,他一年赚50万

    前两天我去了一趟广州 xff0c 参加了一个内部圈子的交流会 xff0c 加过我微信的朋友可能会看到 在交流会上 xff0c 认识了一个年轻小伙子 xff0c 大伙称呼他为豪哥 xff0c 在分享会上他讲述了自己卖喜茶配方年赚50万的创业历
  • 入职新公司被要工资流水!这背后到底有什么猫腻?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 关于 什么时候工资流水成了新人入职必须提供的资料项之一 这件事 xff0c 作为一个打工人还是多少了解一下背后的原因的 其实要说以前 xff08 不
  • 俄罗斯自研的CPU,能用吗?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 从 2014 年吞并克里米亚到 2022 年的俄乌战争 xff0c 俄罗斯和西方世界的冲突愈发加剧 xff0c 在能源和科技上的相互制裁不断升级 在
  • 爆一下年终奖

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 各个公司的年终奖大多尘埃落定了 xff0c 大环境说实话不是很好 xff0c 有人欢喜有人愁 xff0c 汇总了一波 xff0c 大概50位小伙伴的
  • ChatGPT火爆,背后的核心到底是什么?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 2022年12月份的时候 xff0c ChatGPT还只是个被人各种撩的聊天工具 但进入2023年后 xff0c 已经向着效率工具迈进了 微软宣布正
  • 不小心当上CTO了

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 大家好 xff0c 我是小麦 在知乎上看到一篇从创业公司的工程师一路成长为CTO的真实故事 看完我获益匪浅 在这里分享给大家 01 创业初期 在创业
  • 盘点一下电子嵌入式相关的公司

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 大家好 xff0c 我是小麦 最近入坑电子信息工程专业的表弟问我毕业能去干什么 xff1f 于是在这里盘点了一下电子嵌入式相关的公司 在这里和大家分
  • C# 解析ini类型文件详解

    1 什么是ini文件 INI文件是一种配置文件格式 xff0c 通常用于Windows操作系统中的应用程序中 它是一种文本文件 xff0c 由多个节和键值对组成 xff0c 用于存储应用程序的配置信息 INI文件的特点包括 xff1a IN
  • CAN总线显性电平和隐性电平详解

    相关文章 CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 CAN 信号线 CAN 传输的两条信号线被称为 CAN H 和CAN L 通电状态 xff1a CAN H xff08 2 5V xff
  • STM32的CAN总线调试经验分享

    相关文章 CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 文章目录 相关文章背景CAN总线CAN控制器CAN收发器 调试过程硬件排查CAN分析仪芯片CAN控制器调试 总结 背景 最近负责的一个项
  • 我的新副业

    大家好 xff0c 我是麦叔 聊聊我的新副业吧 尝试做了一段时间餐饮 xff0c 差不多有半年时间了 感触很深 在这里和大家分享一下 缘起 去年10月份朋友的店铺转让 xff0c 于是我就盘下来了 店面不大 xff0c 投入也不是很大 xf
  • 螺旋桨拉力

    介绍 螺旋桨拉力计算公式 直径 xff08 米 xff09 X 螺距 xff08 米 xff09 X 桨宽度 xff08 米 xff09 X 转速 xff08 转 秒 xff09 X 经验系数 xff08 0 25 xff09 61 拉力
  • 爆炸了!但YYDS

    正文共 xff1a 2962字 预计阅读时间 xff1a 8分钟 成功发射 xff0c 但在空中爆炸了 这一刻 xff0c 我们都仰望星空 北京时间 4 月 20 日晚 9 点半 xff0c 随着倒计时声音的结束 xff0c 在 Space
  • 赞爆了!Tabby 这款开源工具真的好用!

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达
  • 惠普暗影精灵VMware安装CentOS7显示[此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态]

    进入BIOS页面开启CPU虚拟化处理技术 电脑开机时按 ESC 键进入系统启动菜单 然后按F10进入BIOS页面 xff0c 开启 处理器虚拟化技术
  • Python的main函数

    在 Python 中 xff0c 程序的入口点通常指的是一个特定的函数 xff0c 即 main 函数 这个函数是程序的起点 xff0c 也是程序的入口 xff0c 通过调用 main 函数 xff0c 程序开始执行 在 Python 中
  • CMakeList静态库多层嵌套问题 undefined reference to

    前言 被一个问题缠绕了很长时间 xff0c 这两天花精力好好研究了一下 xff0c 总算解决了 xff0c 翻过来看 xff0c 就是自己不注意造的很多小问题 我的想法是把一些代码封装起来 xff0c 但是有些部分要求能让现场工作同事有一定