为什么要两次使用静态库来使编译工作正常进行?

5氩

我正在学习ARToolKit和CMake。我正在尝试制作一个CMake例程,以复制ARToolKit在其Makefile文件中所做的事情。我找到了这个 :

LIBS= -lARgsub_lite -lARvideo -lAR -lARICP -lAR -lglut -lGLU -lGL -lX11 -lm -lpthread -ljpeg -ldc1394 -lraw1394

$(BIN_DIR)/simpleLite: simpleLite.o $(OBJS)
cc -o $(BIN_DIR)/simpleLite simpleLite.o $(OBJS) $(LDFLAG) $(LIBS)

我注意到这-lAR被声明了两次我决定将其复制到我的CMake文件中,该文件也声明了两次。

set( ART_STATICS libARgsub_lite.a libARvideo.a libAR.a libARICP.a libAR.a)
link_directories(${ART_DIR}/lib)

它的工作原理。但是,如果我删除了最后一个重复的副本,则程序会抱怨找不到libAR库中的函数。(确切地说,它是libAR的matrix.h中的矩阵函数)为什么?顺序重要吗?还是可能libARICP.a是“消耗”了某种东西,libAR.a所以您必须再次声明它?抱歉,我不了解链接静态库的内部工作原理...

阿玛·侯赛因(Ammar Husain)

