Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symbol not found when static linking on MacOSX

I am trying to create a static library and link it on MacOS X (several versions): File foo.c:

char foo[111];

File bar.c:

#include <string.h>

extern char foo[];

int bar(char *src) {
  strcpy(foo, src);
  return strlen(foo);
}

Create a library:

$ cc -c foo.c bar.c
$ ar r libfoobar.a foo.o bar.o
ar: creating archive libfoobar.a
$ ranlib libfoobar.a 
$ nm libfoobar.a 

libfoobar.a(foo.o):
000000000000006f C _foo

libfoobar.a(bar.o):
                 U ___strcpy_chk
0000000000000000 T _bar
                 U _foo
                 U _strlen

Create a small test program:

File main.c:

#include <stdio.h>

int bar(char *);

int main(void) {
  printf("foobarbar = %i\n", bar("123"));
  return 0;
}

Compile and link:

$ cc -c main.c
$ cc -o m main.o -L. -lfoobar
Undefined symbols for architecture x86_64:
  "_foo", referenced from:
      _bar in libfoobar.a(bar.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Why is the symbol not found? It is defined in foo.c? Shouldn't at least ranlib create an index in the library that allows a random order of the files there?

The same code works well under Linux (gcc), and also when the symbol in foo.c is not a char array, but an int.

like image 553
olebole Avatar asked Jun 03 '17 12:06

olebole


People also ask

Can a static library have unresolved symbols?

At link time, a static library can have unresolved symbols in it, as long as you don't need the unresolved symbols, and you don't need any symbol that is in a .o file that contains an unresolved symbol.

What is linking static library?

Static Linking and Static Libraries is the result of the linker making copy of all used library functions to the executable file. Static Linking creates larger binary files, and need more space on disk and main memory. Examples of static libraries (libraries which are statically linked) are, . a files in Linux and .


1 Answers

There is a similar question: Object files not properly added to archive on mac which has this answer:

Option 1:

ar -rs my_archive.a foo.o bar.o other_object_files.o
ranlib -c my_archive.a

Option 2:

libtool -c -static -o my_archive.a foo.o bar.o other_object_files.o

It is -c flag that makes a difference for both options on ranlib and libtool respectively:

-c

Include common symbols as definitions with respect to the table of contents. This is seldom the intended behavior for linking from a library, as it forces the linking of a library member just because it uses an uninitialized global that is undefined at that point in the linking. This option is included only because this was the original behavior of ranlib. This option is not the default.

like image 51
Stanislav Pankevich Avatar answered Oct 15 '22 08:10

Stanislav Pankevich