简体   繁体   中英

How do I embed v8 on Windows?

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.

It seems like the building procedure for v8 changes frequently. There are a few tutorials out there, but they all seem to be outdated. So until the Chromium team decides to change it again, these steps should work for the time being.

Getting depot tools and the v8 source code

These steps were copied from here .

  1. Uninstall Python. I had problems with the v8 compiler scripts finding the wrong Python executable instead of the one provided in depot tools. Make your life easier by temporarily uninstalling Python.
  2. Configure Visual Studio and your development environment. You need VS2019 with the components "Desktop development with C++" and "MFC/ATL support". You will need the Windows 10 SDK and with the "Debugging Tools For Windows" feature.
  3. 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.

  1. Add depot_tools to the start of your PATH (must be ahead of any installs of Python). Assuming you unzipped the bundle to C:\src\depot_tools , open:

Control Panel → System and Security → System → Advanced system settings

If you have Administrator access, modify the PATH system variable and put C:\src\depot_tools at the front (or at least in front of any directory that might already have a copy of Python or Git).

If you don't have Administrator access, you can add a user-level PATH environment variable and put C:\src\depot_tools at the front, but if your system PATH has a Python in it, you will be out of luck.

  1. Also, add a DEPOT_TOOLS_WIN_TOOLCHAIN system variable in the same way, and set it to 0 . This tells depot_tools to use your locally installed version of Visual Studio (by default, depot_tools will try to use a google-internal version).

You may also have to set variable vs2017_install or vs2019_install to your installation path of Visual Studio 2017 or 19, like set vs2019_install=C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional for Visual Studio 2019.

  1. From a cmd.exe shell, run the command gclient . 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 (eg, 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.
  1. Open command prompt and type where python and confirm that the depot_tools python.bat comes ahead of any copies of python.exe . Failing to ensure this can lead to overbuilding when using gn.

  2. App Execution Aliases can conflict with other installations of python on the system so disable these for python.exe and python3.exe by opening App execution aliases section of Control Panel and unticking the boxes next to both of these that point to App Installer.

  3. cd to the directory you want to store v8 and run mkdir v8 && cd v8 && fetch v8 .

  4. cd v8 and git checkout 9.0.257.19 , which is the latest stable at the time of this writing.

  5. Apply this patch:

diff --git a/BUILD.gn b/BUILD.gn
index a9ab6783fa..ede2774d18 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1051,6 +1051,7 @@ config("toolchain") {
       "/wd4723",  # https://crbug.com/v8/7771
       "/wd4724",  # https://crbug.com/v8/7771
       "/wd4800",  # Forcing value to bool.
+      "/wd4805",
     ]
   }

This is to silence a warning about comparing a bool to an int. Hopefully they know what they're doing.

  1. Run gclient sync to get all dependencies.

Compile v8

  1. Run python tools/dev/v8gen.py x64.debug .

  2. Replace the contents of 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

  1. Run ninja -C out.gn/x64.debug v8_monolith .

  2. Run python tools/dev/v8gen.py x64.release .

  3. Replace the contents of v8\out.gn\x64.release\args.gn with:

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

  1. Run ninja -C out.gn/x64.release v8_monolith .

Hello World

  1. Create a new empty C++ project in Visual Studio.

  2. Add the library directories to the project.

    1. Go to your project properties and change the configuration to All Configurations and Platform to x64.
    2. Under VC++ Directories, add the absolute path to v8\include to Include Directories. Click Apply after this step and after each of the following steps.
    3. Change Configuration to Debug and add the absolute path to v8\out.gn\x64.debug\obj to Library Directories.
    4. Repeat step 3 for the Release configuration, with the path to v8\out.gn\x64.release\obj . 配置设置
    5. Change to All Configurations, go to Linker | Input, and add the following files to Additional Dependencies: v8_monolith.lib;dbghelp.lib;Winmm.lib; .
    6. Go to C/C++ | Preprocessor and add V8_COMPRESS_POINTERS;_ITERATOR_DEBUG_LEVEL=0; to the Preprocessor Definitions.
    7. Change to Debug configuration. Go to C/C++ | Code Generation and change Runtime Library to Multi-threaded Debug (/MTd).
    8. Change to Release configuration. Change Runtime Library to Multi-threaded (/MT).
  3. Add a new main.cpp file and add the following code which is a slightly modified version of v8\samples\hello-world.cc .

// 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.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::ShutdownPlatform();
  delete create_params.array_buffer_allocator;
  return 0;
}

  1. Compile and run both Debug and Release configurations. They should output:
Hello, World!
3 + 4 = 7

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM