How to build V8 on Windows and not go mad
“Building V8 is not for the faint of heart “ — someone on the internet
AngularInDepth is moving away from Medium. More recent articles are hosted on the new platform inDepth.dev. Thanks for being part of indepth movement!
Sometimes I wonder where my insatiable hunger for JavaScript knowledge will lead me to. This time I decided to learn how V8 is used by a browser and Node and where the API we use daily comes from. So I set out to investigate the integration between V8 and two most popular hosting environment for myself.
My plan was to build a simple application that embeds V8. And since not many web developers know that event loop is not implemented by V8 but by a hosting environment I wanted to demonstrate this in my app. I also hoped to learn about V8 inner workings along the way.
But first I had to build V8 from sources and embed it into a simple HelloWorld application. The task turned out to be not for the faint-of-heart. I spent about a week googling and learning about many thing related to C++
and python
. I had to ask four heavily downvoted questions on stackoverflow. I’m going to keep them as a reminder of the efforts it took me to build the thing.
Since both building and embedding are not trivial this article consists of two parts. The first one shows how to build V8 from the sources on Windows machine. The second part explains what is required to plug it into your application. Currently V8 can only be built on x64 machines so make sure you’re building on Windows x64 version.
👏 Please recommend this article so that others know there is a simpler way to build V8. I really hope this article will save some curious mind much pains.
Setting up environment
The instructions on how to build V8 are available here but unfortunately they assume you already have a working environment and omit many details. But these details is exactly what makes building V8 tricky.
V8 uses part of a toolchain for Chromium project, so some of the information found here also was helpful to me. Please note that you don’t need to fetch and build Chromium sources to build V8. Only part of the tool chain like depot_tools
is required.
Git
V8 uses GIT as a VCS so download and install it. If you’re not very proficient with Git checkout Become a GIT pro by learning GIT architecture in 15 minutes to boost your Git knowledge.
VS 2015
Building V8 on Windows requires building tools that come with Visual Studio. As of December 8, 2016 Chromium requires Visual Studio 2015 Update 3 with the 14393 Windows SDK. So go ahead and download the installer for Visual Studio Community 2015 with Update 3 here. This page requires membership, but it’s free, so no worries here. Now run the installer and make sure to select the following:
After the install finished, check that the installer has installed Debug Interface Access (DIA) SDK
and vcvarsall.bat
to the following directories:
- …\Microsoft Visual Studio 14.0\DIA SDK
- …\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
For some reason these may be missing after the install. If that’s the case, you’ll have to figure why and somehow get them installed. Otherwise, you won’t be able to build. In my case it installed correctly on one machine were missing on the other.
Windows SDK
Since Chromium uses Debugging Tools For Windows
which are not installed as part of VS installation, you’ll also need to install Windows SDK separately. Download the installer here and install. Make sure you’ve selected the package in the installer:
Depot tools
Download the depot_tools
bundle and extract it somewhere.
Warning: DO NOT use drag-n-drop or copy-n-paste extract from Explorer, this will not extract the hidden “.git” folder which is necessary for depot_tools to autoupdate itself. You can use “Extract all…” from the context menu though.
Environment variables
Add depot_tools
to the start of your PATH
. Many build python scripts are written for Python version lower than 3.x so ensure it’s ahead of any installs of Python. Assuming you unzipped the bundle to E:\V8\depot_tools
update path like that:
I also recommend to add it to the system variables PATH
not user variables. The PATH
is constructed from the system path, which can be viewed in the System Environment Variables field in the System dialog box. The User path is appended to the system path. It means if you add path to User variables, and you have other Python installation found from the system path, you’ll have a problem.
You’ll also need to specify two environment variables:
- DEPOT_TOOLS_WIN_TOOLCHAIN=0
- GYP_MSVS_VERSION =2015
Update Depot tools
From a cmd.exe shell, run the command gclient
(without arguments). On first run, gclient will install all the Windows-specific bits needed to work with the code, including msysgit
and python
.
- If you run gclient from a non-cmd shell (e.g., cygwin, PowerShell), it may appear to run properly, but msysgit, python, and other tools may not get installed correctly.
- If you see strange errors with the file system on the first run of gclient, you may want to disable Windows Indexing.
After running gclient open a command prompt and type where python
and confirm that the depot_tools python.bat
comes ahead of any copies of python.exe
.
Get source code
Go into the directory where you want to download the V8 source into and execute the following in your terminal/shell:
fetch v8
cd v8
Building V8
Now that we have environment ready we can build V8. All commands should be executed using Windows Command Shell inside the V8 source directory. We will be executing python scripts as part of the build process and we need to ensure that the python executable from build_tools
is used. The problem is that Windows can associate python files with other versions of python installed on your PC, so always execute command in the following syntax:
python path/to/script params
not this
path/to/script params
Start with the downloading of all build dependencies by executing the following:
gclient sync
Then generate the necessary build files by running the following:
python tools/dev/v8gen.py x64.release
To embed V8 into our application we need to build it as a static library. To do that, we need to modify default build configuration and add these two flags to args.gn
file:
is_component_build = false
v8_static_library = true
Run the following to open the file ..\out.gn\x64.release\args.gn
in an editor:
gn out.gn\x64.release
Add the lines so the resulting file looks like this:
is_debug = false
target_cpu = “x64”
is_component_build = false
v8_static_library = true
The last thing is to compile the source by executing the following:
ninja -C out.gn/x64.release
Run tests to verify that everything is built correctly:
tools/run-tests.py --gn
Build result
The build generates ..\v8source\out.gn\x64.release\obj
folder with many static library files (*.lib) : v8_base.lib
, v8_libbase.lib
etc. We will use these files when embedding v8
into our application.
Embedding V8 into a custom application
As it turned out, the struggle didn’t end with a successful build. I also jumped over multiple hoops when trying to embed V8 and build sample Hello world
application. The manual is pretty short and it’s for Linux based systems and again is lacking on many important details.
We will embed V8 into a simple console application. Create an application by following the instructions described here (don’t check Empty project
) or here. This creates Win32 application but the V8 is built for x64 architecture so we need to modify our project a bit. To do that, go to project properties and select x64 active solution platform:
Also, by default V8 is built in release mode. To avoid mismatch errors like this, we need to set the project to release configuration:
Also, we need to make the application to use the multithread, static version of the run-time library:
Configure include and library directories
Next, we need to add folders to look for V8 header files to Include Directories:
And add folders with V8 static library files to Library Directories:
This page nicely summarizes all types of directories.
Compose HelloWorld cpp file
Now, copy the HelloWorld example from here to your main cpp file and include stdafx
as the top include in your file:
#include “stdafx.h”
Link static libraries
We’re almost done. As mentioned earlier the V8 itself is comprised of static library files in the ..\v8source\out.gn\x64.release\obj
directory. Now we need to link those libraries. To do that add the following to your code:
#pragma comment(lib, "v8_base.lib")
#pragma comment(lib, "v8_libbase")
#pragma comment(lib, "v8_external_snapshot")
#pragma comment(lib, "v8_libplatform")
#pragma comment(lib, "v8_libsampler")
#pragma comment(lib, "icuuc.lib")
#pragma comment(lib, "icui18n.lib")
#pragma comment(lib, "inspector")
And also link Windows related libraries required by V8 libraries:
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dbghelp.lib")
#pragma comment(lib, "shlwapi.lib")
Build the application
And now finally we’re ready build. Go to Build->Build solution
or press Ctrl+Shift+B
. This will generate an executable file to the following location:
..\project-folder\x64\Release\project-name.exe
A few more bits
V8 requires two files located in …\v8-source\out.gn\x64.release
for a startup:
- snapshot_blob.bin
- natives_blob.bin
Copy them to where the executable is. That’s it. You can now run your executable from the command line and it should output “Hello World”.