ClangLLVM使用

更新时间:2023-04-23 01:23:14 阅读: 评论:0


2023年4月23日发(作者:乾统元宝)

ClangLLVM使⽤

下载和准备⼯作

打算使⽤ clang++ 编译 C++ 程序的注意事项

编译和安装

为了不弄脏 source tree,

建议采⽤ out-of-source build 的⽅式编译。

先到 llvm 以外的地⽅造⼀个⽬录,

然后再下 cmake 来产⽣ Makefile。

configure 的下法我就不写了,

都 2010 年了哪还有傻⼦看见 还会去跑 configure?

当然 没写好或乱写的状况下例外。

cmake 的下法这边以 tcsh 为例:

env CFLAGS=-fno-strict-aliasing CXXFLAGS=-fno-strict-aliasing

cmake -i path/to/llvm/source

或者把src解压后,在主⽬录下⾯如果任何project有⼀个,可以直接在⽬录下建⽴⼀个build⽂件夹。

然后在build⽂件夹下运⾏, cmake ../ (../上⼀级⽬录,也可以是source解压后的绝对路径)

加上 -i 就会以 wizard mode 启动 cmake,

⾼兴的话也可以⽤ cmake-gui 跑。

我知道有⼈看到 -fno-strict-aliasing 会⾮常想笑,

但是不昼造句 加的话光从 warning messages 来看是有⼀定机率编出坏掉的玩具。

这个问题是出在 clang 的 code 上,

所以如果⾛ llvm-gcc 这条路的应该不会遇上。

出来的选项可以学这样填:

Would you like to e advanced options? [No]:

Plea wait while cmake process

Variable Name: CLANG_BUILD_EXAMPLES

Description: Build CLANG example programs.

Current Value: OFF

New Value (Enter to keep current value):

Variable Name: CLANG_TEST_USE_VG

Description: Run Clang tests under Valgrind

Current Value: OFF

New Value (Enter to keep current value):

Variable Name: CMAKE_BUILD_TYPE

Description: Choo the type of build, options are: None(CMAKE_CXX_FLAGS orCMAKE_C_FLAGS ud) Debug Relea

RelWithDebInfo MinSizeRel.

Current Value:

New Value (Enter to keep current value): RelWithDebInfo

Variable Name: CMAKE_INSTALL_PREFIX

Description: Install path prefix, prepended onto install directories.

Current Value: /usr/local

New Value (Enter to keep current value): 就是 make install 以后会装进去的路径

Variable Name: C_INCLUDE_DIRS

Description: Colon parated list of directories clang will arch for headers.

Current Value:

New Value (Enter to keep current value):

Variable Name: LLVM_BUILD_32_BITS

Description: Build 32 bits executables and libraries.

Current Value: OFF

New Value (Enter to keep current value):

Variable Name: LLVM_BUILD_EXAMPLES

Description: Build LLVM example programs.

Current Value: OFF

New Value (Enter to keep current value):

Variable Name: LLVM_BUILD_TOOLS

Description: Build LLVM tool programs.

Current Value: ON

New Value (Enter to keep current value):

Variable Name: LLVM_ENABLE_ASSERTIONS

Description: Enable asrtions

Current Value: ON

New Value (Enter to keep current value):

Variable Name: LLVM_ENABLE_PEDANTIC

Description: Compile with pedantic enabled.

Current Value: ON

New Value (Enter to keep current value): OFF

Variable Name: LLVM_ENABLE_PIC

Description: Build Position-Independent Code

Current Value: ON

New Value (Enter to keep current value):

Variable Name: LLVM_ENABLE_THREADS

Description: U threads if available.

Current Value: ON

New Value (Enter to keep current value):

Variable Name: LLVM_ENABLE_WARNINGS

Description: Enable compiler warnings.

Current Value: ON

New Value (Enter to keep current value):

Variable Name: LLVM_ENABLE_WERROR

Description: Fail and stop if a warning is triggered.

Current Value: OFF

New Value (En参加英文 ter to keep current value):

Variable Name: LLVM_LIBDIR_SUFFIX

Des腌东北酸菜 cription: Define suffix of library directory航天知识科普 name (32/64)

Current Value:

New Value (Enter to keep current value):

Variable Name: LLVM_TABLEGEN

Description: Native TableGen executable. Saves building one whencross-compiling.

Current Value: tblgen

New Value (Enter to keep current value):

Variable Name: LLVM_TARGETS_TO_BUILD

Description: Semicolon-parated list of targets to build, or "all".

Current

Value:Alpha;ARM;Blackfin;CBackend;CellSPU;CppBackend;Mips;MBlaze;MSIL;MSP430;PIC16;PowerPC;Sparc;SystemZ;X86;XCore

New Value (Enter to keep current value): ARM;CBackend;CppBackend;Mips;X86(反正就选⾼兴的⽤,不然⼲脆 all也⾏)

Variable Name: LLVM_TARGET_ARCH

Description: Set target to u for LLVM JIT or u "host" forautomatic detection.

Current Value: host

New Value (Enter to keep current value保险种类介绍 ):

Variable Name: NM_PATH

Description: Path to a program.

Current Value: /usr/bin/nm

New Value (Enter to keep current value):

Plea wait while cmake process

CMake complete, run make to build project.

然后直接⽤ GNU make 编译:

gmake -j9 install

N 可以是⼯作站的 CPU threads 总数 + 1。

⽆法使⽤ CMake 的状况

学习⾃⼰编译和安装的理由

因为我本⾝是做 compiler 的,

所以总有⼀天会需要去修改它们的 source code。

