【问题标题】:Cannot understand linker issue无法理解链接器问题
【发布时间】:2020-04-24 11:49:48
【问题描述】:

我通常可以使用 nm 解决链接器的问题,例如“未定义的引用”,并弄清楚我忘记在 makefile 中添加源文件,但在这里我无法理解发生了什么:

$ make
gcc -I.. -I../../data_structures
-I../../iterator -I../../stack -I../../array_stack 
-Wall -Wextra -Werror  array_collection.o -o array_collection
-L.. -larray_collection
-L../../data_structures -ldyn_array
-L../../iterator -literator
-L../../stack -lstack
-L../../array_stack -larray_stack 
../../array_stack/libarray_stack.a(array_stack_init_stack.o): In function `array_stack_init_stack':
array_stack_init_stack.c:(.text+0x79): undefined reference to `stack_init'
$ nm ../../stack/libstack.a| grep stack_init
auto_stack_init.o:
0000000000000000 T auto_stack_init
0000000000000000 T stack_init

你能帮帮我吗? 说 gcc 命令在我正在使用的 vm 上别名为 clang 可能很重要。

这里是stack_init的代码:

void    stack_init(t_stack *stack, void *realisation)
{
    stack->realisation = realisation;
    stack->_release = stack->release;
}

【问题讨论】:

  • 显而易见的问题是:您是否真的定义了一个名为stack_init 的函数?我们不知道您的代码是什么样的,所以在这里很难为您提供帮助
  • 你在哪里定义stack_init
  • 这里需要哪部分代码?不想发垃圾邮件。
  • @David 您的问题很简单,函数 stack_init 从未定义,或者您错过了与定义它的文件的链接,但您调用了它。因为您与 stack lib (-lstack) 链接,这意味着您声明它但从未定义它
  • 谢谢@KamilCuk 会改变它

标签: c clang ld


【解决方案1】:
  1. 编译时使用静态库路径即可。所以不要使用gcc -L../../stack -lstack,而是使用gcc ../../stack/libstack.a

  2. 静态库的顺序很重要。如果一个静态库依赖于另一个静态库,它必须在命令行参数中出现在它之前。链接器在搜索符号时会扫描以下库,因此如果您有依赖于 stack.alibarray_stack.a,则必须在它之后。如果它们都相互依赖,请指定它们两次(无论如何这是处理问题的一种巧妙方法)。或者与gcc 编译器一起使用-Wl,--whole-archive。网上有各种资源可以解释为什么/如何发生,例如this thread

  3. 将 40 多年前(但仍然令人惊叹)的 make 工具重新搁置并移至 cmake 或其他为您处理此类问题(以及更多问题)的构建系统。

所以尝试编译:

gcc -I.. -I../../data_structures
-I../../iterator -I../../stack -I../../array_stack 
-Wall -Wextra -Werror  array_collection.o -o array_collection
-L.. -larray_collection
-L../../data_structures -ldyn_array
-L../../iterator -literator
-L../../stack -lstack
-L../../array_stack -larray_stack 
-L.. -larray_collection
-L../../data_structures -ldyn_array
-L../../iterator -literator
-L../../stack -lstack
-L../../array_stack -larray_stack 

【讨论】:

  • 好的,尝试此解决方案 make 出现一个(其他)“未定义引用”投诉,因此我将尝试您的第一个解决方案,但必须更改我的 makefile,以便它首先执行此操作。谢谢。 (我不允许使用make以外的其他工具)
  • 当然。也可以试试-Wl,--whole-archive ../libarray_collection.a ../../data_structurs/libdyn_array.a <all other libraries> -Wl,--no-whole-archive <you can repeat the libraries here again。一般找符号在哪里,把库放在编译行的最后。
  • 最后你的第二点成功了,但是上帝我现在需要一个自动系统来把图书馆放在“好”的秩序中:(...必须制作一个
  • will have to craft one 或使用一个。 cmake 是一个配置构建工具的工具(它不会构建项目本身)。所以你可以使用cmake 来生成makefile,所以你在cmake 中编写配置并生成makefile,然后依次使用。
  • 哦,好吧,我以为 cmake 可以代替 make,如果它最终使用 make,我当然可以使用它。感谢您提供宝贵的知识和时间。
猜你喜欢
  • 2019-08-30
  • 2019-11-03
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
相关资源
最近更新 更多