2

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?

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
mj_r96
  • 37
  • 6
  • Does the c/c++ code `#include `? Typically those the functions it provides turn into inline code (or disappear entirely) so there isn't usually any external function to reference. – wallyk Nov 08 '18 at 22:55
  • I did include endian.h – mj_r96 Nov 08 '18 at 22:56
  • what is the gcc version? – Jan Spurny Nov 08 '18 at 22:58
  • `-I.` Did you `#include ` or `#include "endian.h"` ? Is endian.h in your directory overwriting the default /usr/include/endian.h include? [`le32toh`](https://github.com/lattera/glibc/blob/master/string/endian.h#L72) is probably a macro or at least an inline function, shouldn't be linked with. If not, maybe just write your own function, maybe `fat32.c` expects you to write it. – KamilCuk Nov 08 '18 at 22:59
  • gcc version 7.3.0 – mj_r96 Nov 08 '18 at 23:07
  • I'm using #include – mj_r96 Nov 08 '18 at 23:07

1 Answers1

2

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.
Shawn
  • 47,241
  • 3
  • 26
  • 60