How do you compile and embed v8 using Visual Studio on Windows? The official guide worked on Linux but not on Windows with Visual Studio because I keep getting compile errors while trying to build v8 and the sample project.
These instructions have been updated in 2023 for v8 version 11.5.83
on Windows 11.
Follow the "depot_tools_tutorial" for Windows. Here is a summary of the instructions.
depot_tools.zip
.DEPOT_TOOLS_WIN_TOOLCHAIN
and set it to 0.python.exe
and python3.exe
.gclient
(from any folder) to download all tools.where python
. The depot_tools Python should appear first in the list. Then run python3 --version
to ensure it outputs as expected.Follow "Setting up Windows".
v8_download
, then open command prompt and cd
to that folder.fetch v8
and then cd v8
.11.5.83
with git checkout 11.5.83
. I highly recommend using this tag that I tested the instructions on because future versions may change the building steps. After completing all the steps, you can try the latest commit or latest tag.gclient sync
.Assuming command prompt is still in the v8_download\v8
folder, run python3 tools/dev/v8gen.py x64.debug
to generate the configuration file.
There was one compilation error, error C3477
, that I had to fix manually. The diff looks like this. I figured that the DCHECK_EQ
is just a debug check that I could comment out to fix the error.
diff --git a/src/heap/new-spaces.cc b/src/heap/new-spaces.cc
index 43a19fe797..ba9fff6e10 100644
--- a/src/heap/new-spaces.cc
+++ b/src/heap/new-spaces.cc
@@ -1069,11 +1069,11 @@ void PagedSpaceForNewSpace::Verify(Isolate* isolate,
DCHECK_EQ(current_capacity_, Page::kPageSize * CountTotalPages());
- DCHECK_EQ(
- AllocatedSinceLastGC() + limit() - top(),
- std::accumulate(begin(), end(), 0, [](size_t sum, const Page* page) {
- return sum + page->AllocatedLabSize();
- }));
+ // DCHECK_EQ(
+ // AllocatedSinceLastGC() + limit() - top(),
+ // std::accumulate(begin(), end(), 0, [](size_t sum, const Page* page) {
+ // return sum + page->AllocatedLabSize();
+ // }));
}
#endif // VERIFY_HEAP
v8\out.gn\x64.debug\args.gn
with:is_debug = true
target_cpu = "x64"
v8_enable_backtrace = true
v8_enable_slow_dchecks = true
v8_optimized_debug = false
v8_monolithic = true
v8_use_external_startup_data = false
is_component_build = false
is_clang = false
Run ninja -C out.gn/x64.debug v8_monolith
.
Run python3 tools/dev/v8gen.py x64.release
.
Replace the contents of v8\out.gn\x64.release\args.gn
with:
dcheck_always_on = false
is_debug = false
target_cpu = "x64"
is_component_build = false
v8_monolithic = true
v8_use_external_startup_data = false
is_component_build = false
is_clang = false
ninja -C out.gn/x64.release v8_monolith
.Create a new Console App for C++ in Visual Studio.
Add the library directories to the project.
v8\include
to Include Directories. Click Apply after this step and after each of the following steps.v8\out.gn\x64.debug\obj
to Library Directories.v8\out.gn\x64.release\obj
.Multi-threaded Debug (/MTd)
.Multi-threaded (/MT)
.v8_monolith.lib;dbghelp.lib;Winmm.lib;
.V8_ENABLE_SANDBOX;V8_COMPRESS_POINTERS;_ITERATOR_DEBUG_LEVEL=0;
to the Preprocessor Definitions.Replace the .cpp
file contents with the following code which is v8\samples\hello-world.cc
but with the include paths corrected.
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libplatform/libplatform.h"
#include "v8-context.h"
#include "v8-initialization.h"
#include "v8-isolate.h"
#include "v8-local-handle.h"
#include "v8-primitive.h"
#include "v8-script.h"
int main(int argc, char* argv[]) {
// Initialize V8.
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
// Create a new Isolate and make it the current one.
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator =
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(isolate);
// Create a new context.
v8::Local<v8::Context> context = v8::Context::New(isolate);
// Enter the context for compiling and running the hello world script.
v8::Context::Scope context_scope(context);
{
// Create a string containing the JavaScript source code.
v8::Local<v8::String> source =
v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'");
// Compile the source code.
v8::Local<v8::Script> script =
v8::Script::Compile(context, source).ToLocalChecked();
// Run the script to get the result.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
// Convert the result to an UTF8 string and print it.
v8::String::Utf8Value utf8(isolate, result);
printf("%s\n", *utf8);
}
{
// Use the JavaScript API to generate a WebAssembly module.
//
// |bytes| contains the binary format for the following module:
//
// (func (export "add") (param i32 i32) (result i32)
// get_local 0
// get_local 1
// i32.add)
//
const char csource[] = R"(
let bytes = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01,
0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07,
0x07, 0x01, 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, 0x0a, 0x09, 0x01,
0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
]);
let module = new WebAssembly.Module(bytes);
let instance = new WebAssembly.Instance(module);
instance.exports.add(3, 4);
)";
// Create a string containing the JavaScript source code.
v8::Local<v8::String> source =
v8::String::NewFromUtf8Literal(isolate, csource);
// Compile the source code.
v8::Local<v8::Script> script =
v8::Script::Compile(context, source).ToLocalChecked();
// Run the script to get the result.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
// Convert the result to a uint32 and print it.
uint32_t number = result->Uint32Value(context).ToChecked();
printf("3 + 4 = %u\n", number);
}
}
// Dispose the isolate and tear down V8.
isolate->Dispose();
v8::V8::Dispose();
v8::V8::DisposePlatform();
delete create_params.array_buffer_allocator;
return 0;
}
Hello, World!
3 + 4 = 7