LLVM和Clang无法为支持的架构编译

12

在 Ubuntu 64 位系统中,我遇到了以下问题:

llc --version
LLVM (http://llvm.org/):
  LLVM version 3.1
  Optimized build with assertions.
  Built Oct 15 2012 (18:15:59).
  Default target: x86_64-pc-linux-gnu
  Host CPU: btver1

  Registered Targets:
    arm      - ARM
    mips     - Mips
    mips64   - Mips64 [experimental]
    mips64el - Mips64el [experimental]
    mipsel   - Mipsel
    thumb    - Thumb
    x86      - 32-bit X86: Pentium-Pro and above
    x86-64   - 64-bit X86: EM64T and AMD64

我做不了这个

clang -march=arm -x c++ /tmp/cpp.cpp 
error: unknown target CPU 'arm'

我在这里缺少了什么?为什么我无法编译成 ARM 架构?

7个回答

11

-march是LLVM的内部工具命令行选项,与clang没有任何关系。如果您需要为其他目标编译,则需要指定目标三元组。有几种方法可以实现这一点(我不记得是否在3.1中工作,但它们绝对适用于3.2):

  • 将clang链接到您的目标三元组clang,例如arm-none-linux-gnueabi-clang,并通过它编译所有内容
  • 提供-target选项,例如clang -target arm-none-linux-gnueabi

选项确实不是 --target(前面有两个连字符)吗? - Serge Rogatch
@SergeRogatch 两种写法都是有效的。但在前面加一个连字符时,关键词之间需要加一个空格,例如 -target arm-none-linux-gnueabi;而在前面加两个连字符时,则需要加上等号 =,例如 --target=arm-none-linux-gnueabi - Celuk

7

要获取clang编译器的选项列表,请使用:

clang -cc1 -help

要指定目标,请使用-triple

clang -cc1 -triple "arm-vendor-os" 文件名

其中,“vendor”和“os”应替换为实际的供应商和操作系统名称。也可以替换为unknown

-triple是一个形式为ARCHITECTURE-VENDOR-OSARCHITECTURE-VENDOR-OS-ENVIRONMENT的字符串。例如:x86_64-apple-darwin10


1
clangпј€3.6пј‰жІЎжњ‰-tripleйЂ‰йЎ№ -> error: unknown argumentпј€д№џдёЌењЁ-helpдё­пј‰ - Knut

6
LLVM链接器仅链接到主机,而不是列表中的所有目标。它肯定会为任何目标编译。基本上,clang将C/C++转换为字节码,然后llc将字节码转换为特定目标的汇编代码(新的实验选项可直接将字节码转换为对象文件),然后您需要获取交叉汇编器和交叉链接器将其推向最终阶段(我使用GNU binutils)。不幸的是,我发现clang到字节码并非完全通用(我曾希望并期望它是通用的),实际上它根据目标更改了独立于目标的输出。以下示例使用主机三元组而不是使用-march允许我的示例在更多主机上正常构建。
ARMGNU?=arm-none-eabi
LOPS = -Wall -m32 -emit-llvm -ccc-host-triple $(ARMGNU)
OOPS = -std-compile-opts
LLCOPS = -march=thumb -mtriple=$(ARMGNU)

    clang $(LOPS) -c blinker03.c -o blinker03.clang.bc
    opt $(OOPS) blinker03.clang.bc -o blinker03.clang.thumb.opt.bc
    llc $(LLCOPS) blinker03.clang.thumb.opt.bc -o blinker03.clang.thumb.opt.s
    $(ARMGNU)-as blinker03.clang.thumb.opt.s -o blinker03.clang.thumb.opt.o
    $(ARMGNU)-ld -o blinker03.clang.thumb.opt.elf -T memmap vectors.o blinker03.clang.thumb.opt.o

我还没有尝试过,但不久之后会尝试直接使用llc到对象(实际上我已经在简单测试中尝试过了,但还没有在任何大型项目或发布的地方使用它)。


通过将每个源文件编译为IR,然后使用llvm-link将它们组合起来,您可以优化整个应用程序,而不是优化每个单独的文件,在理论上会产生更好的结果,但在实践中,GNU仍然会生成稍微快一些的代码(逐个优化文件)。请注意,我的基准测试非常有限(但随着时间的推移,GCC变得越来越差,LLVM对至少一个开源库变得越来越好)。 - old_timer

3
你搞混了标志。clang的-march=需要一个处理器系列。你可能想使用clang -arch arm

clang -arch arm -x c++ /tmp/cpp.cpp导致clang: warning: argument unused during compilation: '-arch arm',这并没有解决我的问题。 - user1849534
@user1849534:好奇,您使用的是哪个版本的clang?我的clang-421有“-arch”标志。 - Lily Ballard
3
-arch 选项仅适用于 Darwin 系统。 - Anton Korobeynikov
@Anton 现在-arch应该也可以在“标准”clang上使用。我相信我已经在Ubuntu上使用clang了。 - LeoTh3o
@LeoTh3o - 这可能是Ubuntu本地的问题。正确的方法是使用-target。 - Anton Korobeynikov
显示剩余3条评论

2

正如这个评论所说,该选项目前在Linux下尚不支持。


0
"

-arch arm

"在clang中等同于"

-arch armv4t

"。我认为使用"-march="时不允许使用通用的"arm"目标,应该需要更精确的指定,例如"armv6"、"thumbv7"、"armv4t"等。
尝试选择一个特定的子架构。

使用“thumbv7”的提示很有帮助。我给你点赞。 - srking

0

从Clang 11(trunk)开始,可以使用新添加的-print-targets标志方便地打印支持的目标架构列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接