Build Javet from Scratch

Build V8

Please follow the official guide to build V8. If you face any issues, you may contact @sjtucaocao.

Prepare V8

  • Clone the source code.

  • Checkout a proper version.

Also, please make sure args.gn file looks like the following.

  • x86_64-non-i18n

dcheck_always_on = false
is_component_build = false
is_debug = false
symbol_level = 0
target_cpu = "x64"
use_custom_libcxx = false
v8_enable_i18n_support = false
v8_enable_pointer_compression = false
v8_enable_sandbox = false
v8_monolithic = true
v8_static_library = true
v8_target_cpu = "x64"
v8_use_external_startup_data = false
  • x86_64-i18n

dcheck_always_on = false
is_component_build = false
is_debug = false
symbol_level = 0
target_cpu = "x64"
use_custom_libcxx = false
v8_enable_i18n_support = true
v8_enable_pointer_compression = false
v8_enable_sandbox = false
v8_monolithic = true
v8_static_library = true
v8_target_cpu = "x64"
v8_use_external_startup_data = false
  • arm64-non-i18n

dcheck_always_on = false
is_component_build = false
is_debug = false
symbol_level = 0
target_cpu = "arm64"
use_custom_libcxx = false
v8_enable_i18n_support = false
v8_enable_pointer_compression = false
v8_enable_sandbox = false
v8_monolithic = true
v8_static_library = true
v8_target_cpu = "arm64"
v8_use_external_startup_data = false
  • arm64-i18n

dcheck_always_on = false
is_component_build = false
is_debug = false
symbol_level = 0
target_cpu = "arm64"
use_custom_libcxx = false
v8_enable_i18n_support = true
v8_enable_pointer_compression = false
v8_enable_sandbox = false
v8_monolithic = true
v8_static_library = true
v8_target_cpu = "arm64"
v8_use_external_startup_data = false

Build V8 for Linux arm64

export PATH=${DEPOT_TOOLS_HOME}:$PATH
cd ${V8_HOME}

# non-i18n
mkdir -p out.gn.non-i18n/arm64.release
cp ${JAVET_HOME}/scripts/v8/gn/linux-arm64-non-i18n-args.gn out.gn.non-i18n/arm64.release/args.gn
gn gen out.gn.non-i18n/arm64.release
ninja -C out.gn.non-i18n/arm64.release v8_monolith

# i18n
mkdir -p out.gn.i18n/arm64.release
cp ${JAVET_HOME}/scripts/v8/gn/linux-arm64-i18n-args.gn out.gn.i18n/arm64.release/args.gn
gn gen out.gn.i18n/arm64.release
ninja -C out.gn.i18n/arm64.release v8_monolith

Build V8 for Linux x86_64

export PATH=${DEPOT_TOOLS_HOME}:$PATH
cd ${V8_HOME}

# non-i18n
mkdir -p out.gn.non-i18n/x64.release
cp ${JAVET_HOME}/scripts/v8/gn/linux-x86_64-non-i18n-args.gn out.gn.non-i18n/x86_64.release/args.gn
gn gen out.gn.non-i18n/x64.release
ninja -C out.gn.non-i18n/x64.release v8_monolith

# i18n
mkdir -p out.gn.i18n/x64.release
cp ${JAVET_HOME}/scripts/v8/gn/linux-x86_64-i18n-args.gn out.gn.i18n/x86_64.release/args.gn
gn gen out.gn.i18n/x64.release
ninja -C out.gn.i18n/x64.release v8_monolith

Build V8 for Mac OS arm64

export PATH=${DEPOT_TOOLS_HOME}:$PATH
cd ${V8_HOME}

# non-i18n
mkdir -p out.gn.non-i18n/arm64.release
cp ${JAVET_HOME}/scripts/v8/gn/macos-arm64-non-i18n-args.gn out.gn.non-i18n/arm64.release/args.gn
gn gen out.gn.non-i18n/arm64.release
ninja -C out.gn.non-i18n/arm64.release v8_monolith

# i18n
mkdir -p out.gn.i18n/arm64.release
cp ${JAVET_HOME}/scripts/v8/gn/macos-arm64-i18n-args.gn out.gn.i18n/arm64.release/args.gn
gn gen out.gn.i18n/arm64.release
ninja -C out.gn.i18n/arm64.release v8_monolith

Build V8 for Mac OS x86_64

export PATH=${DEPOT_TOOLS_HOME}:$PATH
cd ${V8_HOME}

# non-i18n
mkdir -p out.gn.non-i18n/x64.release
cp ${JAVET_HOME}/scripts/v8/gn/macos-x86_64-non-i18n-args.gn out.gn.non-i18n/x86_64.release/args.gn
gn gen out.gn.non-i18n/x64.release
ninja -C out.gn.non-i18n/x64.release v8_monolith

