网络上关于 Open64 的资料很少,自己安装也花了很长时间,因此将安装过程整理出来。
我使用的是 w2ll 分支,对应的 Tags 为「clang-prebuilt」,系统是 ubuntu 20.04,最后使用以下方法成功安装的时间是:2023 年 09 月 01 日。
从 github open64/tree/w2ll 下载源码并解压。
安装一些先决条件:
sudo apt update
sudo apt install build-essential
sudo apt install git
sudo apt install emacs
sudo apt install cmake
sudo apt install bison
sudo apt install flex
sudo apt install g++-riscv64-linux-gnu
下载「clang-11.0.0.tar.xz」依赖项,使用 tar -xvf clang-11.0.0.tar.xz
解压到 open64/opt 目录下。
安装 openjdk 和 gradle 以支持 java:
# 安装 java8,一定要用 java8
sudo apt install openjdk-8-jdk
# 列出系统中所有可用的 java 版本,输入 java8 前面对应的编号
sudo update-alternatives --config java
# 查看 Java 版本
java -version
# 安装 gradle
sudo apt install gradle
设置环境变量:
# 此时应该在 open64 目录下
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HOME=`pwd`
export CLANG_HOME=$HOME/opt/x86_64
export LLVM_HOME=$CLANG_HOME
export PATH=$CLANG_HOME/bin:$PATH
export PATH=$HOME/local/bin:$PATH
export PATH=$HOME/local/lib/gcc-lib/x84_64-open64-linux/5.0:$PATH
随后创建用于构建的文件夹:
mkdir local
mkdir build && cd build
目录结构应该如下:
open64
├── opt/
│ └── release
├── open64-w2ll/
│
└── local/
│
└── build/
配置 configure:
# 在 build 目录下执行该命令
../open64-w2ll/configure --host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-fortran --with-build-product=OPEN64 --with-build-optimize=DEBUG --disable-multilib --prefix=$HOME/local
执行完后会有如下提示信息,MAPLE 是用于连接 open64 和 ark compiler 的,不用设置直接 make 就行:
checking MAPLE_HOME is set ...no
==========================================================
please set MAPLE_HOME which include the maple prebuilt libs
**** js2mpl and mpl2whirl won't be built ****
==========================================================
checking MOZJS_HOME is set ...no
==========================================================
please set MOZJS_HOME which include the mozjs prebuilt libs
**** js2mpl won't be built ****
==========================================================
接着执行下列命令:
make -j10
make install
make 可以顺利执行,因为需要下载一些东西,若网络不好可能会出错,出错时可以用 make -j1
下载所需的文件。
make install 执行完会有如下报错:
osprey/targdir_lib/libacml_mv/libacml_mv.a does not exist
osprey/targdir_lib/libacml_mv/libacml_mv.so.1 does not exist
这个也不用管,libacml_mv
现在已被弃用了。
可执行文件在 local/bin
目录下,可以直接使用。
首先使用下面的命令获取镜像:
sudo docker pull opencc/open64:llvm15.w2ll
该过程可能比较慢,使用国内镜像加速也没效果。
接着,使用该镜像创建一个容器:
sudo docker run -it 1be /bin/bash
创建用于构建的文件夹:
mkdir build && cd build
配置 configure:
../open64/configure --host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-fortran --with-build-product=OPEN64 --with-build-optimize=DEBUG --disable-multilib --prefix=$HOME/local
接着执行下面的命令:
make -j10
make install
首先,使用 open64 生成 .B/.I/.O 文件:
opencc -clang -emit-llvm -I/usr/lib/gcc/x86_64-linux-gnu/9/include -fno-exceptions -O3 -OPT:malloc_alg=off -PHASE:c=off -c -sw -kp hello.c
如果提示找不到 stddef.h
,一定要指定 /usr/lib/gcc/x86_64-linux-gnu
目录下的 stddef.h
,目前 open64 还不支持 llvm 的 libc。
接着使用 ir_b2a 将 WHIRL IR 从字节码形式转化为 ASCII 形式:
ir_b2a hello.O
然后可以得到以下内容:
LOC 0 0 source files: 1 "/home/qgw/SRC/open64/local/hello.c"
LOC 0 0 source files: 2 "/usr/include/stdio.h"
FUNC_ENTRY <1,50,main> {line: 1/3}
BODY
BLOCK {line: 0/0}
PRAGMA 0 72 0 (0x0) # WOPT_FINISHED_OPTIMIZATION {line: 0/0}
END_BLOCK
BLOCK {line: 0/0}
END_BLOCK
BLOCK {line: 1/3}
PRAGMA 0 119 0 (0x0) # PREAMBLE_END {line: 1/3}
U8LDA 0 <1,52,(13_bytes)_"hello_world\n\000"> T<57,anon_ptr.,8>
U8PARM 2 T<55,anon_ptr.,8> # by_value
VCALL 126 <1,51,printf> # flags 0x7e {line: 1/5}
U4INTCONST 0 (0x0)
I4STID 1 <1,5,.preg_I8> T<4,.predef_I4,4> # $1 {line: 1/6}
RETURN {line: 1/6}
END_BLOCK
可以使用下面的命令获取 WHIRL IR 的符号表:
ir_b2a -st2 sum.O
w2ll 编译成功后并没有放在 open64/local/bin 目录下,而是放在 open64/build/osprey/targdir/ir_tools 目录下。
使用 w2ll 时会有如下报错:
$ w2ll
w2ll: error while loading shared libraries: be.so: cannot open shared object file: No such file or directory
只需要将 be.so 添加到搜索路径即可:
export LD_LIBRARY_PATH=/open64/build/osprey/targdir/ir_tools:$LD_LIBRARY_PATH
这时使用 w2ll 会显示如下内容:
$ w2ll
Usage: w2ll [-a] <Whirl IR>
下面是将 WHIRL IR 转成 IIVM IR 的示例,有如下 C 代码:
#include
int main() {
printf("hello world\n");
return 0;
}
先使用如下指令生成二进制形式的 WHIRL IR:
opencc -clang -emit-llvm -I/usr/lib/gcc/x86_64-linux-gnu/9/include -fno-exceptions -O3 -OPT:malloc_alg=off -PHASE:c=off -c -sw -kp hello.c
接着使用 w2ll 生成 LLVM IR:
w2ll hello.O -all
生成的 LLVM IR 保存在 hello.O.ll。
; ModuleID = 'hello.O'
source_filename = "hello.O"
@0 = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1
@llvm.global_ctors = appending global [0 x { i32, ptr, ptr }] zeroinitializer, section ".ctor"
@str = private unnamed_addr constant [12 x i8] c"hello world\00", align 1
; Function Attrs: nounwind
declare signext i32 @printf(ptr, ...) #0
; Function Attrs: nounwind
define signext i32 @main() #0 {
entry:
%puts = call i32 @puts(ptr nonnull @str)
ret i32 0
}
; Function Attrs: nofree nounwind
declare noundef i32 @puts(ptr nocapture noundef readonly) #1
attributes #0 = { nounwind "target-features"="+a,+c,+d,+f,+m,+relax" }
attributes #1 = { nofree nounwind }
对于上面简单的例子,w2ll 可以正常工作。但使用 s2102.c 试验发现有如下报错,目前 w2ll 还处于开发状态,没开发完。
### Assertion failure ../../../../open64-w2ll/osprey/ir_tools/whirl2llvm.cxx:1903:
### CreateExt: rhs should be floating type
### For s2102.O in s2102