Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for building javet native libraries for linux-arm64 #235

Merged
merged 1 commit into from Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 17 additions & 7 deletions cpp/CMakeLists.txt
Expand Up @@ -88,7 +88,7 @@ if(DEFINED V8_DIR)
set(V8_RELEASE_DIR ${V8_DIR}/out.gn/x64.release)
endif()
else()
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "(arm64|aarch64)")
set(V8_RELEASE_DIR ${V8_DIR}/out.gn/arm64.release)
else()
set(V8_RELEASE_DIR ${V8_DIR}/out.gn/x64.release)
Expand Down Expand Up @@ -117,20 +117,24 @@ if(DEFINED NODE_DIR)
base64 brotli cares histogram llhttp nghttp2 nghttp3 ngtcp2 openssl simdutf torque_base uvwasi
v8_base_without_compiler v8_compiler v8_init v8_initializers
v8_libbase v8_libplatform v8_snapshot v8_zlib zlib zlib_adler32_simd zlib_inflate_chunk_simd)
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "(arm64|aarch64)")
list(APPEND importLibraries base64_neon64)
else()
list(APPEND importLibraries base64_avx base64_avx2 base64_sse41 base64_sse42 base64_ssse3)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
list(APPEND importLibraries libnode libuv)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "(arm64|aarch64)")
list(APPEND importLibraries node uv)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
list(APPEND importLibraries node node_text_start uv)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
list(APPEND importLibraries node uv)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
list(APPEND importLibraries zlib_arm_crc32)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "(arm64|aarch64)")
list(APPEND importLibraries zlib_arm_crc32)
else()
list(APPEND importLibraries zlib_crc32_simd)
endif()
Expand All @@ -146,6 +150,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(JAVET_LIB_PREFIX "libjavet")
set(JAVET_LIB_SYSTEM "windows")
set(JAVET_LIB_ARCH x86_64)
set(JAVET_LIB_ARCH x86_64)
# Generate PDB file
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
Expand Down Expand Up @@ -180,14 +185,19 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_library(Javet SHARED ${sourceFiles})
add_library(JavetStatic STATIC ${sourceFiles})
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "(arm64|x86_64|aarch64)")
set(JAVET_LIB_SYSTEM "linux")
set(JAVET_LIB_ARCH x86_64)
add_definitions(-D__x86_64__)
if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(JAVET_LIB_ARCH x86_64)
add_definitions(-D__x86_64__)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64 ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 ")
else()
set(JAVET_LIB_ARCH arm64)
add_definitions(-D__arm64__)
endif()
add_definitions(-D__linux__)
list(APPEND includeDirs $ENV{JAVA_HOME}/include/linux)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64 ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 ")
if(DEFINED V8_DIR)
foreach(importLibrary ${importLibraries})
set_target_properties(${importLibrary} PROPERTIES IMPORTED_LOCATION ${V8_RELEASE_DIR}/obj/lib${importLibrary}.a)
Expand Down
117 changes: 117 additions & 0 deletions docker/linux-arm64/base_all_in_one.Dockerfile
@@ -0,0 +1,117 @@
# Copyright (c) 2021 caoccao.com Sam Cao
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Usage: docker build -t sjtucaocao/javet-arm64:2.1.0 -f docker/linux-arm64/base_all_in_one.Dockerfile .

ARG JAVET_NODE_VERSION=18.15.0
ARG JAVET_V8_VERSION=11.1.277.14

FROM ubuntu:20.04
WORKDIR /

# Update Ubuntu
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install --upgrade -qq -y --no-install-recommends git curl wget build-essential software-properties-common patchelf maven sudo zip unzip execstack cmake pkg-config
RUN apt-get install --upgrade -qq -y --no-install-recommends python3 python python3-pip python3-distutils python3-testresources
RUN apt-get upgrade -y
RUN pip3 install coloredlogs

# Install CMake
RUN wget https://github.com/Kitware/CMake/releases/download/v3.25.1/cmake-3.25.1-linux-aarch64.sh
RUN chmod 755 cmake-3.25.1-linux-aarch64.sh
RUN mkdir -p /usr/lib/cmake
RUN ./cmake-3.25.1-linux-aarch64.sh --skip-license --exclude-subdir --prefix=/usr/lib/cmake
RUN ln -sf /usr/lib/cmake/bin/cmake /usr/bin/cmake
RUN ln -sf /usr/lib/cmake/bin/cmake /bin/cmake
RUN rm cmake-3.25.1-linux-aarch64.sh

# Install LLVM
RUN wget https://apt.llvm.org/llvm.sh
RUN chmod +x llvm.sh
RUN ./llvm.sh 15 all

# Prepare V8
RUN mkdir google
WORKDIR /google
RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
WORKDIR /google/depot_tools
RUN git checkout remotes/origin/main
ENV PATH=/google/depot_tools:$PATH
WORKDIR /google
RUN fetch v8
WORKDIR /google/v8
RUN git checkout ${JAVET_V8_VERSION}
RUN sed -i 's/snapcraft/nosnapcraft/g' ./build/install-build-deps.sh
RUN ./build/install-build-deps.sh
RUN sed -i 's/nosnapcraft/snapcraft/g' ./build/install-build-deps.sh
WORKDIR /google
RUN gclient sync
RUN echo V8 preparation is completed.

# Build V8
WORKDIR /google/v8
RUN sed -i -e "s/target_cpu=\"x64\" v8_target_cpu=\"arm64/target_cpu=\"arm64\" v8_target_cpu=\"arm64/" infra/mb/mb_config.pyl
RUN python3 tools/dev/v8gen.py arm64.release -- 'target_cpu="arm64"' 'v8_target_cpu="arm64"' v8_monolithic=true v8_use_external_startup_data=false is_component_build=false v8_enable_i18n_support=false v8_enable_pointer_compression=false v8_static_library=true symbol_level=0 use_custom_libcxx=false v8_enable_sandbox=false 'clang_base_path="/usr/lib/llvm-15"' clang_use_chrome_plugins=false blink_gc_plugin=false
COPY ./scripts/python/patch_v8_build.py .
RUN ninja -C out.gn/arm64.release v8_monolith || python3 patch_v8_build.py -p ./
RUN ninja -C out.gn/arm64.release v8_monolith
RUN rm patch_v8_build.py
RUN echo V8 build is completed.

# Prepare Node.js v18
WORKDIR /
RUN git clone https://github.com/nodejs/node.git
WORKDIR /node
RUN git checkout v${JAVET_NODE_VERSION}
RUN echo Node.js preparation is completed.

# Build Node.js
WORKDIR /node
COPY ./scripts/python/patch_node_build.py .
RUN python3 patch_node_build.py -p ./
RUN ./configure --enable-static --without-intl
RUN python3 patch_node_build.py -p ./
RUN rm patch_node_build.py
RUN make -j4
RUN echo Node.js build is completed.

# Prepare Javet Build Environment
RUN apt-get install --upgrade -qq -y --no-install-recommends openjdk-8-jdk
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-arm64
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
ENV SDKMAN_HOME="/root/.sdkman"
ENV GRADLE_HOME="${SDKMAN_HOME}/candidates/gradle/current"
RUN curl -s https://get.sdkman.io | bash
RUN source ${SDKMAN_HOME}/bin/sdkman-init.sh && sdk install gradle 7.2
ENV PATH=$GRADLE_HOME/bin:$PATH