# i18n
mkdir -p out.gn.i18n/x64.release
cp ${JAVET_HOME}/scripts/v8/gn/macos-x86_64-i18n-args.gn out.gn.i18n/x86_64.release/args.gn
gn gen out.gn.i18n/x64.release
ninja -C out.gn.i18n/x64.release v8_monolith

Build V8 for Windows

Caution

The patch script requires Python 3.

set PATH=%DEPOT_TOOLS_HOME%;%PATH%
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
cd %V8_HOME%

# non-i18n
md out.gn\x64.release
copy %JAVET_HOME%\scripts\v8\gn\windows-x86_64-non-i18n-args.gn out.gn\x86_64.release\args.gn
gn gen out.gn/x64.release
ninja -C out.gn/x64.release v8_monolith
python %JAVET_HOME%\scripts\python\patch_v8_build.py -p .\
ninja -C out.gn/x64.release v8_monolith
move out.gn\x64.release out.gn.non-i18n
gn gen --ide=vs out.gn.non-i18n\x64.solution

# i18n
md out.gn\x64.release
copy %JAVET_HOME%\scripts\v8\gn\windows-x86_64-i18n-args.gn out.gn\x86_64.release\args.gn
gn gen out.gn/x64.release
ninja -C out.gn/x64.release v8_monolith
python %JAVET_HOME%\scripts\python\patch_v8_build.py -p .\
ninja -C out.gn/x64.release v8_monolith
move out.gn\x64.release out.gn.i18n
gn gen --ide=vs out.gn.i18n\x64.solution

Build V8 for Android

export PATH=${DEPOT_TOOLS_HOME}:$PATH
cd ${V8_HOME}

# arm non-i18n
mkdir -p out.gn.non-i18n/arm.release
cp ${JAVET_HOME}/scripts/v8/gn/android-arm-non-i18n-args.gn out.gn.non-i18n/arm.release/args.gn
gn gen out.gn.non-i18n/arm.release
ninja -C out.gn.non-i18n/arm.release v8_monolith

# arm i18n
mkdir -p out.gn.i18n/arm.release
cp ${JAVET_HOME}/scripts/v8/gn/android-arm-i18n-args.gn out.gn.i18n/arm.release/args.gn
gn gen out.gn.i18n/arm.release
ninja -C out.gn.i18n/arm.release v8_monolith

# arm64 non-i18n
mkdir -p out.gn.non-i18n/arm64.release
cp ${JAVET_HOME}/scripts/v8/gn/android-arm64-non-i18n-args.gn out.gn.non-i18n/arm64.release/args.gn
gn gen out.gn.non-i18n/arm64.release
ninja -C out.gn.non-i18n/arm64.release v8_monolith

# arm64 i18n
mkdir -p out.gn.i18n/arm64.release
cp ${JAVET_HOME}/scripts/v8/gn/android-arm64-i18n-args.gn out.gn.i18n/arm64.release/args.gn
gn gen out.gn.i18n/arm64.release
ninja -C out.gn.i18n/arm64.release v8_monolith

# x86 non-i18n
mkdir -p out.gn.non-i18n/ia32.release
cp ${JAVET_HOME}/scripts/v8/gn/android-x86-non-i18n-args.gn out.gn.non-i18n/ia32.release/args.gn
gn gen out.gn.non-i18n/ia32.release
ninja -C out.gn.non-i18n/ia32.release v8_monolith

# x86 i18n
mkdir -p out.gn.i18n/ia32.release
cp ${JAVET_HOME}/scripts/v8/gn/android-x86-i18n-args.gn out.gn.i18n/ia32.release/args.gn
gn gen out.gn.i18n/ia32.release
ninja -C out.gn.i18n/ia32.release v8_monolith

# x86_64 non-i18n
mkdir -p out.gn.non-i18n/x64.release
cp ${JAVET_HOME}/scripts/v8/gn/android-x86_64-non-i18n-args.gn out.gn.non-i18n/x64.release/args.gn
gn gen out.gn.non-i18n/x64.release
ninja -C out.gn.non-i18n/x64.release v8_monolith

# x86_64 i18n
mkdir -p out.gn.i18n/x64.release
cp ${JAVET_HOME}/scripts/v8/gn/android-x86_64-i18n-args.gn out.gn.i18n/x64.release/args.gn
gn gen out.gn.i18n/x64.release
ninja -C out.gn.i18n/x64.release v8_monolith

Why Patching V8?

A few ninja files set certain warnings as errors so that MSVC stops compilation. The patch is to turn off those errors.

Build Node.js

Please follow Building Node.js to build the static and LTS version of Node.js libraries.

Prepare Node.js

  • Clone the source code.

  • Checkout a proper version.

Build Node.js on Linux

Caution

The patch script requires Python 3.

