当体系结构正确时,为什么链接器抱怨"文件是为存档构建的,而不是正在链接的体系结构"?



当尝试构建一个二进制文件(参见下面的 MWE(使用 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,架构是正确的和一致的(x86_64(:

⟩⟩⟩ 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(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 = %dn", foo());
    printf("bar = %dn", bar());
    }
    

汇编:

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

该错误消息实际上具有误导性: 问题不在于架构不匹配,而在于静态库(.a文件(无法嵌套:

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

(请注意,缺少foo.a的条目_foo

但是,由于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

相关内容

  • 没有找到相关文章