-1

When trying to build a binary (see MWE below) that links a static library using clang I am getting the following error message:

⟩⟩⟩ clang -o test bar.a test.o
ld: warning: ignoring file bar.a, file was built for archive which is not the architecture being linked (x86_64): bar.a
> Undefined symbols for architecture x86_64:  
>   "_bar", referenced from:  
>       _main in test.o  
>   "_foo", referenced from:  
>       _main in test.o  
> ld: symbol(s) not found for architecture x86_64

But the architecture is correct and consistent (x86_64) according to lipo:

⟩⟩⟩ lipo -info test.o bar.a
input file bar.a is not a fat file
Non-fat file: test.o is architecture: x86_64
Non-fat file: bar.a is architecture: x86_64

otools -hv shows similar output. All object files are built for x86_64. So what does this error message mean?


Here’s a complete, minimal, working example to reproduce the problem shown above:

  • foo.c:

    int foo(void) {
        return 1;
    }
    
  • bar.c:

    int bar(void) {
        return 2;
    }
    
  • test.c:

    #include <stdio.h>
    
    int foo(void);
    int bar(void);
    
    int main(void) {
        printf("foo = %d\n", foo());
        printf("bar = %d\n", bar());
    }
    

Compilation:

clang -c -o foo.o foo.c
ar rcs foo.a foo.o

clang -c -o bar.o bar.c
ar rcs bar.a foo.a bar.o

clang -c -o test.o test.c
clang -o test bar.a test.o
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • There are many other questions with this error message but these are all concerned with actual architecture mismatches due to cross-compilation. I’ve asked this question because it’s currently impossible to google the error message for somebody experiencing the same problem as me. Hope this helps somebody else. – Konrad Rudolph Aug 17 '18 at 11:09
  • And, in case anybody is interested in anecdotes: debugging and fixing this issue has taken me several days in a complex code base. – Konrad Rudolph Aug 17 '18 at 11:15

1 Answers1

1

The error message is in fact misleading: The issue isn’t a mismatch in architecture, it’s the fact static libraries (.a files) cannot be nested:

⟩⟩⟩ nm bar.a

bar.a(bar.o):
0000000000000000 T _bar

(Note that the entry _foo from foo.a is missing!)

But since ar is originally a general-purpose archival utility, it has no qualms creating a nested archive via

ar rcs bar.a foo.a bar.o

As we can verify by listing its contents:

⟩⟩⟩ ar t bar.a
__.SYMDEF SORTED
foo.a
bar.o

To fix the problem, don’t nest archives but rather pack the object files directly:

rm bar.a
ar rcs bar.a foo.o bar.o
clang -o test bar.a test.o
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214