链接器抱怨“文件是为归档而构建的,不是链接的体系结构”

时间:2018-08-17 11:08:26

标签: macos clang

尝试构建使用clang链接静态库的二进制文件时,出现以下错误消息:

⟩⟩⟩ 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

这是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显示类似的输出。因此:所有目标文件都是针对x86_64构建的。那么此错误消息是什么意思?


这是一个完整的,最小的有效示例,可以重现上面显示的问题:

  • foo.c

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

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

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

编译:

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 

1 个答案:

答案 0 :(得分:0)

该错误消息实际上是令人误解的:问题不是体系结构上的不匹配,而是不能嵌套静态库(.a文件)的事实:

⟩⟩⟩ nm bar.a

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

(请注意,_foo中的条目foo.a丢失了!)

但是,由于ar最初是一种通用的归档实用程序,因此它不会通过以下方式创建嵌套的归档文件:

ar rcs bar.a foo.a bar.o

我们可以通过列出其内容进行验证:

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

要解决此问题,请不要嵌套档案,而应直接打包目标文件:

rm bar.a
ar rcs bar.a foo.o bar.o
clang -o test bar.a test.o