Macos 为什么链接器会抱怨&x201C;文件是为存档而构建的,而存档不是要链接的体系结构”;架构何时正确?

Macos 为什么链接器会抱怨&x201C;文件是为存档而构建的,而存档不是要链接的体系结构”;架构何时正确?,macos,clang,ld,unix-ar,Macos,Clang,Ld,Unix Ar,当尝试使用clang构建链接静态库的二进制文件(请参见下面的MWE)时,我收到以下错误消息: ⟩⟩⟩ 叮当作响的测试棒 ld:警告:忽略文件bar.a,文件是为存档而生成的,而存档不是要链接的体系结构(x86_64):bar.a >架构x86_64的未定义符号: >“_栏”,引用自: >_测试中的主管道。o >“_foo”,引用自: >_测试中的主管道。o >ld:找不到架构x86_64的符号 但是根据lipo,体系结构是正确和一致的(x86_64): ⟩⟩⟩ lipo-info测试.o ba

当尝试使用clang构建链接静态库的二进制文件(请参见下面的MWE)时,我收到以下错误消息:

⟩⟩⟩ 叮当作响的测试棒
ld:警告:忽略文件bar.a,文件是为存档而生成的,而存档不是要链接的体系结构(x86_64):bar.a
>架构x86_64的未定义符号:
>“_栏”,引用自:
>_测试中的主管道。o
>“_foo”,引用自:
>_测试中的主管道。o
>ld:找不到架构x86_64的符号
但是根据
lipo
,体系结构是正确和一致的(x86_64):

⟩⟩⟩ lipo-info测试.o bar.a
输入文件bar.a不是fat文件
非fat文件:test.o是体系结构:x86_64
非fat文件:bar.a is体系结构:x86_64
otools-hv
显示类似的输出所有对象文件都是为x86_64构建的。那么这个错误消息是什么意思呢


下面是一个完整的、最小的工作示例,用于重现上述问题:

  • foo.c

    intfoo(无效){
    返回1;
    }
    
  • bar.c

    int条(无效){
    返回2;
    }
    
  • test.c

    #包括
    int foo(无效);
    内栏(空);
    内部主(空){
    printf(“foo=%d\n”,foo());
    printf(“bar=%d\n”,bar());
    }
    
汇编:

clang-c-o foo.o foo.c
阿福,阿福
叮当作响,砰砰作响
酒吧,一个foo,一个bar,o
叮当声-c-o测试.o测试.c
叮当作响的测试棒

错误消息实际上是误导性的:问题不是架构不匹配,而是静态库(
.a
文件)不能嵌套:

⟩⟩⟩ nm bar.a

bar.a(bar.o):
0000000000000000 T _bar
(请注意,缺少来自
foo.a
的条目
\u foo

但由于
ar
最初是一个通用归档实用程序,因此它通过

ar rcs bar.a foo.a bar.o
我们可以通过列出其内容来验证:

⟩⟩⟩ ar t bar.a
__.SYMDEF SORTED
foo.a
bar.o
要解决此问题,请不要嵌套归档,而是直接打包对象文件:

rmbar.a
ar rcs bar.a foo.o bar.o
叮当作响的测试棒

此错误消息还有许多其他问题,但都与交叉编译导致的实际架构不匹配有关。我问这个问题是因为目前不可能用谷歌搜索和我有同样问题的人的错误信息。希望这对其他人有所帮助。而且,如果有人对轶事感兴趣:调试和修复这个问题花了我好几天的时间在一个复杂的代码库中。