聊一聊編譯和使用V8
V8編譯是個比較麻煩的事情,不僅是下載、編譯的過程,不同系統(tǒng)、不同編譯器、不同C++版本都可能會出現(xiàn)不同的問題。之前編譯的時候沒有記錄步驟,這次簡單記錄一下編譯V8的過程,我的工作目錄是/code/v8_code/。
- 1 編譯V8
- 2 編譯V8為靜態(tài)庫
- 3 使用V8
一. 編譯V8
1 下載工具:
- git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
2 執(zhí)行
- export PATH=$PATH:/code/v8_code/depot_tools
后續(xù)執(zhí)行命令用到。
3 執(zhí)行
- gclient config https://chromium.googlesource.com/v8/v8.git
4 執(zhí)行gclient sync (成功后當前目錄下多一個v8目錄,這時候有depot_tools和v8兩個目錄)
5 執(zhí)行命令:alias gm=/code/v8_code/v8/tools/dev/gm.py,然后cd v8進入v8源碼目錄。
6 執(zhí)行gm x64.release,編譯成功,新建一個hello.js,執(zhí)行out/x64.release/d8 hello.js就看到相應輸出,或者執(zhí)行out/x64.release/d8進入互動模式。
二. 編譯V8為靜態(tài)庫
執(zhí)行
- alias v8gen=/code/v8_code/v8/tools/dev/v8gen.py
v8源碼目錄執(zhí)行v8gen x64.release.sample生成配置文件,執(zhí)行
- ninja -C out.gn/x64.release.sample v8_monolith
編譯靜態(tài)庫。
三.使用V8
我們可以在自己的項目里使用V8,這個已經(jīng)有不少的例子,Node.js就是典型的例子,不過Node.js比較復雜,不利于快速理解如何使用V8,其實V8靜態(tài)庫和其他的靜態(tài)庫是一樣,下面以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;
- }
V8的API使用過程就是初始化V8,編譯執(zhí)行腳本,銷毀V8。下面執(zhí)行
- 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
編譯hello-world,執(zhí)行./hello_world,看到相應輸出。