C++ 使用叮当声和发射LLVM IR构建V8

C++ 使用叮当声和发射LLVM IR构建V8,c++,clang,llvm,v8,llvm-ir,C++,Clang,Llvm,V8,Llvm Ir,我正在尝试用Clang构建V8 Javascript引擎,并输出一个.ll文件。我正试图将这些信息结合起来,并做到这一点。然而,当我尝试生成时,它失败了,说“没有规则生成目标”。我迷路了。我尝试过编译v8.cc,但完全失败了。我想这是因为我试图通过将它作为编译器来强制-emit llvm,但我不确定 $ cd v8 $ export CXX="clang++ -S -emit-llvm" $ export CC="clang -S -emit-llvm" $ export CPP="clang

我正在尝试用Clang构建V8 Javascript引擎,并输出一个
.ll
文件。我正试图将这些信息结合起来,并做到这一点。然而,当我尝试
生成
时,它失败了,说“没有规则生成目标”。我迷路了。我尝试过编译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
。。。(更多的CXX呼叫,全部输出)

编辑:

生成文件:

编辑2:

下面构建的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的情况下,阶段2是一种拆分:首先生成LLVMIR,然后将其组装为目标体系结构的组装

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

    • -E只运行预处理器阶段
    • -S运行预处理和编译阶段,输出程序集文件
    • -c运行预处理、编译和汇编阶段,生成一个.o对象文件
    • 如果不包括这些选项中的任何一个,那么它还将链接以生成可执行文件(或者,根据其他选项,生成静态或共享库)
    -emit llvm
    选项仅影响编译阶段,必须与
    -S
    选项结合使用。添加这些选项意味着调用编译器时,它将生成一个包含LLVM IR的文件。默认输出文件名与输入文件名相同,但扩展名为.ll

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

  • 从.cpp输入文件生成.o文件(对于每个.cpp文件,相当于上面的阶段1-3)
  • 从对象文件生成静态(.a)和/或动态(.so)库文件
  • 已修改的环境变量会影响这些规则中使用的命令。具体来说,
    CXX
    变量指定用于上述第一条规则的命令

    另一件需要注意的事情是编译的Makefile规则将
    -o
    选项添加到覆盖输出文件名的命令中。因此,当它使用您指定的CXX环境变量设置执行此规则时,它实际上是在生成LLVM IR文件,但将它们命名为.o而不是.ll

    当make进入下一阶段并试图从这些对象文件中生成.a或.so文件时,就会出现问题,因为它们实际上不是对象文件,而是LLVM IR文件

    但好消息是,根据您自己的问题,您只需要LLVM IR文件。当它走向失败时,它已经产生了这些。唯一需要注意的是,它们是用.o而不是.ll命名的,但是,嘿,你可以很容易地重命名它们

    如果您想让构建干净地进行到底,可以通过将用于链接和归档的命令更改为“true”来抑制库文件的生成,而“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 \{\} \;
    

    你能告诉我们Makefile在线吗?据我所知,它使用gyp来构建,所以Makefile可能没有多大帮助,但我会把它放到在线上。编译成功了,但是重命名的事情没有…奇怪<(eval 1)第1行“.”附近的代码>语法错误
    看起来您正在使用另一个基于perl的重命名命令()。它需要不同的论点。试试看:
    find/native/obj.target/-name“*.o”-exec rename's/\.o$/.ll/'\{\\\
    
    find out/native/obj.target/ -name "*.o" -exec rename .o .ll \{\} \;