Skip to content

Instantly share code, notes, and snippets.

@jhalon
Last active May 6, 2024 01:54
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save jhalon/5cbaab99dccadbf8e783921358020159 to your computer and use it in GitHub Desktop.
Save jhalon/5cbaab99dccadbf8e783921358020159 to your computer and use it in GitHub Desktop.

Building Chrome V8 on Windows

In order to be able to build v8 from scratch on Windows for x64, please follow the following steps.

These instructions were updated to work with Windows 11 Build 10.0.22621, but this should also work on WInodws 10

NOTE: While the Chrome team does provide decent documentation, there are some nuances and other additional steps that must be done for v8 to compile on Windows.

Documentation:

Some Nuances:

  • As of April/May 2023, Chromium requires Visual Studio 2022 (>=17.0.0) to build
  • For debugging (that will be us) Visual Studio 2022 is needed. Anything below might result in a build failure
  • Desktop development with C++ components and the MFC/ATL support modules must be installed in Visual Studio.
  • Building v8 in Debug mode with ASan on Windows is not supported, as it's not yet implemented in LLVM.
    • If you need this functionality, build v8 on Linux or macOS.

Get a Fresh Dev VM (Optional):

If you want to start on a fresh Windows 11 Development VM with Visual Studio 2022 then download one of the last W11 Dev VM's from Microsoft:

If you want to start on a fresh Windows 10 Development VM with Visual Studio 2019 then download one of the last W10 Dev VM's from Microsoft:

Setting Up Windows:

Once you have Visual Studio 2022 installed, you will need to install the following additional components:

  • Desktop Development with C++
  • Python Development
  • C++ ATL for Latest v143 Build Tools (x86 & x64)
  • C++ MFC for Latest v143 Build Tools (x86 & x64)
  • C++ Clang Compiler for Windows (15.0.1)
  • C++ Clang tools for Windows (15.0.1 - x64/x86)
  • C++ CMake tools for Windows
  • Windows 11 SDK (10.0.22621.0)

Next, we need to install the "SDK Debugging Tools" to be able to build and debug v8.

Note: If you downloaded the W11 Development VM, this should already be installed. But if you install the SDK, make sure that you have the correct install path of C:\Program Files (x86)\Windows Kits\10\WindowsSDK and that you select Debugging Tools, or you will have build failures.

To do that, either download the Windows 11 SDK (10.0.22621.755) or do the following if you installed the SDK via Visual Studio:

  1. Open up Control Panel
  2. Click Program
  3. Click "Programs and Features"
  4. Select the "Windows Software Development Kit"
  5. Click "Change"
  6. In the new Window, select "Change"
  7. Click "Change"
  8. Check the "Debugging Tools For Windows" Option
  9. Click "Change"
  10. Let the Debugging Tools Install

Download Chrome Tools and V8

First, start by creating a folder where you will be storing Google's tools and v8. In my case I made a new directory called dev in my C:\ drive.

Download the depot_tools and extract it to your previously created folder. In my case it will be extracted to C:\dev\depot_tools.

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 auto update itself. You can use “Extract all…” from the context menu though.

Assuming that you unzipped the budle to C:\dev\depot_tools, we now need to add the following Environmental Variables:

  • Modify the PATH System Variable and put C:\dev\depot_tools at the front.
  • Add the DEPOT_TOOLS_WIN_TOOLCHAIN User Variable and set it to 0.
    • This tells depot_tools to use your locally installed version of Visual Studio
  • Add the vs2022_install User Variable and set it to your installation path of Visual Studio.
    • For 2022 Community it would be set to => C:\Program Files (x86)\Microsoft Visual Studio\2022\Community

Once done, open up cmd.exe, cd to your depot_tools directory and then run the following command:

> gclient

On the 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, like so:

C:\dev\depot_tools>where python
C:\dev\depot_tools\python.bat
C:\Users\User\AppData\Local\Microsoft\WindowsApps\python.exe

