首页 > 解决方案 > 给定目标 x86_64-windows 时 Clang 输出垃圾标签

问题描述

我正在使用 clang 在 Mac 上为 Windows 交叉编译一个程序,我的组装步骤失败了,因为 clang 在编译时输出了奇怪的标签。

给定输入文件:

int main(void) {
    const char *msg = "test";
    return 0;
}

并使用该命令编译到主机clang test.c -S会提供良好的汇编输出,即

    .section    __TEXT,__text,regular,pure_instructions
    .build_version macos, 11, 0
    .globl  _main                           ## -- Begin function main
    .p2align    4, 0x90
_main:                                  ## @main
    .cfi_startproc
## %bb.0:                               ## %entry
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    xorl    %eax, %eax
    movl    $0, -4(%rbp)
    leaq    L_.str(%rip), %rcx
    movq    %rcx, -16(%rbp)
    popq    %rbp
    retq
    .cfi_endproc
                                        ## -- End function
    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz  "test"

.subsections_via_symbols

然而,交叉编译clang test.c -S -target x86_64-windows产生几乎相同的输出,除了字符串常量的标签是垃圾。输出正好是

    .text
    .def     @feat.00;
    .scl    3;
    .type   0;
    .endef
    .globl  @feat.00
.set @feat.00, 0
    .file   "test.c"
    .def     main;
    .scl    2;
    .type   32;
    .endef
    .globl  main                            # -- Begin function main
    .p2align    4, 0x90
main:                                   # @main
.seh_proc main
# %bb.0:                                # %entry
    subq    $16, %rsp
    .seh_stackalloc 16
    .seh_endprologue
    xorl    %eax, %eax
    movl    $0, 12(%rsp)
    leaq    "??_C@_04CEJDCDCH@test?$AA@"(%rip), %rcx
    movq    %rcx, (%rsp)
    addq    $16, %rsp
    retq
    .seh_handlerdata
    .text
    .seh_endproc
                                        # -- End function
    .section    .rdata,"dr",discard,"??_C@_04CEJDCDCH@test?$AA@"
    .globl  "??_C@_04CEJDCDCH@test?$AA@"    # @"??_C@_04CEJDCDCH@test?$AA@"
"??_C@_04CEJDCDCH@test?$AA@":
    .asciz  "test"

    .addrsig

这些奇怪的标签导致我的汇编程序因错误而失败

Error: invalid character '?' in operand 1

有没有办法切换到非交叉编译输出的正常标签?

请注意,当我在 Mac 上时,我没有使用 Xcode clang,而是clang从源代码构建。运行clang --version给出:

clang version 11.0.0
Target: x86_64-apple-darwin20.2.0
Thread model: posix
InstalledDir: /usr/local/bin

标签: cclang

解决方案


答案最初发表在 HolyBlackCat 的评论中:

在为 Windows 构建时,Clang 可以在 MSVC 兼容模式或 MinGW/GCC 兼容模式下运行(并且需要安装相应的编译器才能正常运行)。看来您获得了 MSVC 模式,您可以通过clang --target x86_64-windows --version打印来确认x86_64-unknown-windows-msvc。您可能需要 MinGW 模式,因此您应该使用--target x86_64-w64-windows-gnu.您还必须使用--sysroot. 此外,您不必手动调用汇编程序,设置这两个标志就足够了。


推荐阅读