gcc 静态链接未定义的引用

gcc static linking undefined references

我使用 ar 创建了一个静态库来制作一个简单的单词计数器,但是当我到达 makefile 中的链接阶段时,出现以下错误:

g++ -o wordcount obj/word.o obj/main.o   -Wall -L lib  -llinkedlist
obj/word.o: In function `cleanUp(linkedList*)':
word.c:(.text+0x83): undefined reference to `ll_clear(linkedList*)'
obj/word.o: In function `initialize(linkedList*)':
word.c:(.text+0xa7): undefined reference to `ll_init(linkedList*)'
obj/word.o: In function `getTotalWordCount(linkedList*)':
word.c:(.text+0xbd): undefined reference to `ll_getIterator(linkedList*)'
word.c:(.text+0xd7): undefined reference to `ll_next(linkedListIterator*)'
word.c:(.text+0xea): undefined reference to `ll_hasNext(linkedListIterator*)'
obj/word.o: In function `getWord(linkedList*, unsigned int)':
word.c:(.text+0x118): undefined reference to `ll_get(linkedList*, unsigned int)'
obj/word.o: In function `findWord(linkedList*, char*)':
word.c:(.text+0x12e): undefined reference to `ll_getIterator(linkedList*)'
word.c:(.text+0x148): undefined reference to `ll_next(linkedListIterator*)'
word.c:(.text+0x178): undefined reference to `ll_hasNext(linkedListIterator*)'
obj/word.o: In function `combineCounts(linkedList*, wordData*)':
word.c:(.text+0x26e): undefined reference to `ll_add(linkedList*, void const*, unsigned int)'
obj/main.o: In function `main':
main.c:(.text+0x1df): undefined reference to `ll_getIterator(linkedList*)'
main.c:(.text+0x1f2): undefined reference to `ll_next(linkedListIterator*)'
main.c:(.text+0x25c): undefined reference to `ll_hasNext(linkedListIterator*)'
collect2: error: ld returned 1 exit status
makefile:38: recipe for target 'wordcount' failed
make: *** [wordcount] Error 1

但是,使用 nm 查看我的库的符号 table 会产生这些结果(为了便于阅读而被截断):

linkedlist.o:
00000028 T ll_add
00000124 T ll_addIndex
000003b7 T ll_clear
00000363 T ll_get
00000438 T ll_getIterator
00000477 T ll_hasNext
00000000 T ll_init
00000493 T ll_next
00000285 T ll_remove
00000420 T ll_size

我为类似问题找到的所有答案都提到您指定库的顺序很重要,但我已经在所有其他目标文件之后添加了我的库。有没有人知道我可能哪里出错了?

问题是该库是由 C 编译器编译的,但我已经使用 C++ 编译器编译了引用该库的新源代码。这两种方法的目标文件输出不同。以下面的代码为例:

// main.c
#include <stdio.h>

void foo(int x) {
  printf("%d\n");
}

int main(int argc, char** argv) {
  foo(argc);
  return 0;
}

将此文件作为 C 程序编译成目标文件将产生与作为 C++ 程序编译不同的符号。示例:

# Compile as C program
$ gcc -c main.c; nm main.o
00000000 T foo
00000018 T main
         U printf

# Compile as C++ program
$ g++ -c main.c; nm main.o
00000018 T main
         U printf
00000000 T _Z3fooi

如您所见,foo 函数使用两个不同的符号编译。由于新的源文件被编译为 C++,链接器需要 C++ 风格的符号,而库包含 C 风格的符号。链接器无法匹配符号,因​​此抛出错误,因为 C++ 符号未定义。