c - 给定目标 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
解决方案
答案最初发表在 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
. 此外,您不必手动调用汇编程序,设置这两个标志就足够了。
推荐阅读
- android - Android Release 版本上的 Xamarin 奇怪错误
- spring-boot - 未经授权的 401 - Spring Boot 服务
- linux - Thingsboard 容器不会在配置更改时更新
- c - 如何在c中计算2个文件的相同1 kb块?
- sql - 如何将存储为 VARCHAR 的 UTC 日期时间值转换为常规日期时间
- javascript - Javascript/Html 游戏的左键单击功能
- javascript - 让一个 NodeJS 程序处理另一个程序的代码
- javascript - How to put background-image over the node borders in cytoscape js?
- javascript - 在 HTML 画布上绘制圆圈时遇到问题
- javascript - Allow create if authenticated, allow update if requested userid corresponds to it