我发现这个类比对您所询问的内容(来源特别有用

  • 可以将存档库视为一个书架,上面有一些书(单独的.o文件)。
  • 有些书可能会(通过未解析的符号)将您引向其他书,这些书可能在同一书架上,也可能在不同的书架上。

图书馆员来到第一个书架(链接线上的第一个档案库)时,有两个列表-一个她仍然需要的东西列表(未解决的符号),一个她已经拥有的东西列表(已经定义的符号)。

通常,她已经有crt0.o(由编译器驱动程序添加到链接行中),它​​指向main。因此,她的“需要”列表包含主要信息。通常,她也将具有main.o,这意味着她不再需要main.o,但可能需要malloc,free,printf等。

现在,她开始一次扫描一个书架,以查找定义她需要的符号的书。如果一本书定义了“需要”列表中的一个符号,则将她从书架上拿走,从“需要”列表中删除该书中定义的所有符号,将所有已定义的符号添加到“必须”列表中,然后将该书使用的所有符号添加到“需要”列表中,而该符号尚未出现在“拥有”列表中。

如果一本书没有在“需要”列表中定义任何符号,则她不会接受(即使这本书稍后可能派上用场)。

如果她刚读过的书定义了她已经拥有的符号,则存在“多重定义符号”问题。

如果她从当前书架上拿走了任何书,她会再次重新扫描书架,以寻找更多的书(因为她刚拿走的书可能需要当前书架上的其他书)。

一旦在当前书架上不再需要她的书,便完成了该书架,并且不返回该书架(除非对应于该书架的库在命令行中多次列出)。

如果在搜索了命令行中列出的所有书架(以及由编译器驱动程序添加的libc)之后,她仍然在“需要”列表中有条目,则出现“未定义符号”错误。

显然,如果您的许多生物学书籍都涉及化学书籍,并且您有生物学论文要撰写,那么您最好在化学书籍之前先搜索生物学书架。

有时,两个存档库是相互依赖的:一个库中的对象依赖于另一个库中的对象,反之亦然。

这意味着,没有正确的顺序链接这些库,两个库的结构都较差,并且为了成功链接一个可执行文件,您可能需要多次列出这两个库,如下所示:

 gcc main.o -lfoo -lbar -lfoo -lbar -lfoo

在使用GNU ld的系统上,可以使用--start-group和--end-group命令行选项来解决此类库间依赖性。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么需要两次应用flexbox才能使其正常工作?

来自分类Dev

为什么我的功能不能正常工作两次?

来自分类Dev

为什么$(window).resize()上的click事件不能正常工作两次?

来自分类Dev

为什么要两次拿东西?

来自分类Dev

DNX为什么要两次运行代码

来自分类Dev

为什么要两次声明jQuery?

来自分类Dev

为什么控制器要创建两次?

来自分类Dev

为什么说明我要渲染两次或调用渲染两次?

来自分类Dev

为什么键盘回调可以工作两次并进行双键打印(Java / JNA)?

来自分类Dev

为什么Java的编译成汇编两次?

来自分类Dev

为什么OpenCL Nvidia编译器(nvcc)不使用寄存器两次?

来自分类Dev

为什么OpenCL Nvidia编译器(nvcc)不使用寄存器两次?

来自分类Dev

在Angular2中,为什么在setTimeout之后要进行两次内容检查和查看?

来自分类Dev

为什么需要单击两次按钮才能工作

来自分类Dev

为什么在使用此工作单元时两次调用Dispose?

来自分类Dev

为什么我的程序在使用时两次输出一个参数([-d?]和[-d | --data])?(我正在使用popt库进行选项解析)

来自分类Dev

为什么execvp()使用fork()执行两次?

来自分类Dev

为什么在Java中两次使用构造函数

来自分类Dev

Function.prototype.apply.apply-为什么要两次调用

来自分类Dev

为什么指定了生命周期管理器时,类型要注册两次?

来自分类Dev

为什么要尝试两次查找析构函数?

来自分类Dev

Java 6:为什么要定义两次泛型?

来自分类Dev

为什么对象副本要构造和破坏两次?

来自分类Dev

AWS EB docker app:为什么要配置两次nginx?

来自分类Dev

Ember.js应用程序为什么要加载两次?

来自分类Dev

导入模块和子模块。为什么要进口两次?

来自分类Dev

为什么对象副本要构造和销毁两次?

来自分类Dev

为什么要读取 csv 文件的列两次,而最后一列是 None?

来自分类Dev

在函数式编程中,为什么 IO 的 join 方法要运行 unsafePerformIO 两次?

Related 相关文章

  1. 1

    为什么需要两次应用flexbox才能使其正常工作?

  2. 2

    为什么我的功能不能正常工作两次?

  3. 3

    为什么$(window).resize()上的click事件不能正常工作两次?

  4. 4

    为什么要两次拿东西?

  5. 5

    DNX为什么要两次运行代码

  6. 6

    为什么要两次声明jQuery?

  7. 7

    为什么控制器要创建两次?

  8. 8

    为什么说明我要渲染两次或调用渲染两次?

  9. 9

    为什么键盘回调可以工作两次并进行双键打印(Java / JNA)?

  10. 10

    为什么Java的编译成汇编两次?

  11. 11

    为什么OpenCL Nvidia编译器(nvcc)不使用寄存器两次?

  12. 12

    为什么OpenCL Nvidia编译器(nvcc)不使用寄存器两次?

  13. 13

    在Angular2中,为什么在setTimeout之后要进行两次内容检查和查看?

  14. 14

    为什么需要单击两次按钮才能工作

  15. 15

    为什么在使用此工作单元时两次调用Dispose?

  16. 16

    为什么我的程序在使用时两次输出一个参数([-d?]和[-d | --data])?(我正在使用popt库进行选项解析)

  17. 17

    为什么execvp()使用fork()执行两次?

  18. 18

    为什么在Java中两次使用构造函数

  19. 19

    Function.prototype.apply.apply-为什么要两次调用

  20. 20

    为什么指定了生命周期管理器时,类型要注册两次?

  21. 21

    为什么要尝试两次查找析构函数?

  22. 22

    Java 6:为什么要定义两次泛型?

  23. 23

    为什么对象副本要构造和破坏两次?

  24. 24

    AWS EB docker app:为什么要配置两次nginx?

  25. 25

    Ember.js应用程序为什么要加载两次?

  26. 26

    导入模块和子模块。为什么要进口两次?

  27. 27

    为什么对象副本要构造和销毁两次?

  28. 28

    为什么要读取 csv 文件的列两次,而最后一列是 None?

  29. 29

    在函数式编程中,为什么 IO 的 join 方法要运行 unsafePerformIO 两次?

热门标签

归档