1. 程式人生 > >windows下 V8 JS引擎 編譯 2016-06-30

windows下 V8 JS引擎 編譯 2016-06-30

最近需要編譯V8,找了找網上的教程都是比較老的,所以自己折騰下編譯。

由於google連不上的問題。。你需要一個穩定的VPN服務,這個是必須的,如果有代理,可以設定
git config –global http.proxy http://127.0.0.1:1080
git config –global https.proxy https://127.0.0.1:1080

1.使用vs2013編譯,因為可能要支援C++ 11 新特性,所以需要提前裝vs2013
2.谷歌現在V8原始碼放到了 https://github.com/v8/v8,但是還是推薦使用depot_tools gyp下載,直接下載的話,third_party目錄下少cygwin,icu 兩個資料夾,所以還是使用工具下載
3.安裝git 客戶端,下載depot_tools, 使用git clone

https://chromium.googlesource.com/chromium/tools/depot_tools.git,下載好了以後,例如我的目錄
D:\v8\depottools\depot_tools,然後設定系統的環境變數path下新增D:\v8\depottools\depot_tools,期間可能會安裝一些東西如python27版本.
這裡寫圖片描述
4.下載v8原始碼,新建D:\v8\src目錄,然後使用cmd命令進入當前目錄,輸入命令gclient config .gclient,會在當前目錄下建立一個.gclient檔案,然後把這個檔案內容修改為
solutions = [
{
“managed”: False,
“name”: “src”,
“url”: “
https://chromium.googlesource.com/v8/v8.git
“,
“custom_deps”: {},
“deps_file”: “.DEPS.git”,
“safesync_url”: “”,
},
]
如圖所示
這裡寫圖片描述

cmd 進入D:\v8\src下,輸入命令gclient sync命令更新。
這裡寫圖片描述

一直等待更新吧,更新到一定程度會報錯,比如檔案找不到之類的如(v8/gypfiles/landmines.py),此時目錄下應該有2個檔案夾了,把缺少的檔案從src目錄拷貝到v8對應的目錄,繼續執行gclient sync
這裡寫圖片描述
這裡寫圖片描述

執行命令的過程中,可能自動會安裝一些東西,如gyp,window8 sdk等等。
這裡寫圖片描述


這裡寫圖片描述
安裝完gyp以後,同樣需要在環境變數path下新增路徑,如D:\v8\src\v8\tools\gyp

更新完成以後。把src目錄下的gypfiles include test testing tools samples src等目錄拷貝v8目錄下,
gypfiles也拷貝一份到build目錄下覆蓋,如圖
這裡寫圖片描述

我可能因為網路問題,D:\v8\src\v8\third_party\icu 下還缺少一些檔案,我查看了下,用的是icu4c-56.1版本,讓後我在http://igor-zivkovic.from.hr/BLFS/general/icu.html網站,下載了http://download.icu-project.org/files/icu4c/56.1/icu4c-56_1-src.tgz對應的版本,拷貝到了對應的D:\v8\src\v8\third_party\icu目錄下,在用原來的D:\v8\src\v8\third_party\icu備份的檔案在覆蓋一次

開始編譯

cmd 進入D:\v8\src目錄下
執行
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
set GYP_GENERATORS=ninja,msvs-ninja
set GYP_MSVS_VERSION=2013
python build/gyp_v8 -Dtarget_arch=ia32
就會在build目錄下生成all.sln工程檔案。同事在out目錄生成對應的編譯檔案,開啟就可以編譯,但是會報BytecodeRegisterOptimizer::kInvalidEquivalenceId 重定義在v8_base_0.lib重定義.
在D:\v8\src\v8\src\interpreter\bytecode-register-optimizer.cc中,
註釋程式碼const uint32_t BytecodeRegisterOptimizer::kInvalidEquivalenceId; 就可以了,所以工程還是會報錯,但是會在D:\v8\src\v8\out\Debug\obj\src 目錄下生成
icui18n.lib v8_libplatform.lib v8_libbase.lib v8_base_0.lib v8_base_1.lib v8_base_2.lib v8_base_3.lib
v8_nosnapshot.lib icuuc.lib v8_libsampler.lib v8_external_snapshot.lib
等檔案,就可以了。可以新建一個功能跑跑demo程式,標頭檔案在D:\v8\src\src\include目錄下

也可以使用ninja編譯

set GYP_GENERATORS=ninja
python build/gyp_v8 -Dtarget_arch=ia32
ninja -C out/Debug all
這裡寫圖片描述

測試demo

// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "libplatform/libplatform.h"
#include "v8.h"

#pragma comment(lib,"icui18n.lib")
#pragma comment(lib,"v8_libplatform.lib")
#pragma comment(lib,"v8_libbase.lib")
#pragma comment(lib,"v8_base_0.lib")
#pragma comment(lib,"v8_base_1.lib")
#pragma comment(lib,"v8_base_2.lib")
#pragma comment(lib,"v8_base_3.lib")
#pragma comment(lib,"v8_nosnapshot.lib")
#pragma comment(lib,"icuuc.lib")
#pragma comment(lib,"v8_libsampler.lib")
#pragma comment(lib,"v8_external_snapshot.lib")


using namespace v8;

int main(int argc, char* argv[]) {
    // Initialize V8.
    //V8::InitializeICUDefaultLocation(argv[0]);
    //V8::InitializeExternalStartupData(argv[0]);
    Platform* platform = platform::CreateDefaultPlatform();
    V8::InitializePlatform(platform);
    V8::Initialize();

    // Create a new Isolate and make it the current one.
    Isolate::CreateParams create_params;
    create_params.array_buffer_allocator =
        v8::ArrayBuffer::Allocator::NewDefaultAllocator();
    Isolate* isolate = Isolate::New(create_params);
    {
        Isolate::Scope isolate_scope(isolate);

        // Create a stack-allocated handle scope.
        HandleScope handle_scope(isolate);

        // Create a new context.
        Local<Context> context = Context::New(isolate);

        // Enter the context for compiling and running the hello world script.
        Context::Scope context_scope(context);

        // Create a string containing the JavaScript source code.
        Local<String> source =
            String::NewFromUtf8(isolate, "'Hello' + ', World!'",
            NewStringType::kNormal).ToLocalChecked();

        // Compile the source code.
        Local<Script> script = Script::Compile(context, source).ToLocalChecked();

        // Run the script to get the result.
        Local<Value> result = script->Run(context).ToLocalChecked();

        // Convert the result to an UTF8 string and print it.
        String::Utf8Value utf8(result);
        printf("%s\n", *utf8);
    }

    // Dispose the isolate and tear down V8.
    isolate->Dispose();
    V8::Dispose();
    V8::ShutdownPlatform();
    delete platform;
    delete create_params.array_buffer_allocator;
    return 0;
}

這裡寫圖片描述