Andre's Blog
Perfection is when there is nothing left to take away
Building Google v8

Google's JavaScript engine is a wonderful C++ library that works on many platforms and runs JavaScript code with speeds that are comparable with a natively built and fully optimized C++ code. Awesome. Sign me up. All I need to do now is to build this wonderful library, which should be as easy as saying: "Hey, Google!". Right? I wish... Once you start the process, you quickly learn that writing up-to-date documentation isn't one of the qualities Google excels at.

I started my v8 build journey on the following page, which was short enough and made me think that I would be done within a couple of hours:

https://github.com/v8/v8/wiki/Building-with-GN

The reality turned out to be a couple of evenings that I had to spend troubleshooting shortcomings in the Google's build process and looking for ways to configure the build system to produce what I need.

1. Download Google's depot_tools from this location:

http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up

, and unzip the archive into any directory. I will use C:\projects\v8\depot_tools\ throughout this post.

2. Add the depot_tools location to the system path. You can do it just within the command line prompt where you are building the v8, as you will not need it after you are done with the build, so no need to litter the system path with this location.

set PATH=C:\projects\v8\depot_tools;%PATH%

3. Some depot_tools scripts invoke Python without the file extension (i.e. python) and some use the full file name (i.e. python.exe), so the first form finds python.bat in C:\projects\v8\depot_tools\, while the second results in an error because there is no python.exe in depot_tools. Add this directory to the path, unless you are using some other version of Python that is compatible with the v8 build process:

set PATH=C:\projects\v8\depot_tools\win_tools-2_7_6_bin\python\bin;%PATH%

4. Google build process is intended for Google employees and pulls many dependencies from Google's internal repositories, which are not accessible from outside (e.g. the build is supposed to pull and install the Visual Studio from Google's internal repository). Prevent this by setting this environment variable:

set DEPOT_TOOLS_WIN_TOOLCHAIN=0

Indicate the version of Visual Studio you have by setting this environment variable:

set GYP_MSVS_VERSION=2017

Note that this variable seems to be a holdover from the GYP build, so it's possible that it could change in the future to reflect the GN build.

5. Google build process completely bypasses all conventions of how to obtain Windows SDK files and reaches into Windows SDK directories for the files they need, such as dbghelp.dll, based on the directory structure of the specific Windows SDK version. Consequently, none of the official Windows SDK versions shipped with Visual Studio 2017 will work because Microsoft changes their internal directory structure from time to time and the v8 build will fail because dbghelp.dll and other files will not be found in new Windows SDK installations. The only way current v8 build works is that if you install an archived version of the Windows SDK from Microsoft's archives:

https://developer.microsoft.com/en-us/windows/downloads/sdk-archive

Hopefully this archive link will work for a while until Google figures out how to reference Windows development files in a portable way.

6. When installing Visual Studio 2017, make sure to include ATL MFC component. Check this section for additional Visual Studio dependencies:

https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md#Visual-Studio

7. Now we can grab the v8 source code with this command:

fetch v8

This will take a while and will create a v8 directory in the current directory.

8. Change to the v8 directory and follow up with this command to make sure the source is up-to-date:

cd v8
gclient sync

9. Now we are ready to work with the v8 source code. Make sure the current command prompt environment is initialized for x64 VC++ builds.

vcvarsall.bat x64

Note that vcvarsall.bat isn't on the path, so you will need to prefix the batch file with the full path leading to the file for your edition of Visual Studio (e.g. in the Community edition this batch file is in C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\).

10. Use git to check out the revision of the v8 engine you would like to build. As a general rule, the v8 engine revision should be the one that is released with a stable Chrome release, which you can look up on this page:

https://omahaproxy.appspot.com/

Find a stable win64 Chrome release and scroll to the right to see the corresponding v8 release. For example, a stable win64 Chrome release on the moment of this writing is 63.0.3239.132 and the corresponding v8 version is 6.3.292.49. Google tags v8 revisions with the version, so you can check out this version to make a build:

git checkout 6.3.292.49

11. If you would like to build the v8 as a static library, but use a dynamically-linked C runtime, you need to edit build/config/win/BUILD.gn and change the section config("default_crt"), under the line # Desktop Windows: static CRT. to dynamic_crt.

12.  Generate build scripts for debug and release x64 builds:

python tools/dev/v8gen.py x64.release
python tools/dev/v8gen.py x64.debug

You will need both, debug and release builds, even if you don't intend to dive into Google's code.

Note that 32-bit builds will not work on a true 32-bit machine because Google assumes that 32-bit stuff is located in WOW64 and fails to find them in their original locations on a 32-bit machine.

13. Change args.gn files as follows for a static or a dynamic build of the v8:

In order to build the v8 as a static library:

echo v8_static_library = true >> out.gn\x64.release\args.gn
echo is_component_build = false >> out.gn\x64.release\args.gn
echo v8_static_library = true >> out.gn\x64.debug\args.gn 
echo is_component_build = false >> out.gn\x64.debug\args.gn

In order to build the v8 as a dynamic library:

echo is_component_build = true >> out.gn\x64.release\args.gn
echo is_component_build = true >> out.gn\x64.debug\args.gn

14.  Now you can build the v8 with this command, one platform at a time:

ninja -C out.gn/x64.release

Note, however, that the static build of the v8 breaks close to the end and does not finish. However, all the libraries you need will be built, so you can ignore this error. Hopefully, it will be fixed at some later point.

15. Once the build is finished, run these tests for the last build. Note that this command won't work against an arbitrary build.

python tools\run-tests.py --gn

One test failed in my setup, but the failure was in the wrong currency symbol and wasn't that important for me to troubleshoot any further, so I left it alone.

16. Repeat the last two steps for x64.debug.

17. The last two steps produce a set of import libraries and DLLs that you can use for your projects.

For a static v8 build you will need these libraries:

icui18n.lib
icuuc
.lib
v8_base_0
.lib
v8_base_1
.lib
v8_external_snapshot
.lib
v8_init
.lib
v8_initializers
.lib
v8_libbase
.lib
v8_libplatform
.lib
v8_libsampler
.lib
v8_nosnapshot
.lib
v8_snapshot
.lib

For a dynamic v8 build, you will need these libraries:

v8.dll.lib
v8_libbase.dll.lib
v8_libplatform.dll.lib
icui18n.dll.lib
icuuc.dll.lib

You will need to package DLLs corresponding to these libraries with your application.

One important note is that Google packs all Microsoft libraries in the v8 build, such as those that come with Windows (e.g. api-ms-win-crt-runtime-l1-1-0.dll), as well as VC runtime (e.g. vcruntime140.dll) and Universal C runtime (e.g. ucrtbase.dll). Tempting as it is, avoid shipping these libraries with your application unless you plan to ship security updates released for these libraries by Microsoft. Universal C runtime is shipped with Windows Updates and VC++ runtime should be installed using the corresponding version of the VC++ redistributable package.

18. If you intend to copy v8 samples into your own project to experiment with v8 constructs, keep in mind that all of the samples incorrectly include v8 headers as #include <include/v8.h>, so these includes will not be found if you add the v8/include directory into your project's include search path. You will need to change them to #include <v8.h> to make it work.

19. One more problem I ran into after successfully building a test v8 application in my own project was crashing when trying to allocate a v8 context with the v8::Isolate::New call and the error was just a heap check failure. It turns out that one needs to copy natives_blob.bin and snapshot_blob.bin files from the v8 build directory into whatever directory is supplied to the v8::V8::InitializeExternalStartupData call.

At this point you should be able to build and run your own code using v8 libraries.

Comments:
Name:

Comment: