[折腾]编译 merlin compiler
背景:为了测试 HLS ,需要 merlin compiler 这个 VLS 编译器。这个库需要
gcc 4.9.4 llvm6 以及
零、阅读须知
⚠先弄好好gcc4.9.4然后开始后面llvm、boost、clang库的处理。
这是一个老项目了,不确定使用最新的库文件是否正常编译。且本教程最后只能编译得到编译器本身,附带的一些功能仍然编译失败。
一、gcc4.9.4
1、准备工作
从以下位置下带源代码。
一并下载编译gcc所需的依赖库。 1
2
3wget ftp://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2 -o gmp.tar.bz2
wget https://www.mpfr.org/mpfr-3.1.0/mpfr-3.1.0.tar.bz2 -o mpfr.tar.bz2
wget https://ftp.gnu.org/gnu/mpc/mpc-1.0.1.tar.gz -o mpc.tar.gz
2、开始编译
进入gcc文件目录cd ./gcc.4.9.4,然后设定编译参数:
1
./configure --prefix=[使用本地目录即可]/gcc4 --enable-bootstrap --enable-checking=release --enable-languages=c,c++1
make -j 1
3、错误修复
这编译多是一件美事啊,编,TNND,为什么不编
因为现在系统环境上默认的 gcc 11.3 及其之后的版本默认带
c++17 标准,所以编译路上会有很多错误。 >
⚠注意以下解决方案中的 cd 路径需要根据实际情况自行修改,不可照抄
a、type bool in operator++ is forbidden in c++1789
原因:因为 C++17 标准不允许 bool 变量使用 ++ 操作符。 1
../.././gcc/reload1.c: In function ‘void init_reload()’:../.././gcc/reload1.c:89:24: error: use of an operand of type ‘bool’ in ‘operator++’ is forbidden in C++1789 | (this_target_reload->x_spill_indirect_levels)| ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~1
cd ./host-x86_64-unknown-linux-gnu/gcc-std=c++11 重新执行,然后回到上层目录重新
make -j 1 即可。
b、dereferencing pointer to incomplete type
原因:数据类型不匹配。 1
2
3
4./md-unwind-support.h: 在函数'x86_64_fallback_frame_state'中:
./md-unwind-support.h:65:47: 错误: dereferencing pointer to incomplete type
sc = (struct sigcontext *) (void *) &uc_->uc_context;
make[3]: *** [../.././libgcc/shared-object.mk:14: unwind-dw2.o] 错误 11
2
3./md-unwind-support.h: 在函数‘x86_fallback_frame_state’中:
./md-unwind-support.h:141:18: 错误: 字段‘uc’的类型不完全
struct ucontext uc;1
cd [path to gcc]/gcc4.9.4/x86_64-unknown-linux-gnu/libgcc1
2
3struct ucontext *uc_ = context->cfa
// 改成
struct ucontext_t *uc_ = context->cfa1
2
3struct ucontext uc;
// 改成
struct ucontext_t uc;
c、Handler_stack未定义
原因不知道。 1
2
3../../.././libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc: 在函数‘int __sanitizer::TracerThread(void*)’中:
../../.././libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc:241:22: 错误: 聚合‘sigaltstack handler_stack’类型不完全,无法被定义
struct sigaltstack handler_stack;sanitizer_common/sanitizer_linux.h 去掉其中的
struct sigaltstack; 并把之后出现的两处
struct sigaltstack 换成 void 。 - 打开
sanitizer_common/sanitizer_linux.cc 文件出现的两处
struct sigaltstack 换成 void 。 - 打开
sanitizer_common/sanitizer_stoptheworld_linux_libcedep.cc
把 struct sigaltstack handler_stack; 换成
stack_t handler_stack 。 - 打开
tsan/rtl/tsan_platform_linux.cc 文件把
__res_state *statp = (__res_state*)state; 换成
struct __res_state *statp = (struct __res_state*) state;
。
d、SIGSEGV undefined
错误原因不知道。 1
2
3../../.././libsanitizer/asan/asan_linux.cc: 在函数‘bool __asan::AsanInterceptsSignal(int)’中:
../../.././libsanitizer/asan/asan_linux.cc:107:20: 错误: ‘SIGSEGV’在此作用域中尚未声明
return signum == SIGSEGV && flags()->handle_segv;libsanitizer/asan/asan_linux.cc 中添加头文件
#include <signal.h> 即可。
二、LLVM6.0.0
1、准备工作
从这个链接下载 llvm6 的源码。
2、开始编译
1 | |
然后不需要执行make
install在build文件夹下会存在编译好的结果,把build文件夹放到merlin
compiler/trunk/lib下即可。同时改名与merlin_setting.sh中的LLVM_ROOT_DIR变量一致。
这里就改名为 llvm6.0.0 。
三、Clang6.0.0
参考LLVM6那一节,已经下载好源代码了。llvm这个项目的特点是,所有的库都需要llvm-project-llvmorg-6.0.0/llvm为编译的起始点,通过设置不同的DLLVM_ENABLE_PROJECTS变量改变编译的对象,可选的对象是底下每一个文件夹。
## 1、开始编译
1 | |
可以运行以下指令进行llvm编译结果测试,当然前面的-DLLVM_BUILD_TESTS=ON才行。
1
2ninja check # Test LLVM Only
ninja clang-test # Test Clang Onlymake install,把build文件夹放到merlin compiler/trunk/lib下即可。同时改名与merlin_setting.sh中的LLVM_ROOT_DIR变量一致。
这里就改名为 llvm6.0.0 。
四、boost1.67.0
从链接获得源码(记得解压),存放到merlin_compiler/trunk/source-opt/lib目录下,并修改bootstrap.sh的PREFIX变量如下(⚠要和merlin_setting.sh的设置一致)。
1 | |
然后,会自动在目录下生成b2和bjam两个指令脚本,确保安装gcc和g++,一般不会有bug。
五、编译merlin_compiler主体
1、准备工作
在上面编译过程中多次修改 merlin_setting.sh
文件,这里干脆放出最终修改版本(TODO) 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#######################################
# Merlin
#######################################
export MERLIN_COMPILER_HOME=/home/w/DSE/merlin-compiler/trunk
export MERLIN_PATH=$MERLIN_COMPILER_HOME/source-opt/lib
export llvm_path=$MERLIN_PATH/llvm6.0.0
export deps_path=$MERLIN_PATH/
export clang_path=$MERLIN_PATH/llvm6.0.0/bin
export rose_path=$MERLIN_PATH/rose
export rjson_path=$MERLIN_PATH/rapidjson
export gcc_path=$MERLIN_PATH/gcc4
export boost_path=$MERLIN_PATH/boost
export MERLIN_DEPS=$deps_path
export LLVM_ROOT_DIR=$llvm_path
export CLANG_ROOT_DIR=$llvm_path
export ROSE_ROOT_DIR=$rose_path
export RAPIDJSON_ROOT_DIR=$rjson_path
export GCC_ROOT_DIR=$gcc_path
export BOOST_ROOT=$boost_path
export PATH=$gcc_path/bin/:$PATH
export PATH=$llvm_path/bin/:$PATH
#lib32 if lib64 is not available
export LD_LIBRARY_PATH=$gcc_path/lib64:$llvm_path/lib:$LD_LIBRARY_PATH
export LIBRARY_PATH=$llvm_path/lib
export PATH=$MERLIN_COMPILER_HOME/build/bin:$PATHmerlin_compiler主文件夹下,执行:
1
2
3
4
5
6source ./merlin_setting.sh
mkdir trunk/build
cd trunk/build
# 我也是绷不住了,默认 python3 执行会报错,只好指定 python2
cmake -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=/usr/bin/python2 ..
make -j 1
2、错误修复
a、GLIBCXX_3.4.22 not found
问题原因:gcc4.9.4自带的libstdc++版本太老(我是真不明白,为什么merlin指定编译环境4.9.4,又出现libstdc++版本不够的问题,只能认为写merlin时的服务器很老很老)。
1
2
3
4
5
6$ make -j 1
/usr/bin/cmake: /home/w/DSE/merlin-compiler/trunk/source-opt/lib/gcc4/lib64/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by /usr/bin/cmake)
/usr/bin/cmake: /home/w/DSE/merlin-compiler/trunk/source-opt/lib/gcc4/lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by /usr/bin/cmake)
/usr/bin/cmake: /home/w/DSE/merlin-compiler/trunk/source-opt/lib/gcc4/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/bin/cmake)
Makefile:1783: recipe for target 'cmake_check_build_system' failed
make: *** [cmake_check_build_system] Error 1libstdc++就好,比如我从/usr/lib/gcc环境(即服务器上的高版本gcc)中借一个。在借之前先保存原版,然后搜索本地的高版本gcc中的libstdc++的文件位置替换gcc4.9.4的libstdc++文件。
1
2
3
4
5
6mv libstdc++.so.6.0.20 libstdc++.so.6.0.20.old
mv libstdc++.so.6 libstdc++.so.6.old
mv libstdc++.so libstdc++.so.old
# 这里就偷懒搜一个,一般在 /usr/lib/x86_64-linux-gnu 目录下会有
sudo find /usr/lib -name libstdc++*
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.29 [path to merlin]/merlin_compiler/trunk/source-opt/gcc4/lib641
2ln -s libstdc++.so.6.0.29 libstdc++.so
ln -s libstdc++.so.6.0.29 libstdc++.so.6
b、MDiag::emitDiagnosticLoc() marked override, but does not override
问题原因:子类标记为override,但是父类没有标记为override。不过实际检查报错的位置发现clang对应位置是有override标记的,推测编译merlin时指定的clang位置有错误。
1
2/home/w/DSE/merlin-compiler/trunk/mars-gen/tools/mcheck/mdiag.h:60:8: 错误: ‘void MDiag::emitDiagnosticLoc(clang::FullSourceLoc, clang::PresumedLoc, clang::DiagnosticsEngine::Level, llvm::ArrayRef<clang::CharSourceRange>)’ marked override, but does not override
void emitDiagnosticLoc(clang::FullSourceLoc, clang::PresumedLoc,
解决方案:打开merlin_compiler/trunk/mars-gen/tools/mcheck/mdiag.h去掉其中
62、63 行的 override 。
c、mcheck mrefactor undfeind
问题原因:clang库中确实没有这些定义,不知道是版本问题还是代码bug。错误类似下面这种:
1
2using clang::ast_matchers::cxxNewExpr; Undefined
using clang::ast_matchers::cxxOperatorCallExpr; Undefinedmerlin-compiler/trunk/mars-gen/tools/mcheck/CMakeLists.txt文件去掉以下两行(为什么取巧呢,这是因为这两个模块是工具,不确定这样编译出的merlincc是否正常工作,寄希望于这两个工具不影响正常编译不大)。
1
2add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/mcheck")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/mrefactor")
d、/usr/bin/ld -lrose
问题原因:找不到库文件位置(经典错误了。 1
/usr/bin/ld:/home/w/DSE/merlin-compiler/trunk/source-opt/lib/rose/lib/librose.so: file format not recognized; treating as linker scriptlibrose.so没有链接指向它。这里删除然后重新建立软链接即可。随即又冒出另一个问题(不是哥们,那之前找到的librose.so算什么?)。
1
2/usr/bin/ld: 找不到 -lrose
clang: error: linker command failed with exit code 1 (use -v to see invocation)librose.so的软连接。
1
2
3
4
5
6
7cd merlin-compiler/trunk/source-opt/lib/rose/lib
rm librose.so
ln -s librose.so.0.0.0 librose.so
# 然后拷贝到 /usr/bin 目录下新建一个软连接,这一步需要 sudo 权限
sudo cp librose.so.0.0.0 /usr/lib
cd /usr/lib
sudo ln -s librose.so.0.0.0 librose.so
六、见证曙光
经过三天鏖战,走了一堆弯路之后,终于见到如下的输出。(应该是好了吧
1
2
3
4
5
6
7
8
9
10
11
12[ 92%] Built target DsBitwidthOpt
[ 92%] Built target set_cfg
[ 93%] Built target DsTiling
[ 94%] Built target DsScope
[ 95%] Built target DsLoopParallel
[ 96%] Built target DsSkeletonExtract
[ 97%] Built target DsResourceEval
[ 98%] Built target DsPipeline
[ 99%] Built target LoopParallel
[100%] Linking CXX executable ../../../bin/mars_opt_org
[100%] Built target mars_opt_org
(base) w@HAS-T640:~/DSE/merlin-compiler/trunk/build$ 1
2
3
4
5
6
7
8
9
10
11
12
13(base) w@HAS-T640:~/DSE/merlin-compiler/trunk/build$ merlincc -h
Smartmatch is experimental at /home/w/DSE/merlin-compiler/trunk//mars-gen/scripts/lib/message.pm line 392.
Usage: merlincc <options> <filename>.< c|cpp|mco >
Options:
-v, --version
Display compiler version
--list-platform
Display supported platforms
...