Search code examples
cgccubuntu-18.04unix-ar

Unable to identify issue GNU archiver. Compiling with *.o works but libname.a dosen't


I'm trying to make a static library (.a) but facing issues that I'm unable to understand. So in brief compiling with *.o succeeds but archiving them using ar and then using the .a file to compile gives me an undefined reference to 'symbol' error.

So here is a simple code.

test.c

#include <stdio.h>
#include <string.h>

int main()
{
    hello_world();
    return 0;
}

hello_world.c

#include<stdio.h>

void hello_world (void) {
    printf("Hello World\n");
}

Compile.

gcc -c -o hello_world.o hello_world.c
ar crs libhello.a hello_world.o
gcc libhello.a -o test test.c

gives me the error

/tmp/ccsO7AJl.o: In function `main':
test.c:(.text+0xa): undefined reference to `hello_world'

Instead doing this works(Compiles and runs fine)

gcc -c -o hello_world.o hello_world.c
gcc hello_world.o -o test test.c

I have no idea what I have done wrong so any help is appreciated.


Solution

  • This is an almost duplicate of Why does the order of '-l' option in gcc matter? - but the behaviour can be replicated without the -l switch by specifying the archive name on command line.

    The GNU linker as executed by GCC will, by default, link from left to right, and only use those .o files from the library archive that are needed to satisfy undefined references so far. Since your library precedes the main translation unit on the command line, hello_world is not required at the time the linker is processing it.

    The solution is to mention the library after the translation units/object files that depend on it:

    gcc -o test test.c libhello.a