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
clang_use_chrome_plugins = false
compiler_timing = false
dcheck_always_on = false
is_component_build = false
is_debug = false
is_official_build = false
symbol_level = 0
target_cpu = "x64"
use_blink = false
use_clang_modules = false
use_custom_libcxx = true
use_custom_libunwind = true
use_safe_libstdcxx = false
v8_enable_external_code_space = true
v8_enable_i18n_support = false
v8_enable_pointer_compression = true
v8_enable_pointer_compression_shared_cage = false
v8_enable_sandbox = true
v8_enable_temporal_support = true
v8_enable_webassembly = true
v8_monolithic = true
v8_monolithic_for_shared_library = true
v8_static_library = true
v8_target_cpu = "x64"
v8_use_external_startup_data = false
x86_64-i18n
clang_use_chrome_plugins = false
compiler_timing = false
dcheck_always_on = false
is_component_build = false
is_debug = false
is_official_build = false
symbol_level = 0
target_cpu = "x64"
use_blink = false
use_clang_modules = false
use_custom_libcxx = true
use_custom_libunwind = true
use_safe_libstdcxx = false
v8_enable_external_code_space = true
v8_enable_i18n_support = true
v8_enable_pointer_compression = true
v8_enable_pointer_compression_shared_cage = false
v8_enable_sandbox = true
v8_enable_temporal_support = true
v8_enable_webassembly = true
v8_monolithic = true
v8_monolithic_for_shared_library = true
v8_static_library = true
v8_target_cpu = "x64"
v8_use_external_startup_data = false
arm64-non-i18n
clang_use_chrome_plugins = false
compiler_timing = false
dcheck_always_on = false
is_component_build = false
is_debug = false
is_official_build = false
symbol_level = 0
target_cpu = "arm64"
use_blink = false
use_clang_modules = false
use_custom_libcxx = true
use_custom_libunwind = true
use_safe_libstdcxx = false
v8_enable_external_code_space = true
v8_enable_i18n_support = false
v8_enable_pointer_compression = true
v8_enable_pointer_compression_shared_cage = false
v8_enable_sandbox = true
v8_enable_temporal_support = true
v8_enable_webassembly = true
v8_monolithic = true
v8_monolithic_for_shared_library = true
v8_static_library = true
v8_target_cpu = "arm64"
v8_use_external_startup_data = false
arm64-i18n
clang_use_chrome_plugins = false
compiler_timing = false
dcheck_always_on = false
is_component_build = false
is_debug = false
is_official_build = false
symbol_level = 0
target_cpu = "arm64"
use_blink = false
use_clang_modules = false
use_custom_libcxx = true
use_custom_libunwind = true
use_safe_libstdcxx = false
v8_enable_external_code_space = true
v8_enable_i18n_support = true
v8_enable_pointer_compression = true
v8_enable_pointer_compression_shared_cage = false
v8_enable_sandbox = true
v8_enable_temporal_support = true
v8_enable_webassembly = true
v8_monolithic = true
v8_monolithic_for_shared_library = 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 Deno.
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
deno --allow-all %JAVET_HOME%\scripts\deno\patch_v8_build.ts -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
deno --allow-all %JAVET_HOME%\scripts\deno\patch_v8_build.ts -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.
Patch the source tree.
--osis the OS being built for, one ofandroid,linux,macosorwindows. It is never detected because Android is cross compiled from Linux. Add--i18nfor an i18n build:android-configureruns./configureitself, so on Android the ICU choice has to be patched in rather than passed on the command line. Every other OS takes it on its own configure command line and ignores the flag. Re-running the script is safe.
Caution
The patch script requires Deno.
deno --allow-all ${JAVET_HOME}/scripts/deno/patch_node_build.ts -p ${NODE_HOME} --os <os> [--i18n]
Build Node.js on Linux¶
cd ${NODE_HOME}
./configure --enable-static --without-intl --v8-enable-temporal-support
export CFLAGS="-fPIC -ftls-model=global-dynamic -Wno-return-type"
export CXXFLAGS="${CFLAGS}"
export LDFLAGS="${CFLAGS}"
make -j4
Why Patching Node.js?¶
Static libraries: All static node libraries are
<thin>libraries. The patch is to disable<thin>.Temporal: Node.js drops V8's Temporal whenever it is built without the bundled ICU, because V8 then links a baked-in copy of
zoneinfo64.resthat only V8's GN build knows how to generate (themake_temporal_zoneinfo_cppaction). The patch ports that action togyp, so--v8-enable-temporal-supportalso works for--without-intl.Thread local storage: V8's
V8_TLS_MODELattribute makes the linker reject the shared library, so the patch drops it in favour of-ftls-model=global-dynamic.The flags: Many static node libraries are not compiled to position independent code and link phase is broken with the following error.
CFLAGS,CXXFLAGSandLDFLAGSset-fPICfor every target. GYP appends them to each target of the target toolset viaCFLAGS.target,CXXFLAGS.targetandLDFLAGS.target./usr/bin/ld: /....../out/Release/libnode.a(node_binding.o): relocation R_X86_64_TPOFF32 against
_ZN4nodeL23thread_local_modpendingEcan 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 --v8-enable-temporal-support
make -j4
Build Node.js on Windows¶
cd %NODE_HOME%
vcbuild.bat static without-intl v8temporal vs2026
Build Javet JNI Library¶
Caution
The build script requires Deno.
Once Node.js and V8 are ready, please navigate to ${JAVET_HOME}/cpp, make sure CMake is accessible and execute the unified build script.
The build script supports additional options:
--i18n- Enable internationalization support--cpu-count <n>- Set the number of CPU cores for parallel builds (default: auto-detect)--log-debug,--log-error,--log-info,--log-trace- Enable logging for debugging
OS |
Node.js Command |
V8 Command |
|---|---|---|
Linux arm64 |
|
|
Linux x86_64 |
|
|
Mac OS arm64 |
|
|
Mac OS x86_64 |
|
|
Windows |
|
|
After a while, the following libraries will be placed in folder ${JAVET_HOME}/src/main/resources.
OS |
Node.js Library |
V8 Library |
|---|---|---|
Linux arm64 |
|
|
Linux x86_64 |
|
|
Mac OS arm64 |
|
|
Mac OS x86_64 |
|
|
Windows |
|
|
Build Javet JNI Library for Android¶
Caution
The build script requires Deno.
Once V8 are ready, please navigate to ${JAVET_HOME}/cpp, make sure CMake is accessible and execute the unified build script.
The Android NDK path can be specified using --android-ndk option. For additional options, see the Build Javet JNI Library section above.
Arch |
Command |
|---|---|
arm |
|
arm64 |
|
x86 |
|
x86_64 |
|
After a while, the following libraries will be placed in folder ${JAVET_HOME}/android/javet-android/src/main/jniLibs.
Arch |
Library |
|---|---|
arm |
|
arm64 |
|
x86 |
|
x86_64 |
|
Build Javet JNI Library with i18n¶
To enable i18n support, please append --i18n to the command.
For example:
# V8 build with i18n on Linux x86_64
deno run build --os linux --arch x86_64 --v8-dir ${V8_HOME} --i18n
# Node.js build with i18n on macOS arm64
deno run build --os macos --arch arm64 --node-dir ${NODE_HOME} --i18n
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.