Compile and embed V8 engine in C++ application on MacOS Big Sur
Introduction
Since the first JavaScript engine which was created by Brendan Eich in 1995 for the Netscape Navigator web browser, JavaScript has became one of the most successful language ever-known. After the first implementations as interpreters, Just-in-time (JIT) JavaScript engines became more popular and widely-used. The high-efficiency of JavaScript engines and the successful of ECMAScript series point out more by more applications of JavaScript and JavaScript-based techniques like TypeScript, Node.js distributing in many form of Software applications. Despite the fact of widely prebuilt, the compiling and embedding process of V8 engine inside each individual C++ applications would still give out high-performance minimized applications which support embedded JavaScript or WebAssembler runtime.
In this article, the first section introduce the most well-known JavaScript engines used in the most common browsers; the second section illustrate the process of compiling and embedding V8 engine into individual C++ application; the discussion section shows the side results in size and time and the final section give a conclusion about the Mac OS build system and V8 engine compatibility.
Common Javascript Engines
These are the most popular JavaScript engines currently stay maintained
- V8 engine from Google, used in Chromium-based browsers, embeded in CEF, Electron, especially Node.js and Deno runtime systems.
- SpiderMoney is developed by Mozilla which is used in Firefox.
- JavaScriptCore is developed by Apple which is used in Safari.
- Chakra which is used in Internet Explorer. The replacement of Chakra by V8 engine in Edge is announced by Microsoft in Jan 2020 https://blogs.windows.com/windowsexperience/2020/01/15/new-year-new-browser-the-new-microsoft-edge-is-out-of-preview-and-now-available-for-download/.
In the time of writing this article, Google Chrome is clearly dominant other browsers. This partially prove the high-efficiency characteristics of V8 engine over another engines.
C++ Embeded V8 engine
This section guide you on how to compile V8 engine from source code and embed it inside you c++ application.
- Install depot_tools.
To clone V8 engine source code, you need to install depot_tools first. depot_tools consists of fetch, gn, ninja and many more commands which is required to compile V8 engine.
Inside your working directory, clone depot_tools:
git clone
https://chromium.googlesource.com/chromium/tools/depot_tools.git
Put this line at the end of ~/.bash_profile to add depot_tools to your bash
export PATH=/path/to/depot_tools:$PATH
2. Clone V8 engine source code
mkdir ~/v8_engine
cd ~/v8_engine
fetch v8
cd v8
The source code will be located at ~/v8_engine/v8. The current directory should be ~/v8_engine/v8
3. Compile v8 engine
Install Xcode if it is not ready (the whole Xcode IDE, not just the Command line tools) and run this command
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
Generate configuration
./tools/dev/v8gen.py x64.release.sample
To view or manually edit the configuration, you could run:
gn args out.gn/x64.release.sample
The configuration should like this:
is_component_build = false
is_debug = false
target_cpu = “x64”
use_custom_libcxx = false
v8_monolithic = true
v8_use_external_startup_data = false
If one of the last three lines of the above configuration is not defined, the output static library will not work.
4. Testing
Compile hello-world sample
clang++ -I. -Iinclude samples/hello-world.cc -o hello_world -lv8_monolith -Lout.gn/x64.release.sample/obj/ -pthread -std=c++14 -DV8_COMPRESS_POINTERS
Execute the sample
./hello_world
The result
Hello, World!
3 + 4 = 7
In the future usage of V8 engine, C++ build system should include ~/v8_engine/v8/include as the header and then link your binary with the static library located at ~/v8_engine/v8/out.gn/x64.release.sample/obj/libv8_monolith.a
To further custom configuration, file out.gn/x64.release.sample/args.gn should be investigated and manually edited.
Discussion
After finish the V8 engine compilation (step 3), the out.gn/x64.release.sample/obj directory stores all the object file and static libraries. In there, libv8_monolith.a is the most important file. Athough this final static library is about 3.2 GB in size, only used binary of this monolith are embeded into individual C++ application. For example, the size of the executable hello_world is only about 29 MB.
The time to build V8 engine is about 15 minutes depends on the configurations and the build system.
Conclusion
The building of V8 engine on Mac OS is fully supported by both the OS and Xcode IDE. The official V8 engine’s documentation is comprehensive to help user build the source code. Final individual C++ application has an resonable size while has the ability to apply the latest ECMAScript-262 techniques.
References
You can leave a comment if you are in a struggle with compiling or embedding V8 engine inside you C++ application!