Create a v8 directory within your C:\dev folder (assuming that's what you created) for the checkout and change to it:

> mkdir v8 && cd v8

Run the fetch tool from depot_tools to check out the v8 code and its dependencies:

> fetch v8

Once the command has completed (~15-30 minutes), we now need to change to the v8 directory and sync the dependencies by running the following command:

> cd v8
> git fetch
> gclient sync

NOTE: Usually, you can update your current v8 branch with git pull. Note that if you’re not on a branch, git pull won’t work, and you’ll need to use git fetch instead.

Building V8

Now that we have all our tools installed, and dependencies synced, it's time to build v8.

All of your 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.

WARNING: Take note, that there is a problem in the way Windows can associate python files with other versions of python installed on your PC. v8 relies on certain older Python v2 scripts, so always execute commands in the python path/to/script params syntax!

So, once we're in the v8 folder, we can execute the following command to build the debug version of v8:

> python3 tools\dev\gm.py x64.debug

If you want the release version, just change x64.debug to x64.release in the command.

Let this command run, and go get a coffee ☕ as this will take ~2-3 hours to build.

If the compile is successful your console output should be pretty similar to mines, as shown below:

C:\dev\v8\v8>python tools/dev/gm.py x64.debug
# mkdir -p out\x64.debug
# echo > out\x64.debug\args.gn << EOF
is_component_build = true
is_debug = true
symbol_level = 2
target_cpu = "x64"
v8_enable_sandbox = true
use_goma = false
v8_enable_backtrace = true
v8_enable_fast_mksnapshot = true
v8_enable_slow_dchecks = true
v8_optimized_debug = false
EOF
# gn gen out\x64.debug
Done. Made 190 targets from 103 files in 5968ms
# autoninja -C out\x64.debug d8
"C:\dev\depot_tools\bootstrap-2@3_8_10_chromium_26_bin\python3\bin\python3.exe" C:\dev\depot_tools\ninja.py -C out\x64.debug d8 -j 6
ninja: Entering directory `out\x64.debug'
[2137/2137] LINK d8.exe d8.exe.pdb
Done! - V8 compilation finished successfully.

Testing d8

Alright! So, we just successfully compiled v8, nice! If you haven't already noticed, gm also built d8 for us, which is v8's developer shell.

d8 is useful for running some JavaScript locally or debugging changes you have made to V8. This will be useful for us in better understanding v8 and writing exploits.

To test if d8 was successfully built, let's execute it with the --print-bytecode command, like so:

> out\x64.debug\d8 --print-bytecode
V8 version 11.6.0 (candidate)
d8>

From here, to make sure that we can see the bytecode, let's execute a simple function like Array.from(String('12345')) which simply creates an array with each number in the index of the string.

Your output should be similar to mines:

d8> Array.from(String('12345'))
[generated bytecode for function:  (0x02330025a8c9 <SharedFunctionInfo>)]
Bytecode length: 28
Parameter count 1
Register count 5
Frame size 40
Bytecode age: 0
         000002330025A94A @    0 : 21 00 00          LdaGlobal [0], [0]
         000002330025A94D @    3 : c3                Star2
         000002330025A94E @    4 : 2d f8 01 02       GetNamedProperty r2, [1], [2]
         000002330025A952 @    8 : c4                Star1
         000002330025A953 @    9 : 21 02 04          LdaGlobal [2], [4]
         000002330025A956 @   12 : c2                Star3
         000002330025A957 @   13 : 13 03             LdaConstant [3]
         000002330025A959 @   15 : c1                Star4
         000002330025A95A @   16 : 63 f7 f6 06       CallUndefinedReceiver1 r3, r4, [6]
         000002330025A95E @   20 : c2                Star3
         000002330025A95F @   21 : 5f f9 f8 f7 08    CallProperty1 r1, r2, r3, [8]
         000002330025A964 @   26 : c5                Star0
         000002330025A965 @   27 : aa                Return
Constant pool (size = 4)
000002330025A911: [FixedArray] in OldSpace
 - map: 0x023300002231 <Map(FIXED_ARRAY_TYPE)>
 - length: 4
           0: 0x0233000058e5 <String[5]: #Array>
           1: 0x0233000060a1 <String[4]: #from>
           2: 0x023300006dfd <String[6]: #String>
           3: 0x02330025a8a9 <String[5]: #12345>
Handler Table (size = 0)
Source Position Table (size = 0)
["1", "2", "3", "4", "5"]

Congratulations, you built v8 and d8!

Downloading Pre-Built Binaries

In case you don't want to compile V8, you can just grab fresh Chrome binaries built with ASan from here. Additionally, you can use OmahaProxy CSV Viewer to look for specific branch base positions by specifying a version of Chrome you want to target, and then just downloading the appropriate build from the chromium browser list.

@jhalon
Copy link
Author

jhalon commented May 4, 2023

@0xDivyanshu - I believe the reason you're getting an lld-link error is due to the fact that you are using Visual Studio 2019. The Chromium team recently updated the build documentation and state that "Chromium requires Visual Studio 2022 (>=17.0.0) to build".

Try installing VS 2022, v10.0.22621.0 Windows 11 SDK, and the v10.0.22621.755 (Windows 11) SDK Debugging Tools. Then try again, it should work. I'll try to test the build on a fresh W10/W11 VM today and updated the documentation accordingly.

And did the depot_tools update to Python3? I would suggest using their python.bat via the path over Python3 since GN still requires Python2 for certain scripts/functionality.

@uf0o
Copy link

uf0o commented May 15, 2023

@0xDivyanshu

Make sure you have Visual Studio 2022 installed with the latest Win11 SDK as described here:

Also, set the new VS environmental variable as follows:
vs2022_install=C:\Program Files\Microsoft Visual Studio\2022\Community

@zamelyzm
Copy link

@jhalon I am still facing same error event with Visual Studio 2022 version 17.5.5 ! I think root cause is something else. x64.release works perfectly but error only comes for x64.debug mode

i face the same problem as you. has u resolved it?

@jhalon
Copy link
Author

jhalon commented May 24, 2023

@0xDivyanshu & @zamelyzm - I just updated the instructions on how to build the debug version of V8 with VS 2022.

If you are getting build or link errors, make sure that you added the vs2022_install environmental variable, and that you downloaded and installed both the v10.0.22621.0 Windows 11 SDK, and the v10.0.22621.755 (Windows 11) SDK Debugging Tools in the correct path.

I tested this in a fresh Windows 11 Development VM, so if you have any other issues then let me know!

@iweizime
Copy link

As of 4th May 2023, the above steps doesn't really work. For building the debug mode via python, I get error with Linking

C:\dev\v8\v8>python3 tools/dev/gm.py x64.debug
# mkdir -p out\x64.debug
# echo > out\x64.debug\args.gn << EOF
is_component_build = true
is_debug = true
symbol_level = 2
target_cpu = "x64"
v8_enable_sandbox = true
use_goma = false
v8_enable_backtrace = true
v8_enable_fast_mksnapshot = true
v8_enable_slow_dchecks = true
v8_optimized_debug = false
EOF
# gn gen out\x64.debug
Done. Made 194 targets from 103 files in 5429ms
# autoninja -C out\x64.debug d8
"C:\dev\depot_tools\bootstrap-2@3_8_10_chromium_26_bin\python3\bin\python3.exe" C:\dev\depot_tools\ninja.py -C out\x64.debug d8 -j 14
ninja: Entering directory `out\x64.debug'
[245/2133] LINK torque.exe torque.exe.pdb
FAILED: torque.exe torque.exe.pdb
..\..\third_party\llvm-build\Release+Asserts\bin\lld-link.exe /OUT:./torque.exe /nologo -libpath:..\..\third_party\llvm-build\Release+Asserts\lib\clang\17\lib\windows "-libpath:../../../../../Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/ATLMFC/lib/x64" "-libpath:../../../../../Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/lib/x64" "-libpath:../../../../../Program Files (x86)/Windows Kits/NETFXSDK/4.8/lib/um/x64" "-libpath:../../../../../Program Files (x86)/Windows Kits/10/lib/10.0.22621.0/ucrt/x64" "-libpath:../../../../../Program Files (x86)/Windows Kits/10/lib/10.0.22621.0/um/x64" /MACHINE:X64  /PDB:./torque.exe.pdb @./torque.exe.rsp
lld-link: error: duplicate symbol: private: static class v8::base::ContextualVariable<class v8::internal::torque::SourceFileMap, class v8::internal::torque::SourceFileMap>::Scope *& __cdecl v8::base::ContextualVariable<class v8::internal::torque::SourceFileMap, class v8::internal::torque::SourceFileMap>::Top(void)
>>> defined at .\..\..\src\base\contextual.h:82
>>>            obj/torque/torque.obj
>>> defined at obj/torque_base/source-positions.obj
[258/2133] CXX obj/third_party/icu/icui18n/collationiterator.obj
ninja: build stopped: subcommand failed.
Error! - V8 compilation finished with errors.

This error does not happen for release mode and I have been able to build release for v8 successfully. Any help would be appreciated! PS: Anyone stumbling across this, change from python to python3 for all build steps.

This error seems to be related to the v8 version. It was resolved after I updated to the latest main branch.

@trentn
Copy link

trentn commented Jun 1, 2023

I had been running into this issue too awhile back.
I did some debugging and tracked the issue to a set of commits related to the file src/base/contextual.h, and ultimately took the route of working on other stuff.

I got around to looking into this again finding this thread, and the fix.

The fix is here: https://chromium.googlesource.com/v8/v8/+/b0c2bacaea09f8be5c3f9d702fbf3790a8ea8894
Tracked here: https://bugs.chromium.org/p/v8/issues/detail?id=14015

@0xDivyanshu-new
Copy link

I have been trying to get it working for a specific commit hash for v8 to replicate a cve. I am missing a small thing over here but not able to solve it. I would appreciate a slight nudge.

So, I want to build v8 for a specific commit hash 09ecd88ef275f6c66605218a0ffb72123ea3b5e1, I followed the following steps:-

  • Downloaded the depot_tools.zip and unzipped it inside C:\dev\depot_tools
  • set the environment variables as shared above and run gclient
  • Post that, create a directory v8 from depot_tools. From C:\dev\depot_tools , I ran fetch v8 command
  • Post that, cd into v8 and ran git checkout 09ecd88ef275f6c66605218a0ffb72123ea3b5e1 to checkout to the specific hash
  • Post that, ran gclient sync --with_branch_heads (from v8 directory)
  • Finally, ran python3 tools\dev\gm.py x64.debug from v8 directory

At the last step, I got this error :-

# mkdir -p out\x64.debug
# echo > out\x64.debug\args.gn << EOF
is_component_build = true
is_debug = true
symbol_level = 2
target_cpu = "x64"
use_goma = false
goma_dir = "None"
v8_enable_backtrace = true
v8_enable_fast_mksnapshot = true
v8_enable_slow_dchecks = true
v8_optimized_debug = false
EOF
# gn gen out\x64.debug
Done. Made 171 targets from 92 files in 16038ms
# autoninja -C out\x64.debug d8

Apparently ninja.exe is not in path but the same error doesn't come when I try to built the latest v8 debug build. It works just fine. So I think somewhere I have messed up but I don't seem to know the exact issue

@jcoleman1969
Copy link

jcoleman1969 commented Oct 2, 2023

Thanks for putting this together... I typically upgrade v8 in our app once a year or so and it's always a painful experience because something has changed about the process.

A couple of comments:

  1. You mention that people may want to pull specific branches using https://omahaproxy.appspot.com/ above, but I highly recommend pulling the latest stable branch for your platform, not just using the default head branch pulled down by the gclient sync (e.g. git checkout branch-heads/11.7) . We recently had a v8 crashing bug in the default branch go unnoticed through our testing and make it into production.
  2. Some folks might want to modify the GN arguments (for example, to make the monolith library). Instead of doing gm.py you can instead do "gn args out\x64.debug" to allow you to specify the args, followed by "autoninja -C out\x64.debug"

I used the following arguments to generate the monolith build (release):

is_debug = false
target_cpu = "x64"
v8_enable_sandbox=false
treat_warnings_as_errors = false
is_component_build = false
v8_enable_i18n_support = false
v8_use_external_startup_data = false
v8_static_library = true
v8_enable_i18n_support = false
v8_monolithic = true
use_custom_libcxx = false

I used the following arguments to generate the monolith build (debug):

is_debug=true
is_clang=true
target_cpu="x64"
v8_enable_backtrace=true
v8_enable_slow_dchecks=true
v8_enable_sandbox=false
v8_optimized_debug=true
is_component_build=false
v8_enable_i18n_support=false
v8_monolithic=true
v8_use_external_startup_data=false
v8_target_cpu = "x64"
v8_static_library = true
use_custom_libcxx = false
use_custom_libcxx_for_host = false
treat_warnings_as_errors = false
enable_iterator_debugging = true

@billywhizz
Copy link

thanks for writing this up. it's really useful. if anybody is interested, i have set up a github actions build of v8 for common platforms, including win64, here.

i am building other things on top of this and should be able to automate it to produce new builds automatically whenever version changes for omahaproxy stable releases.

@eiantee
Copy link

eiantee commented Jan 14, 2024

do you know how to run v8 tests on windows since i succeed to build

@eiantee
Copy link

eiantee commented Jan 14, 2024

i am working on a big subject. i need to crawl data from XHR request. but some of those XHR requests have a sign key as a request parameter to prevent auto-crawl data, although the sign key is calculated by javascripts which we can retrieve but mixed.
in order to solve this problem, i need to analyze the data flow which the whole XHR request object depends on and reconstruct the AST and regenerate the neat javascript source code, so i can run the javascript to build the XHR request to get data.
would you please give me some guidance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment