I made a static library using ar to make a simple word counter, but when I reach the linking stage in my makefile, I get the following error:
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
However, using nm to look at the symbol table for my library produces these results (truncated for readability):
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
All the answers I've found for similar questions mention that the order in which you specify libraries matters, but I already am adding my library after all my other object files. Does anyone have any ideas where I might be going wrong?
The issue is that the library was compiled by a C compiler, but I had compiled my new sources that reference the library with a C++ compiler. The object file output is different between these two methods. Take the following code for example:
// main.c
#include <stdio.h>
void foo(int x) {
printf("%d\n");
}
int main(int argc, char** argv) {
foo(argc);
return 0;
}
Compiling this file into an object file as a C program will produce different symbols than compiling as a C++ program. Example:
# 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
As you can see the foo
function compiled with two different symbols. Since the new source files were compiled as C++, the linker expected C++ style symbols while the library contained C style symbols. The linker couldn't match the symbols and therefore throws an error since the C++ symbols are undefined.