cmakefilefat32

undefined reference to `le16toh' error in Makefile


I'm trying to compile a C program with the following Makefile:

msh: libFAT32.so
    gcc -Wall -fPIC -I. -o msh newTest.c -L. -lFAT32

libFAT32.so: 
    gcc -std=c99 -shared -o libFAT32.so -fPIC fat32.c

clean: 
    rm *.so msh

However, every time I try to compile the program with make I get the following error:

user@user-VirtualBox:~/fat1$ make
    gcc -Wall -fPIC -I. -o msh newTest.c -L. -lFAT32
    ./libFAT32.so: undefined reference to `le32toh'
    ./libFAT32.so: undefined reference to `le16toh'
    collect2: error: ld returned 1 exit status
    Makefile:19: recipe for target 'msh' failed
    make: *** [msh] Error 1

Can some one tell how to fix this?


Solution

  • So, here's what's going on (making the safe assumption that you're using a linux distribution in your VM).

    With this test program:

    #include <stdio.h>
    #include <endian.h>
    
    int main(void) {
      printf("%d\n", le32toh(1234));
      return 0;
    }
    

    compiling and running it works:

    $ gcc -Wall -Wextra test.c
    $ ./a.out
    1234
    

    However, you're compiling using -std=c99. So let's try that:

    $ gcc -std=c99 -Wall -Wextra test.c
    test.c: In function ‘main’:
    test.c:5:18: warning: implicit declaration of function ‘le32toh’ [-Wimplicit-function-declaration]
       printf("%d\n", le32toh(1234));
                      ^~~~~~~
    /tmp/cc7p3cO8.o: In function `main':
    test.c:(.text+0xf): undefined reference to `le32toh'
    collect2: error: ld returned 1 exit status
    

    Compiling in c99 mode disables a bunch of functions and macros and such that aren't in the 1999 version of the C standard unless they're explicitly requested, hence the implicit declaration warning. le32toh() is a macro, not a function with a symbol in libc, hence the linker error.

    If you read the man page for le32toh(), you'll see that it needs the _DEFAULT_SOURCE feature test macro, which must be defined before any headers are included.

    So, your options are:

    1. Compile in gnu99 mode instead, since that automatically defines a bunch of the feature test macros.
    2. Continue to use c99 mode and add a #define _DEFAULT_SOURCE at the very start of your fat32.c source file.
    3. Continue to use c99 mode and add -D_DEFAULT_SOURCE to your compiler arguments.