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

Add support for cross-compiling for s390x platform #9455

Merged
merged 10 commits into from
Mar 23, 2023
4 changes: 3 additions & 1 deletion buildscripts/build_docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
set -eu -o pipefail

readonly buildscripts_dir="$(dirname "$(readlink -f "$0")")"
docker build -t grpc-java-artifacts "$buildscripts_dir"/grpc-java-artifacts
docker build -t grpc-java-artifacts-x86 "$buildscripts_dir"/grpc-java-artifacts
docker build -t grpc-java-artifacts-multiarch -f "$buildscripts_dir"/grpc-java-artifacts/Dockerfile.multiarch.base "$buildscripts_dir"/grpc-java-artifacts

10 changes: 10 additions & 0 deletions buildscripts/build_s390x_artifacts_in_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
set -exu -o pipefail

# first we need to install the prerequisites required for s390x cross compilation
apt-get update && apt-get install -y g++-s390x-linux-gnu
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to install g++-s390x-linux-gnu within the Dockerfile.

If we do that, do we need this build_s390x_artifacts_in_docker.sh any more? "$GRPC_JAVA_DIR"/buildscripts/run_in_docker.sh grpc-java-artifacts-x86 SKIP_TESTS=true ARCH=s390_64 /grpc-java/buildscripts/kokoro/unix.sh might just work.

