使用Clang构建V8并发出LLVM IR

Pit*_*taJ 8 c++ v8 llvm clang llvm-ir

我正在尝试使用Clang构建V8 Javascript引擎并输出.ll文件.我想在这里这里结合信息来做到这一点.然而,当我尝试时make,它失败了,说"没有规则来制定目标".我搞不清楚了.我试过编译v8.cc,但这完全失败了.我想这是因为我试图-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
Run Code Online (Sandbox Code Playgroud)

...(更多一堆电话CXX,全输出这里)...

  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
Run Code Online (Sandbox Code Playgroud)

编辑:

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
Run Code Online (Sandbox Code Playgroud)

har*_*mic 10

C和C++编译器通常有4个阶段:

  1. 前处理
  2. 将源代码编译为汇编程序
  3. 将汇编程序汇编到二进制目标文件
  4. 链接多个目标文件以生成一个可执行文件,共享库或静态库

在clang的情况下,阶段2是一种分裂:首先生成LLVM IR,然后将其组装成目标体系结构的程序集.

clang和gcc都共享相同的命令行选项来控制将执行哪个阶段:

  • -E仅运行预处理器阶段
  • -S运行预处理和编译阶段,输出汇编文件
  • -c运行预处理,编译和汇编阶段,生成.o对象文件
  • 如果您不包含任何这些选项,那么它还将链接以生成可执行文件(或者,根据其他选项,还可以生成静态库或共享库).

-emit-llvm选项仅影响编译阶段,必须与-S选项一起使用.添加这些选项意味着在调用编译器时,它会生成包含LLVM IR的单个文件.默认输出文件名与输入文件名相同,但扩展名为.ll.

gyp工具实际上并不构建项目.相反,它会生成一组makefile,用于实际构建.这些makefile包含用于从另一个文件构建一种所需文件的规则.主要规则是:

  1. 从.cpp输入文件生成.o文件(相当于上面的1-3阶段,每个.cpp文件)
  2. 从目标文件生成静态(.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
Run Code Online (Sandbox Code Playgroud)

正如我所说,在构建结束时,每个.cpp文件都有一个.o文件 - 在编译期间将打印文件名.这些实际上是LLVM IR文件.您可以使用以下命令重命名:

find out/native/obj.target/ -name "*.o" -exec rename .o .ll \{\} \;
Run Code Online (Sandbox Code Playgroud)