cd ${NODE_HOME}
python3 ${JAVET_HOME}/scripts/python/patch_node_build.py -p ${NODE_HOME}
./configure --enable-static --without-intl
python3 ${JAVET_HOME}/scripts/python/patch_node_build.py -p ${NODE_HOME}
make -j4

Why Patching Node.js?

  • First patch: All static node libraries are <thin> libraries. The patch is to disable <thin>.

  • Second patch: Many static node libraries are not compiled to position independent code and link phase is broken with the following error. The patch is to set -fPIC to those make files.

    /usr/bin/ld: /....../out/Release/libnode.a(node_binding.o): relocation R_X86_64_TPOFF32 against _ZN4nodeL23thread_local_modpendingE can not be used when making a shared object; recompile with -fPIC

Build Node.js on Mac OS

cd ${NODE_HOME}
./configure --enable-static --without-intl
make -j4

Build Node.js on Windows

cd %NODE_HOME%
vcbuild.bat static without-intl vs2022

Build Javet JNI Library

Once Node.js and V8 are ready, please navigate to ${JAVET_HOME}/cpp, make sure CMake is accessible and execute corresponding build script.

OS

Node.js Command

V8 Command

Linux arm64

sh build-linux-arm64.sh -DNODE_DIR=${NODE_HOME}

sh build-linux-arm64.sh -DV8_DIR=${V8_HOME}

Linux x86_64

sh build-linux-x86_64.sh -DNODE_DIR=${NODE_HOME}

sh build-linux-x86_64.sh -DV8_DIR=${V8_HOME}

Mac OS

sh build-macos.sh -DNODE_DIR=${NODE_HOME}

sh build-macos.sh -DV8_DIR=${V8_HOME}

Windows

build-windows.cmd -DNODE_DIR=%NODE_HOME%

build-windows.cmd -DV8_DIR=%V8_HOME% -T ClangCL

After a while, the following libraries will be placed in folder ${JAVET_HOME}/src/main/resources.

OS

Node.js Library

V8 Library

Linux arm64

libjavet-node-linux-arm64.v.*.*.*.so

libjavet-v8-linux-arm64.v.*.*.*.so

Linux x86_64

libjavet-node-linux-x86_64.v.*.*.*.so

libjavet-v8-linux-x86_64.v.*.*.*.so

Mac OS arm64

libjavet-node-macos-arm64.v.*.*.*.dylib

libjavet-v8-macos-arm64.v.*.*.*.dylib

Mac OS x86_64

libjavet-node-macos-x86_64.v.*.*.*.dylib

libjavet-v8-macos-x86_64.v.*.*.*.dylib

Windows

libjavet-node-windows-x86_64.v.*.*.*.dll

libjavet-v8-windows-x86_64.v.*.*.*.dll

Build Javet JNI Library for Android

Once V8 are ready, please navigate to ./cpp, make sure CMake is accessible and execute corresponding build script.

Arch

Command

arm

sh ./build-android.sh -DV8_DIR=${V8_HOME} -DCMAKE_ANDROID_NDK=${ANDROID_NDK_HOME} -DCMAKE_ANDROID_ARCH=arm

arm64

sh ./build-android.sh -DV8_DIR=${V8_HOME} -DCMAKE_ANDROID_NDK=${ANDROID_NDK_HOME} -DCMAKE_ANDROID_ARCH=arm64

x86

sh ./build-android.sh -DV8_DIR=${V8_HOME} -DCMAKE_ANDROID_NDK=${ANDROID_NDK_HOME} -DCMAKE_ANDROID_ARCH=x86

x86_64

sh ./build-android.sh -DV8_DIR=${V8_HOME} -DCMAKE_ANDROID_NDK=${ANDROID_NDK_HOME} -DCMAKE_ANDROID_ARCH=x86_64

After a while, the following libraries will be placed in folder ${JAVET_HOME}/android/javet-android/src/main/jniLibs.

Arch

Library

arm

armeabi-v7a/libjavet-v8-android.v.*.*.*.so

arm64

arm64-v8a/libjavet-v8-android.v.*.*.*.so

x86

x86/libjavet-v8-android.v.*.*.*.so

x86_64

x86_64/libjavet-v8-android.v.*.*.*.so

Build Javet JNI Library with i18n

To enable i18n support, please append -DENABLE_I18N=1 to the command.

Build Javet Jar

Build Javet for Linux, Mac OS and Windows

cd ${JAVET_HOME}
gradle build test

After a while, javet-*.*.*.jar will be placed in folder ${JAVET_HOME}/build/libs.

Build Javet for Android

cd ${JAVET_HOME}/android
gradle build

After a while, javet-android-*.*.*-release.aar will be placed in folder ${JAVET_HOME}/android/javet-android/build/outputs/aar.