(And that's making me want to remove build_artifacts_in_docker.sh, because we can simply run docker twice.)


# now kick off the build for the mvn artifacts for s390x
# mvn artifacts are stored in grpc-java/mvn-artifacts/
SKIP_TESTS=true ARCH=s390_64 "$(dirname $0)"/kokoro/unix.sh

15 changes: 15 additions & 0 deletions buildscripts/grpc-java-artifacts/Dockerfile.multiarch.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM ubuntu:22.04

# make sure apt-get works in unattended mode
ENV DEBIAN_FRONTEND=noninteractive

# install the OS-level prerequisites for building protobuf and running the gradle build
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends ca-certificates build-essential wget curl openjdk-8-jdk && \
apt-get autoclean -y && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*

ENV JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64

8 changes: 7 additions & 1 deletion buildscripts/kokoro/linux_artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ readonly GRPC_JAVA_DIR="$(cd "$(dirname "$0")"/../.. && pwd)"
trap spongify_logs EXIT

"$GRPC_JAVA_DIR"/buildscripts/build_docker.sh
"$GRPC_JAVA_DIR"/buildscripts/run_in_docker.sh /grpc-java/buildscripts/build_artifacts_in_docker.sh
"$GRPC_JAVA_DIR"/buildscripts/run_in_docker.sh grpc-java-artifacts-x86 /grpc-java/buildscripts/build_artifacts_in_docker.sh

# grpc-android, grpc-cronet and grpc-binder require the Android SDK, so build outside of Docker and
# use --include-build for its grpc-core dependency
Expand Down Expand Up @@ -53,3 +53,9 @@ SKIP_TESTS=true ARCH=aarch_64 "$GRPC_JAVA_DIR"/buildscripts/kokoro/unix.sh
# for ppc64le platform
sudo apt-get install -y g++-powerpc64le-linux-gnu
SKIP_TESTS=true ARCH=ppcle_64 "$GRPC_JAVA_DIR"/buildscripts/kokoro/unix.sh

# for s390x platform
# building these artifacts inside a Docker container as we have specific requirements
# for GCC (version 11.x needed) which in turn requires Ubuntu 22.04 LTS
"$GRPC_JAVA_DIR"/buildscripts/run_in_docker.sh grpc-java-artifacts-multiarch /grpc-java/buildscripts/build_s390x_artifacts_in_docker.sh

4 changes: 3 additions & 1 deletion buildscripts/kokoro/unix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
# ARCH=aarch_64 ./buildscripts/kokoro/unix.sh
# For ppc64le arch:
# ARCH=ppcle_64 ./buildscripts/kokoro/unix.sh
# For s390x arch:
# ARCH=s390_64 ./buildscripts/kokoro/unix.sh

# This script assumes `set -e`. Removing it may lead to undefined behavior.
set -exu -o pipefail
Expand Down Expand Up @@ -91,7 +93,7 @@ fi
LOCAL_MVN_TEMP=$(mktemp -d)
# Note that this disables parallel=true from GRADLE_FLAGS
if [[ -z "${ALL_ARTIFACTS:-}" ]]; then
if [[ "$ARCH" = "aarch_64" || "$ARCH" = "ppcle_64" ]]; then
if [[ "$ARCH" = "aarch_64" || "$ARCH" = "ppcle_64" || "$ARCH" = "s390_64" ]]; then
GRADLE_FLAGS+=" -x grpc-compiler:generateTestProto -x grpc-compiler:generateTestLiteProto"
GRADLE_FLAGS+=" -x grpc-compiler:testGolden -x grpc-compiler:testLiteGolden"
GRADLE_FLAGS+=" -x grpc-compiler:testDeprecatedGolden -x grpc-compiler:testDeprecatedLiteGolden"
Expand Down
3 changes: 3 additions & 0 deletions buildscripts/kokoro/upload_artifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ LOCAL_OTHER_ARTIFACTS="$KOKORO_GFILE_DIR"/github/grpc-java/artifacts/
# for linux ppc64le platform
[[ "$(find "$LOCAL_MVN_ARTIFACTS" -type f -iname 'protoc-gen-grpc-java-*-linux-ppcle_64.exe' | wc -l)" != '0' ]]

# for linux s390x platform
[[ "$(find "$LOCAL_MVN_ARTIFACTS" -type f -iname 'protoc-gen-grpc-java-*-linux-s390_64.exe' | wc -l)" != '0' ]]

# from macos job:
[[ "$(find "$LOCAL_MVN_ARTIFACTS" -type f -iname 'protoc-gen-grpc-java-*-osx-x86_64.exe' | wc -l)" != '0' ]]
# copy all x86 artifacts to aarch until native artifacts are built
Expand Down
2 changes: 2 additions & 0 deletions buildscripts/make_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ else
./configure --disable-shared --host=aarch64-linux-gnu --prefix="$INSTALL_DIR"
elif [[ "$ARCH" == ppc* ]]; then
./configure --disable-shared --host=powerpc64le-linux-gnu --prefix="$INSTALL_DIR"
elif [[ "$ARCH" == s390* ]]; then
./configure --disable-shared --host=s390x-linux-gnu --prefix="$INSTALL_DIR"
fi
# the same source dir is used for 32 and 64 bit builds, so we need to clean stale data first
make clean
Expand Down
4 changes: 3 additions & 1 deletion buildscripts/run_in_docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ quote() {
done
}

readonly docker_image=$1; shift

readonly grpc_java_dir="$(dirname "$(readlink -f "$0")")/.."
if [[ -t 0 ]]; then
DOCKER_ARGS="-it"
Expand All @@ -21,5 +23,5 @@ fi
# the original exit code. $DOCKER_ARGS can not be quoted, otherwise it becomes a '' which confuses
# docker.
exec docker run $DOCKER_ARGS --rm=true -v "${grpc_java_dir}":/grpc-java -w /grpc-java \
grpc-java-artifacts \
$docker_image \
bash -c "function fixFiles() { chown -R $(id -u):$(id -g) /grpc-java; }; trap fixFiles EXIT; $(quote "$@")"
5 changes: 4 additions & 1 deletion compiler/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ model {
cppCompiler.executable = 'aarch64-linux-gnu-g++'
linker.executable = 'aarch64-linux-gnu-g++'
}
target("s390_64")
target("s390_64") {
cppCompiler.executable = 's390x-linux-gnu-g++'
linker.executable = 's390x-linux-gnu-g++'
}
target("loongarch_64")
}
clang(Clang) {
Expand Down
7 changes: 7 additions & 0 deletions compiler/check-artifact.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ checkArch ()
format="$(powerpc64le-linux-gnu-objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")"
echo Format=$format
assertEq "$format" "elf64-powerpcle" $LINENO
elif [[ "$ARCH" == s390_64 ]]; then
format="$(s390x-linux-gnu-objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")"
echo Format=$format
assertEq "$format" "elf64-s390" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
Expand Down Expand Up @@ -115,6 +119,9 @@ checkDependencies ()
elif [[ "$ARCH" == ppcle_64 ]]; then
dump_cmd='powerpc64le-linux-gnu-objdump -x '"$1"' |grep "NEEDED"'
white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld64\.so\.2"
elif [[ "$ARCH" == s390_64 ]]; then
dump_cmd='s390x-linux-gnu-objdump -x '"$1"' |grep "NEEDED"'
white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld64\.so\.1"
fi
elif [[ "$OS" == osx ]]; then
dump_cmd='otool -L '"$1"' | fgrep dylib'
Expand Down