使⽤ OS 提供的套件系统来安装 LLVM,

是纯粹以只会使⽤它的⾓度来考虑。

若是以⼀名开发者的⾓度来企盼 考虑的话,

就需要学习如何⼿动编译及安装到⾃⼰的⽬录下。

基本⽤法

先随便造⼀个范例程序:

Download

#include

int main(int argc,char**argv)

{

("hello worldn");

return 0;

}

直接编译成可执⾏⽂件:

clang test.c -o test

这跟 GCC 没什么差别。

编译成 object file:

clang -c test.c

会得到 test.o,

这也跟 GCC 没什么差别。

输出 asmbly code:

clang -S test.c

会得到 test.s,

还是跟 GCC 没有什么差别。

接下来就是 LLVM 特有的东西了。

-c 搭配 -emit-llvm 会输出 bitcodefile,

你可以把它想成是 target 在 llvm 这平台上的 object file。

-S 搭配 -emit-llvm 会输出所谓的 LLVMasmbly code。

编译成 bitcode file:

clang -c -emit-llvm test.c -o

如果你不加后⾯的 -o 参数,

⽬前我⼿边的版本会输出 test.o 这样的档名。

虽然说 .bc 这种 suffix 只是⼀个建议的命名惯例,

⽽且 llvm 的 command tools 也不会因为 suffix 是 .o ⽽搞混它,

但为了避免⼈类搞近代历史人物 混我建议还是把它输出成带 .bc suffix 的檔名。

这个档案⽤系统的 file 指令测试的话,

应该会告诉你它是个 data ⽽不是 object file。

输出 LLVM asmbly code:

clang -S -emit-llvm test.c -o

⽤ -o 的理由同上,

不加的话你会得到 test.s 这种档名⽽容易跟⼀般asmbly file 混淆。

得到的档案内容会长这样:

View Code TEXT

; ModuleID = 'test.c'

target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-

f80:128:128-n8:16:32:64"

target triple = "x86_64-unknown-linux-gnu"

@.str = private constant [13 x i8] c"hello world0A00" ; <[13 x i8]*> [#us=1]

define i32 @main(i32 %argc, i8** %argv) nounwind {

entry:

%retval = alloca i32, align 4 ; [#us=2]

% = alloca i32, align 4 ; [#us=1]

% = alloca i8**, align 8 ; [#us=1]

store i32 0, i32* %retval

store i32 %argc, i32* %

store i8** %argv, i8*** %

%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0)) ; [#us=0]

%0 = l元旦快乐祝福语 oad i32* %retval ; [#us=1]

ret i32 %0

}

declare i32 @printf(i8*, ...)

以直译的⽅式 (含 JIT 功能) 直接执⾏ bitcode file:

lli

把bitcode file 反组译回 LLVM asmbly code:

llvm-dis

这指令会⾃动输出 这种档名,

所以不必像上⾯那样特地加参数指定。

组译 LLVM asmbly code:

llvm-as

这会得到⼀个新的 。

多档编译与连结

先摆两个测试程序:

Download

void foo();

int main(int argc,char**argv)

{

foo();

return 0;

}

Download

#include

void foo()

{

("hello worldn");

}

编译:

clang -c -emit-llvm test1.c -o

clang -c -emit-llvm test2.c -o

连结:

llvm-link -o

执⾏:

lli

单独执⾏ 和 会发⽣什么事?

函式库的制作与连结

直接沿⽤上⾯的例⼦。

把 封装成 libTest.a:

llvm-ar rucs libTest.a

当然这个并不是普通的 archive file。

查看 symbol table:

llvm-nm libTest.a

连结:

llvm-ld -o test -lTest

这样会得到两个档案。

⼀个是 ,

你可以⽤ lli 去执⾏它。

另⼀个是叫 test 的 script 檔,

⼤概长这样:

View Code BASH

#!/bin/sh

lli=${LLVMINTERP-lli}

exec $lli

${1+"$@"}

其实也不过就是⾃动叫 lli 帮你直译⽽已。

如果你不希望它是⼀个 script 档⽽是真正的可执⾏⽂件,

加上 -native 参数就可以了。

Backend Compiler

如果说 LLVM asmbly code 是 Open64 的 WHIRL 的话,

llc 的地位⼤致上相当于 Open64 的 be。

llc 的主要⽬的是把 bitcode 编译成特定平台的 asmbly code,

⽽要输出哪个平台可以⽤ llc -version 查看:

Registered Targets:

arm - ARM

c - C backend

cpp - C++ backend

mips - Mips

mipl - Mipl

thumb - Thumb

x86 - 32-bit X86: Pentium-Pro and above

x86-64 - 64-bit X86: EM64T and AMD64

因为我在 cmake -i 的时候有删掉⼀些不要的 targets,

所以这⾥可⽤的 targets 会⽐⽤默认值编 LLVM 的⼈少⼀些。

值得注意的是 llc 也有 C 跟 C++ 的 targets。

其实这个也不⽤太意外,

Open64 也是有 whirl2c 等⼀系列的⼯具。

不过相较于⼤部分 target ⼀改就要整套重编⼀份的compiler 来说,

LLVM 在这⽅⾯算是先进多了。

但其实这不过只是软件系统规划能⼒的差别罢了。

举个例⼦,

将 bitcode 编译成 ARM 的 asmbly code:

llc -march=arm

这会得到 test.s。

不过当 target 是 c 或 cpp 时 suffix 就不是 .s。


本文发布于:2023-04-23 01:23:14,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/843565.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:Open64
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图