深圳幻海软件技术有限公司 欢迎您!

聊一聊编译和使用V8

2023-02-27

V8编译是个比较麻烦的事情,不仅是下载、编译的过程,不同系统、不同编译器、不同C++版本都可能会出现不同的问题。之前编译的时候没有记录步骤,这次简单记录一下编译V8的过程,我的工作目录是/code/v8_code/。1编译V82编译V8为静态库3使用V8一.编译V81下载工具:复制git 

V8编译是个比较麻烦的事情,不仅是下载、编译的过程,不同系统、不同编译器、不同C++版本都可能会出现不同的问题。之前编译的时候没有记录步骤,这次简单记录一下编译V8的过程,我的工作目录是/code/v8_code/。

  • 1 编译V8
  • 2 编译V8为静态库
  • 3 使用V8

一. 编译V8

1 下载工具:

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 
  • 1.

2 执行

export PATH=$PATH:/code/v8_code/depot_tools 
  • 1.

后续执行命令用到。

3 执行

gclient config https://chromium.googlesource.com/v8/v8.git 
  • 1.

4 执行gclient sync (成功后当前目录下多一个v8目录,这时候有depot_tools和v8两个目录)

5 执行命令:alias gm=/code/v8_code/v8/tools/dev/gm.py,然后cd v8进入v8源码目录。

6 执行gm x64.release,编译成功,新建一个hello.js,执行out/x64.release/d8 hello.js就看到相应输出,或者执行out/x64.release/d8进入互动模式。

二. 编译V8为静态库

执行

alias v8gen=/code/v8_code/v8/tools/dev/v8gen.py 
  • 1.

v8源码目录执行v8gen x64.release.sample生成配置文件,执行

ninja -C out.gn/x64.release.sample v8_monolith 
  • 1.

编译静态库。

三.使用V8

我们可以在自己的项目里使用V8,这个已经有不少的例子,Node.js就是典型的例子,不过Node.js比较复杂,不利于快速理解如何使用V8,其实V8静态库和其他的静态库是一样,下面以V8的hello-world为例子,看看如何使用V8。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "include/libplatform/libplatform.h" 
#include "include/v8-context.h" 
#include "include/v8-initialization.h" 
#include "include/v8-isolate.h" 
#include "include/v8-local-handle.h" 
#include "include/v8-primitive.h" 
#include "include/v8-script.h" 
 
int main(int argc, char* argv[]) { 
  // Initialize V8. 
  v8::V8::InitializeICUDefaultLocation(argv[0]); 
  v8::V8::InitializeExternalStartupData(argv[0]); 
  std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform(); 
  v8::V8::InitializePlatform(platform.get()); 
  v8::V8::Initialize(); 
 
  // Create a new Isolate and make it the current one. 
  v8::Isolate::CreateParams create_params; 
  create_params.array_buffer_allocator = 
      v8::ArrayBuffer::Allocator::NewDefaultAllocator(); 
  v8::Isolate* isolate = v8::Isolate::New(create_params); 
  { 
    v8::Isolate::Scope isolate_scope(isolate); 
 
    // Create a stack-allocated handle scope. 
    v8::HandleScope handle_scope(isolate); 
 
    // Create a new context. 
    v8::Local<v8::Context> context = v8::Context::New(isolate); 
 
    // Enter the context for compiling and running the hello world script. 
    v8::Context::Scope context_scope(context); 
 
    { 
      // Create a string containing the JavaScript source code. 
      v8::Local<v8::String> source = 
          v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'"); 
 
      // Compile the source code. 
      v8::Local<v8::Script> script = 
          v8::Script::Compile(context, source).ToLocalChecked(); 
 
      // Run the script to get the result. 
      v8::Local<v8::Value> result = script->Run(context).ToLocalChecked(); 
 
      // Convert the result to an UTF8 string and print it. 
      v8::String::Utf8Value utf8(isolate, result); 
      printf("%s\n", *utf8); 
    } 
 
      const char csource[] = R"( 
        let bytes = new Uint8Array([ 
          0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 
          0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 
          0x07, 0x01, 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, 0x0a, 0x09, 0x01, 
          0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b 
        ]); 
        let module = new WebAssembly.Module(bytes); 
        let instance = new WebAssembly.Instance(module); 
        instance.exports.add(3, 4); 
      )"; 
 
      // Create a string containing the JavaScript source code. 
      v8::Local<v8::String> source = 
          v8::String::NewFromUtf8Literal(isolate, csource); 
 
      // Compile the source code. 
      v8::Local<v8::Script> script = 
          v8::Script::Compile(context, source).ToLocalChecked(); 
 
      // Run the script to get the result. 
      v8::Local<v8::Value> result = script->Run(context).ToLocalChecked(); 
 
      // Convert the result to a uint32 and print it. 
      uint32_t number = result->Uint32Value(context).ToChecked(); 
      printf("3 + 4 = %u\n", number); 
    } 
  } 
 
  // Dispose the isolate and tear down V8. 
  isolate->Dispose(); 
  v8::V8::Dispose(); 
  v8::V8::ShutdownPlatform(); 
  delete create_params.array_buffer_allocator; 
  return 0; 

  • 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.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.

V8的API使用过程就是初始化V8,编译执行脚本,销毁V8。下面执行

g++ -I. -Iinclude samples/hello-world.cc -o hello_world -lv8_monolith -Lout.gn/x64.release.sample/obj/ -pthread -std=c++14 -DV8_COMPRESS_POINTERS 
  • 1.

 

编译hello-world,执行./hello_world,看到相应输出。