# Shrink
RUN rm -rf ${SDKMAN_HOME}/archives/*
RUN rm -rf ${SDKMAN_HOME}/tmp/*
RUN apt-get clean -y
RUN rm -rf /var/lib/apt/lists/*
WORKDIR /

# Pre-cache Dependencies
RUN mkdir Javet
WORKDIR /Javet
COPY . .
RUN gradle dependencies
WORKDIR /
RUN rm -rf /Javet

# Completed
RUN echo Javet build base image is completed.
32 changes: 32 additions & 0 deletions docker/linux-arm64/base_gradle.Dockerfile
@@ -0,0 +1,32 @@
# Copyright (c) 2021-2023 caoccao.com Sam Cao
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Usage: docker build \
# -t sjtucaocao/javet:arm64-2.1.0 \
# --build-arg JAVET_REPO=sjtucaocao/javet \
# -f docker/linux-arm64/base_gradle.Dockerfile .

ARG JAVET_REPO=sjtucaocao/javet

FROM ${JAVET_REPO}:arm64-base-jvm

ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-arm64

RUN mkdir Javet
WORKDIR /Javet
COPY . .
RUN gradle dependencies
WORKDIR /
RUN rm -rf /Javet
60 changes: 60 additions & 0 deletions docker/linux-arm64/base_jvm.Dockerfile
@@ -0,0 +1,60 @@
# Copyright (c) 2021 caoccao.com Sam Cao
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Usage: docker build -t sjtucaocao/javet:x86_64-base-jvm-${{ env.JAVET_VERSION }} -f docker/linux-x86_64/base_jvm.Dockerfile .

FROM ubuntu:20.04
WORKDIR /

# Update Ubuntu
ENV DEBIAN_FRONTEND=noninteractive
# files need to be cleaned/deleted in the same RUN layer that adds them, else there is no actual size reduction benefit
# the files remain in the image, just the layer marks the file as deleted and is not visible inside the OS
RUN apt-get update --yes \
&& apt-get install --upgrade -qq --yes --no-install-recommends \
build-essential cmake curl execstack git maven openjdk-8-jdk \
patchelf python3 python python3-pip python3-distutils python3-testresources \
software-properties-common sudo unzip wget zip pkg-config \
&& apt-get upgrade --yes \
&& pip3 install --no-cache-dir coloredlogs \
&& apt-get clean --yes

# Install CMake
RUN wget https://github.com/Kitware/CMake/releases/download/v3.25.1/cmake-3.25.1-linux-aarch64.sh \
&& chmod 755 cmake-3.25.1-linux-aarch64.sh \
&& mkdir -p /usr/lib/cmake \
&& ./cmake-3.25.1-linux-aarch64.sh --skip-license --exclude-subdir --prefix=/usr/lib/cmake \
&& ln -sf /usr/lib/cmake/bin/cmake /usr/bin/cmake \
&& ln -sf /usr/lib/cmake/bin/cmake /bin/cmake \
&& rm cmake-3.25.1-linux-aarch64.sh

# Prepare Javet Build Environment
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-arm64
ENV SDKMAN_HOME="/root/.sdkman"
ENV GRADLE_HOME="${SDKMAN_HOME}/candidates/gradle/current"
ENV PATH=$GRADLE_HOME/bin:$PATH

RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# these two commands need to be on separate lines, else the symlink created above is not visible to the commands run below.
# if the two RUN commmands are merged, we get the error "source: not found"
RUN curl -s https://get.sdkman.io | bash \
&& source ${SDKMAN_HOME}/bin/sdkman-init.sh \
&& sdk install gradle 7.2 \
&& rm -rf ${SDKMAN_HOME}/archives/* \
&& rm -rf ${SDKMAN_HOME}/tmp/*

RUN wget https://apt.llvm.org/llvm.sh
RUN chmod +x llvm.sh
RUN ./llvm.sh 15 all
40 changes: 40 additions & 0 deletions docker/linux-arm64/base_node.Dockerfile
@@ -0,0 +1,40 @@
# Copyright (c) 2021 caoccao.com Sam Cao
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Usage: docker build \
# -t sjtucaocao/javet:arm64-base-node_18.15.0 \
# --build-arg JAVET_REPO=sjtucaocao/javet \
# --build-arg JAVET_NODE_VERSION=18.15.0 \
# -f docker/linux-arm64/base_node.Dockerfile .

ARG JAVET_REPO=sjtucaocao/javet
ARG JAVET_NODE_VERSION=18.15.0

FROM ${JAVET_REPO}:arm64-base-jvm

ARG JAVET_NODE_VERSION

RUN if [ -z "$JAVET_NODE_VERSION" ]; then echo 'Build argument JAVET_NODE_VERSION must be specified. Exiting.'; exit 1; fi

# Prepare Node.js v18
WORKDIR /
COPY ./scripts/shell/fetch_node_source.sh .
RUN bash ./fetch_node_source.sh

# Build Node.js
WORKDIR /node
COPY ./scripts/python/patch_node_build.py .
COPY ./scripts/shell/build_node_source.sh .
RUN bash ./build_node_source.sh
46 changes: 46 additions & 0 deletions docker/linux-arm64/base_v8.Dockerfile
@@ -0,0 +1,46 @@
# Copyright (c) 2021 caoccao.com Sam Cao
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Usage: docker build \
# -t sjtucaocao/javet:arm64-base-v8_11.1.277.14 \
# --build-arg JAVET_REPO=sjtucaocao/javet \
# --build-arg JAVET_V8_VERSION=11.1.277.14 \
# -f docker/linux-arm64/base_v8.Dockerfile .

ARG JAVET_REPO=sjtucaocao/javet
ARG JAVET_V8_VERSION=11.1.277.14

FROM ${JAVET_REPO}:arm64-base-jvm

ARG JAVET_V8_VERSION

RUN if [ -z "$JAVET_V8_VERSION" ]; then echo 'Build argument JAVET_V8_VERSION must be specified. Exiting.'; exit 1; fi

# Prepare V8
WORKDIR /google
ENV DEPOT_TOOLS_UPDATE=0
ENV PATH=/google/depot_tools:$PATH
COPY ./scripts/shell/fetch_v8_source.sh .
RUN bash fetch_v8_source.sh

# Build V8
WORKDIR /google/v8
RUN sed -i -e "s/target_cpu=\"x64\" v8_target_cpu=\"arm64/target_cpu=\"arm64\" v8_target_cpu=\"arm64/" infra/mb/mb_config.pyl
RUN python3 tools/dev/v8gen.py arm64.release -- 'target_cpu="arm64"' 'v8_target_cpu="arm64"' v8_monolithic=true v8_use_external_startup_data=false is_component_build=false v8_enable_i18n_support=false v8_enable_pointer_compression=false v8_static_library=true symbol_level=0 use_custom_libcxx=false v8_enable_sandbox=false 'clang_base_path="/usr/lib/llvm-15"' clang_use_chrome_plugins=false blink_gc_plugin=false
COPY ./scripts/python/patch_v8_build.py .
RUN ninja -C out.gn/arm64.release v8_monolith || python3 patch_v8_build.py -p ./
RUN ninja -C out.gn/arm64.release v8_monolith
RUN rm patch_v8_build.py
RUN echo V8 build is completed.