引言
我們都知道谷歌瀏覽器chrome
采用的javascript引擎是v8
,node.js
這樣的runtime能夠火遍全球,很大一部分功勞得歸於v8
。半年前就想自己編譯v8
引擎玩玩,無奈***阻撓了大部分下載,實在是體驗太差,於是放棄。今天重新編譯v8
,先把代碼從牆外的vps下載下來,再用tar
打個包下載到本地,就可以在本地編譯了。
實驗環境
- 操作系統:Archlinux
- GCC-7.1.1
v8
源碼的版本是6.1.99
步驟記錄
本文參考的資料主要是編譯 V8 源碼以及Getting Started with Embedding。
0x01
先 clone depot_tools 文件
1
|
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
將 depot_tools 添加到當前shell的環境變量 PATH:
1
|
export PATH=`pwd`/depot_tools:"$PATH"
|
注意,depot_tools包含的是谷歌自己的一套工具鏈,里面包含了構建系統Ninja(類似Makefile),以及生成Ninja文件的GN工具。
這一套工具都是用python2
編寫的,所以我們確保系統的python
是python2
版本。在Archlinux下面,默認的python
版本是python3
,所以我強制創建了軟鏈接,sudo ln -sf /bin/python2 /bin/python
,記得編譯完v8
之后再把版本改回去。
0x02
安裝 depot_tools 構建系統的所有依賴,運行:
1
|
gclient sync
|
這樣會下載v8
最新的源代碼以及第三方依賴(比如llvm,clang-format)。
我們並不需要所有的分支,所以fetch v8
可以不執行。
如果這步完成,就可以將depot_tools
和v8
用tar
打包,下載回本地進行編譯了。
目錄結構:
1
2
3
4
5
|
# user1 @ nek-amd in /home/chen [10:08:51]
$ tree -L 1 v8
v8
├── depot_tools
└── v8
|
0x03
先安裝一些不常用的依賴。v8
依賴libtinfo5
,在archlinux下面可以從aur里面裝ncurses5-compat-libs
這個包。其他發行版按實際情況。
進入v8目錄,v8gen
生成 ninja
構建文件:
1
|
cd v8 && tools/dev/v8gen.py x64.debug
|
這樣就會在out.gn
目錄下生成x64.debug
目錄,包含了最重要的build.ninja
文件。
編譯源碼,生成可執行文件,目標系統 x64:
1
|
ninja -C out.gn/x64.debug
|
生成debug版本比release版本要快一些。
如果編譯過程中出錯,要仔細查看報錯信息以及翻閱相關文檔,相信最后一定都可以解決。
編譯完后,可以看到out.gn/x64.debug
目錄下多出許多動態鏈接庫文件一個叫d8
的可執行文件。
1
2
3
4
|
# user1 @ nek-amd in /home/chen/v8/v8 on git:e81af43045 x [10:57:34]
$ ls out.gn/x64.debug/*.so
out.gn/x64.debug/libicui18n.so out.gn/x64.debug/libv8_for_testing.so out.gn/x64.debug/libv8_libplatform.so
out.gn/x64.debug/libicuuc.so out.gn/x64.debug/libv8_libbase.so out.gn/x64.debug/libv8.so
|
0x04
最后一步就是編譯hello-world.cc。
先執行cp out.gn/x64.release/*.bin .
,拷貝快照文件到v8根目錄。
如果按照官網教程,肯定是不能通過的,因為教程使用的是v5.8的代碼。動態鏈接庫的名字已經變掉了。
如功能弄清楚編譯的基本原理,就可以按照自己的需求修改編譯命令。我修改了官網給的編譯命令如下:
1
2
3
4
|
g++ -I. -Iinclude samples/hello-world.cc -o hello-world -Lout.gn/x64.debug -Wl,-rpath=out.gn/x64.debug -Wl,--start-group \
-lv8_libbase -lv8_libplatform -lv8 \
-licuuc -licui18n \
-Wl,--end-group -lrt -ldl -pthread -std=c++0x
|
就可以成功編譯hello-world.cc
了。
執行效果:
1
2
3
|
# user1 @ nek-amd in /home/chen/v8/v8 on git:e81af43045 x [11:07:35]
$ ./hello-world
Hello, World!
|