LLVM/RVV-LLVM 环境搭建
LLVM是什么
LLVM可以简单地理解为是类似GCC的一种编译器,但是他在模型架构上和GCC编译器完全不同,与GCC相比,LLVM将编译的三个部分(前端,优化器,后端)尽可能的解耦,对所有语言使用统一的LLVM IR作为中间代码,因此LLVM需要实现新语言的编译时,不需要修改全部的三个部分,减少了工作量。
LLVM的安装
依赖环境
GCC:
编译安装LLVM需要本机GCC版本高于5.1
,而一般CentOS 7 系统默认版本为 4,8,5
因此需要升级GCC编译器
在这里提供两种方法,使用开发工具包管理GCC(推荐,因为比较省事)
另一种方法,编译最高版本GCC(我就是这样子安装的,编译时间很长,花了一上午,而且挖下了巨坑)
下载源码:
从gcc的源码仓库选责自己想要的GCC版本下载,我这边选择的是GCC 9.2
下载并解压
# 下载gcc-9.2.0并解压 wget http://ftp.gnu.org/gnu/gcc/gcc-9.2.0/gcc-9.2.0.tar.gz tar -zxvf gcc-9.2.0.tar.gz
安装依赖:
# 下载gcc-9.2.0并解压 cd gcc-9.2.0 #下载依赖 ./contrib/download_prerequisites
下载完成应该有如下四个依赖包
gmp-*.tar.bz2
isl-*.tar.bz2
mpc-*.tar.bz2
mpfr-*.tar.bz2
全部解压,编译,安装(这里只演示一个依赖包的安装,其他的都一样)
#解压 tar -xf /root/gcc-tool/gmp-4.3.2.tar.bz2 # 安装 cd gmp-4.3.2 ./configure make make install
正式安装GCC
# 回到gcc的根目录 cd /gcc-9.2.0 ./configure \ --enable-checking=release \ --enable-languages=c,c++ \ --disable-multilib \ make -j4 make install
此处耗时数小时。
- .切换GCC到新版
确定新安装的GCC的路径,一般默认在/usr/local/bin
下。可以先updatedb,然后locate gcc-9.2|tail找一下ls /usr/local/bin | grep gcc
添加新GCC到可选项,倒数第三个是名字,倒数第二个参数为新GCC路径,最后一个参数40为优先级,设大一些之后就自动使用新版了update-alternatives --install /usr/bin/gcc gcc /usr/local/bin/i686-pc-linux-gnu-gcc 40
拉取LLVM代码
由于RVV-LLVM和LLVM的安装流程完全一样,所以这里只提一次:
# LLVM
git clone https://github.com/llvm/llvm-project.git
# RVV-LLVM
git clone https://github.com/isrc-cas/rvv-llvm.git
编译源码
创建build文件夹
mkdir build
生成Makefile
cmake \ -G "Unix Makefiles" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi" \ -DCMAKE_INSTALL_PREFIX=/opt/llvm \ -DCMAKE_CXX_COMPILER=/usr/local/bin/c++ \ -DCMAKE_C_COMPILER=/usr/local/bin/gcc \ ../llvm
这里要挨个讲解一下参数的意思:
-G
:构建系统生成器,可选的值有Ninja,Unix Makefiles,Visual Studio,Xcode
,各个参数的意思在文档里-DCMAKE_BUILD_TYPE
:生成安装包的类型,可选的值有Debug,Release
,据说编译LLVM很吃内存,而Release比较省内存-DLLVM_ENABLE_PROJECTS
:要另外构建的LLVM子项目的列表,以分号分隔。可以包括以下任何一项:clang,clang-tools-extra,libcxx,libcxxabi,libunwind,lldb,compiler-rt,lld,poly或debuginfo-tests。-DCMAKE_INSTALL_PREFIX
:指定要安装LLVM工具和库的完整路径-DCMAKE_CXX_COMPILER
与-DCMAKE_C_COMPILER
:指定编译使用的GCC的路径,如果使用开发工具包管理GCC安装的新版本GCC,可能直接用默认环境变量的GCC就可以。
一个大坑
因为我是编译安装的,所以环境变量出现了问题,无法找到9.2版本的GCC用的还是4.8.5,所以需要显式指定编译器路径
正式编译
nohup make -j4 & # -j4 表示并发执行 4 个任务,这个数字指定 CPU 核心数为佳
编译时间很长,通常在一个小时以上,而我自己作死,LLVM和RVV-LLVM一起编译,现在shell都连接不进去。也不知道什么时候结束。
又有一个大坑
因为我是编译安装的,只指定了新版GCC编译工具,但是动态库使用的还是旧版的,所以还需要处理动态库
编译过程中会报错/usr/lib64/libstdc++.so.6: version 'GLIBCXX_3.4.21' not found
源码编译升级安装了gcc
后,编译程序或运行其它程序时,有时会出现类似/usr/lib64/libstdc++.so.6: version GLIBCXX_3.4.21' not found
的问题。这是因为升级gcc
时,生成的动态库没有替换老版本gcc
的动态库导致的,将gcc
最新版本的动态库替换系统中老版本的动态库即可解决。
运行以下命令检查动态库:
strings /usr/lib64/libstdc++.so.6 | grep GLIBC
查看输出结果,没有需要的GLIBCXX_3.4.21
。
问题处理
回到编译GCC的源码路径下,执行命令
find ./ -name "libstdc++.so*"
输出如下:
/home/gcc-9.2.0/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so
/home/gcc-9.2.0/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
/home/gcc-9.2.0/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.27 //9.2的最新动态库
……
将上面的最新动态库libstdc++.so.6.0.21
复制到/usr/lib64
目录下:
cp /gcc-9.2.0/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.27 /usr/lib64
复制后,修改系统默认动态库的指向,即:重建默认库的软连接。
切换工作目录至/usr/lib64
:
cd /usr/lib64
删除原来软连接:
rm -rf libstdc++.so.6
将默认库的软连接指向最新动态库:
ln -s libstdc++.so.6.0.27 libstdc++.so.6
默认动态库升级完成。重新运行以下命令检查动态库:
strings /usr/lib64/libstdc++.so.6 | grep GLIBC
就可以看到需要的版本了。
安装
make install
Getting Started with the LLVM System