Clang学习历程 概述

介绍

Clang

ClangLLVM(Low Level Virtual Machine)项目提供的工具链中的编译器的前端部分

LLVM项目是模块化和可重用的编译器和工具链技术的集合,LLVM的一大特色就是,有着独立的、完善的、严格约束的中间代码表示。这种中间代码,就是LLVM的字节码,是LLVM抽象的精髓,前端生成这种中间代码,后端自动进行各类优化分析,让用LLVM开发的编译器,都能用上最先见的后端优化技术。

编译器编译流程如下



编译流程

来自《编译原理》

编译器分成前端与后端两部分

前端负责处理源代码,后端负责生成目标代码


来自参考链接3

环境

macOS Hign Sierra 10.13.6
Xcode10.1

编译

获取llvm源代码

1
% git clone https://git.llvm.org/git/llvm.git/

获取Clang源代码

1
2
% cd llvm/tools
% git clone https://git.llvm.org/git/clang.git/

获取compiler-rt源代码

1
2
3
## 定位到llvm工程目录下
% cd llvm
% git clone https://git.llvm.org/git/compiler-rt.git/

获取libomp源代码

1
2
% cd llvm
% git clone https://git.llvm.org/git/openmp.git/

获取libcxxlibcxxabi源代码

1
2
3
% cd llvm
% git clone https://git.llvm.org/git/libcxx.git/
% git clone https://git.llvm.org/git/libcxxabi.git/

获取测试用例

1
2
% cd llvm
% git clone https://git.llvm.org/git/test-suite.git/

Clang 使用CMake(一个用于构建,测试和打包软件的开源跨平台工具系列)进行构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# LLVM 禁止源码内编译(in-tree build is not supported),创建一个与llvm工程同级的build目录
% cd src/
% mkdir build
% cd build

## 安装cmake
% brew install cmake

## -G <generator-name>
## Specify a build system generator.
## cmake [{-D <var>=<value>}...] -P <cmake-script-file>
## Create or update a cmake cache entry.

## When cmake is first run in an empty build tree, it ## creates a CMakeCache.txt file and populates it with customizable settings for
## the project. This option may be used to specify a setting that takes priority over the projectas default value. The option may
## be repeated for as many cache entries as desired.
## 会被存在build目录下的CMakeCache.txt中
## -Wno-dev 忽略开发警告
% cmake -G Ninja ../llvm/ \
-DCMAKE_INSTALL_PREFIX=/opt/llvm \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_FFI=ON \
-DLLVM_BUILD_LLVM_DYLIB=ON \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DLLVM_TARGETS_TO_BUILD="host;AMDGPU" \
-Wno-dev

## 安装 ninja
## Ninja is a small build system with a focus on speed.
## It differs from other build systems in two major respects: it is designed to have its input files generated by a higher-level build system, and it is designed to run builds as fast as possible.
% brew install ninja

## -j N run N jobs in parallel [default=6, derived from CPUs available]
## CMake Error at cmake_install.cmake:36 (file):
## file INSTALL cannot set permissions on "/opt/llvm/include/llvm"
## 加上sudo
% sudo ninja -j4 install

替换Clang

1
2
3
4
5
6
7
8
9
## 查看系统的Clang的位置
~% which clang
/usr/bin/clang

~% clang -v
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

根据参考链接7

新建Xcode工程

创建用户自定义配置CC,并设置DEBUG时的值为编译完成后Clang二进制的位置。

⌘ B 编译,查看编译输出的日志,证明已经使用了编译的Clang

错误原因:

1
Unknown argument: '-index-store-path'

根据参考链接10,在Build Setting 中搜索index并将Enable Index-While-Building Functionality选项设置为NO

⌘ B

错误原因:

1
2
3
4
5
6
fatal error: error in backend: No available targets are compatible with triple "arm64-apple-ios9.0.0"
clang-8: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 8.0.0 (https://git.llvm.org/git/clang.git/ a6eb16ed631365f3bbadd0450ab52746c151794d) (https://git.llvm.org/git/llvm.git/ 1c98a2b870d058132698ae4d67ef954b13dc41b4)
Target: aarch64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /opt/llvm/bin

分析: 因为该手机架构是arm64cmake编译时指定的是 -DLLVM_TARGETS_TO_BUILD="host;AMDGPU",并没有对应的架构

HowToBuildOnARM

cmake $LLVM_SRC_DIR -DCMAKE_BUILD_TYPE=Release \
-DLLVM_TARGETS_TO_BUILD=”ARM;X86;AArch64”

操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 重新编译
% cmake -G Ninja ../llvm/ \
-DCMAKE_INSTALL_PREFIX=/opt/llvm \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_FFI=ON \
-DLLVM_BUILD_LLVM_DYLIB=ON \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DLLVM_TARGETS_TO_BUILD="host;ARM;X86;AArch64" \
-Wno-dev

## 确认
% grep -r "LLVM_TARGETS_TO_BUILD" CMakeCache.txt
CMakeCache.txt:LLVM_TARGETS_TO_BUILD:STRING=host;ARM;X86;AArch64

## 安装 只会处理有变更的部分
% sudo ninja -j4 install

⌘ B 成功

代码

TryLLVM

参考

  1. llvm.org
  2. 结构化编译器前端 Clang 介绍
  3. 编译器架构的王者LLVM
  4. cmake.org
  5. wiki-XcodeVersionInfo
  6. 下载标准库libcxx出现svn: E000104: Error running context: Connection reset by peer的解决方案
  7. 安装 LLVM + Clang
  8. 如何让Xcode使用clang的替代版本
  9. Why can’t I create a directory under /opt without sudo
  10. compilation-error-when-using-xcode-9-0-with-clang-cannot-specify-o-when-genera