使用Clang构建V8并发布LLVM IR
Building V8 with Clang and emitting LLVM IR
我试图用Clang构建V8 Javascript引擎并输出一个.ll
文件。我试着把这里和这里的信息结合起来做这个。然而,当我尝试make
时,它失败了,说"没有规则来制定目标。"我迷路了。我试过编译v8。抄送,但这完全失败了。我想这是因为我试图通过把它作为编译器来强制-emit-llvm
,但我不确定。
$ cd v8
$ export CXX="clang++ -S -emit-llvm"
$ export CC="clang -S -emit-llvm"
$ export CPP="clang -E -S -emit-llvm"
$ export LINK="clang++ -S -emit-llvm"
$ export CXX_host="clang++ -S -emit-llvm"
$ export CC_host="clang -S -emit-llvm"
$ export CPP_host="clang -E -S -emit-llvm"
$ export LINK_host="clang++ -S -emit-llvm"
$ export GYP_DEFINES="clang=1"
$ make native
PYTHONPATH="/home/pitaj/v8/tools/generate_shim_headers:/home/pitaj/v8/build::/home/pitaj/v8/build/gyp/pylib:"
GYP_GENERATORS=make
build/gyp/gyp --generator-output="out" build/all.gyp
-Ibuild/standalone.gypi --depth=. -S.native -Dv8_enable_backtrace=1 -Darm_fpu=default -Darm_float_abi=default
make[1]: Entering directory `/home/pitaj/v8/out'
CXX(target) /home/pitaj/v8/out/native/obj.target/v8_base/src/accessors.o
…
CXX(target) /home/pitaj/v8/out/native/obj.target/v8_base/src/utils.o
make[1]: *** No rule to make target `/home/pitaj/v8/out/native/obj.target/v8_base/src/v8.o', needed by `/home/pitaj/v8/out/native/obj.target/tools/gyp/libv8_base.a'. Stop.
make[1]: Leaving directory `/home/pitaj/v8/out'
make: *** [native] Error 2
编辑:Makefile: http://pastebin.com/PsZrCkzE
EDIT2:
下面构建的v8没有错误,但显然没有发出任何IR。
$ cd v8
$ export CXX="clang++"
$ export CC="clang"
$ export CPP="clang -E"
$ export LINK="clang++"
$ export CXX_host="clang++"
$ export CC_host="clang"
$ export CPP_host="clang -E"
$ export LINK_host="clang++"
$ export GYP_DEFINES="clang=1"
$ make native
C和c++编译器一般有4个阶段:
- 预处理
- 将源代码编译为汇编程序
- 汇编成二进制对象文件
- 链接多个目标文件生成一个可执行的共享库或静态库
在clang的情况下,第二阶段有点分裂:首先生成LLVM IR,然后将其组装成目标体系结构的汇编。
clang和GCC都共享相同的命令行选项来控制哪个阶段将被执行:- -E只运行预处理器阶段
- -S运行预处理和编译阶段,输出汇编文件
- -c运行预处理、编译和汇编阶段,生成。o对象文件
- 如果你不包含任何这些选项,那么它也会链接生成一个可执行文件(或者,取决于其他选项,一个静态或共享库)。
-emit-llvm
选项仅影响编译阶段,并且必须与-S
选项一起使用。添加这些选项意味着当调用编译器时,它会生成包含LLVM IR的单个文件。默认的输出文件名将与输入文件名相同,但扩展名为。ll。
gyp工具实际上并不构建项目。相反,它生成一组makefile,这些makefile执行实际的构建。这些makefile包含从一种类型的文件构建另一种类型所需文件的规则。主要规则是:
- 从。cpp输入文件生成。o文件(相当于上面的步骤1-3,对于每个。cpp文件)
- 从目标文件 生成静态(.a) &/或动态(.so)库文件
修改后的环境变量会影响这些规则中使用的命令。具体来说,CXX
变量指定了上面第一个规则所使用的命令。
另一件要注意的事情是编译的Makefile规则将-o
选项添加到覆盖输出文件名的命令中。因此,当它使用您指定的CXX环境变量设置执行此规则时,它实际上生成LLVM IR文件,但将它们命名为.o而不是.ll。
问题发生在make进入下一阶段并试图从这些目标文件中生成。a或。so文件时-因为它们不是真正的目标文件,而是LLVM IR文件。
但好消息是,根据你自己的问题,你只需要LLVM IR文件。当它出现故障时,它已经产生了这些。唯一值得注意的是,它们是以。o而不是。ll命名的,但是,嘿,您可以轻松地重命名它们。
如果您希望构建过程干净地进行到最后,您可以通过将用于链接和归档的命令更改为'true'来抑制库文件的生成,这将不做任何事情:
cd v8
export CXX="clang++ -S -emit-llvm"
export CC="clang -S -emit-llvm"
export CPP="clang -E"
export LINK="true"
export AR="true"
export CXX_host="clang++ -S -emit-llvm"
export CC_host="clang -S -emit-llvm"
export CPP_host="clang -E"
export LINK_host="true"
export AR_host="true"
export GYP_DEFINES="clang=1"
make native
正如我所说,在构建结束时,您将为每个.cpp文件提供一个.o文件—文件名将在编译期间打印。这些实际上是LLVM IR文件。您可以使用:
重命名它们find out/native/obj.target/ -name "*.o" -exec rename .o .ll {} ;
- 如何使用 IRBuilder 更新 LLVM IR 中的全局变量值?
- 编写一个将 LLVM IR 文件作为命令行参数的程序
- 通过命令行参数获取llvm ir文件时面临问题
- 拥有LLVM IR库如何从Ubuntu将其交叉编译到iOS,Android,Windows和Mac?
- 如何发出编译和运行C++函数的 LLVM IR
- 目标代码可以转换回LLVM IR吗?
- LLVM IR Array Move with c++ api
- 从LLVM IR中的寄存器中存储该值
- 如何通过 LLVM IR 检查溢出
- LLVM IR:具有可变基本块目标的分支指令
- 使用 LLVM IR 实现动态类型语言
- 为什么LLVM-IR中没有显示模板函数
- LLVM IR,简单的程序给出segfault
- Clang在发出LLVM IR时向所有函数添加noinline属性
- 找不到 'llvm/IR/Constants.h' 文件
- 通过编程复制LLVM IR类型错误
- LLVM IR: find_if, var not captured
- 链接时错误地折叠了LLVM IR类型(C++API)
- 将 GCC IR 转换为 LLVM IR
- Reading LLVM IR from a std::istream