首页 > 解决方案 > 无法理解链接器问题

问题描述

我通常可以使用 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;
}

标签: cclangld

解决方案


  1. 编译时只需使用静态库路径。所以不要gcc -L../../stack -lstack只使用gcc ../../stack/libstack.a.

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

  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 

推荐阅读