1#!/bin/bash 2 3# Check that the codegen artifacts are of correct architecture and don't have 4# unexpected dependencies. 5# To be run from Gradle. 6# Usage: check-artifact <OS> <ARCH> 7# <OS> and <ARCH> are ${os.detected.name} and ${os.detected.arch} from 8# osdetector-gradle-plugin 9OS=$1 10ARCH=$2 11 12if [[ $# < 2 ]]; then 13 echo "No arguments provided. This script is intended to be run from Gradle." 14 exit 1 15fi 16 17# Under Cygwin, bash doesn't have these in PATH when called from Gradle which 18# runs in Windows version of Java. 19export PATH="/bin:/usr/bin:$PATH" 20 21E_PARAM_ERR=98 22E_ASSERT_FAILED=99 23 24# Usage: fail ERROR_MSG 25fail() 26{ 27 echo "ERROR: $1" 28 echo 29 exit $E_ASSERT_FAILED 30} 31 32# Usage: assertEq VAL1 VAL2 $LINENO 33assertEq () 34{ 35 lineno=$3 36 if [ -z "$lineno" ]; then 37 echo "lineno not given" 38 exit $E_PARAM_ERR 39 fi 40 41 if [[ "$1" != "$2" ]]; then 42 echo "Assertion failed: \"$1\" == \"$2\"" 43 echo "File \"$0\", line $lineno" # Give name of file and line number. 44 exit $E_ASSERT_FAILED 45 fi 46} 47 48# Checks the artifact is for the expected architecture 49# Usage: checkArch <path-to-protoc> 50checkArch () 51{ 52 echo 53 echo "Checking format of $1" 54 if [[ "$OS" == windows || "$OS" == linux ]]; then 55 format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")" 56 echo Format=$format 57 if [[ "$OS" == linux ]]; then 58 if [[ "$ARCH" == x86_32 ]]; then 59 assertEq "$format" "elf32-i386" $LINENO 60 elif [[ "$ARCH" == x86_64 ]]; then 61 assertEq "$format" "elf64-x86-64" $LINENO 62 elif [[ "$ARCH" == aarch_64 ]]; then 63 assertEq "$format" "elf64-little" $LINENO 64 elif [[ "$ARCH" == loongarch_64 ]]; then 65 echo $format 66 assertEq "$format" "elf64-loongarch" $LINENO 67 elif [[ "$ARCH" == ppcle_64 ]]; then 68 format="$(powerpc64le-linux-gnu-objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")" 69 echo Format=$format 70 assertEq "$format" "elf64-powerpcle" $LINENO 71 elif [[ "$ARCH" == s390_64 ]]; then 72 format="$(s390x-linux-gnu-objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")" 73 echo Format=$format 74 assertEq "$format" "elf64-s390" $LINENO 75 else 76 fail "Unsupported arch: $ARCH" 77 fi 78 else 79 # $OS == windows 80 if [[ "$ARCH" == x86_32 ]]; then 81 assertEq "$format" "pei-i386" $LINENO 82 elif [[ "$ARCH" == x86_64 ]]; then 83 assertEq "$format" "pei-x86-64" $LINENO 84 else 85 fail "Unsupported arch: $ARCH" 86 fi 87 fi 88 elif [[ "$OS" == osx ]]; then 89 format="$(file -b "$1" | grep -o "[^ ]*$")" 90 echo Format=$format 91 if [[ "$ARCH" == x86_32 ]]; then 92 assertEq "$format" "i386" $LINENO 93 elif [[ "$ARCH" == x86_64 ]]; then 94 assertEq "$format" "x86_64" $LINENO 95 else 96 fail "Unsupported arch: $ARCH" 97 fi 98 else 99 fail "Unsupported system: $OS" 100 fi 101 echo 102} 103 104# Checks the dependencies of the artifact. Artifacts should only depend on 105# system libraries. 106# Usage: checkDependencies <path-to-protoc> 107checkDependencies () 108{ 109 echo "Checking dependencies of $1" 110 if [[ "$OS" == windows ]]; then 111 dump_cmd='objdump -x '"$1"' | fgrep "DLL Name"' 112 white_list="KERNEL32\.dll\|msvcrt\.dll\|USER32\.dll" 113 elif [[ "$OS" == linux ]]; then 114 dump_cmd='ldd '"$1" 115 if [[ "$ARCH" == x86_32 ]]; then 116 white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2" 117 elif [[ "$ARCH" == x86_64 ]]; then 118 white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2" 119 elif [[ "$ARCH" == aarch_64 ]]; then 120 dump_cmd='aarch64-linux-gnu-objdump -x '"$1"' |grep "NEEDED"' 121 white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-aarch64\.so\.1" 122 elif [[ "$ARCH" == loongarch_64 ]]; then 123 dump_cmd='objdump -x '"$1"' | grep NEEDED' 124 white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld\.so\.1" 125 elif [[ "$ARCH" == ppcle_64 ]]; then 126 dump_cmd='powerpc64le-linux-gnu-objdump -x '"$1"' |grep "NEEDED"' 127 white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld64\.so\.2" 128 elif [[ "$ARCH" == s390_64 ]]; then 129 dump_cmd='s390x-linux-gnu-objdump -x '"$1"' |grep "NEEDED"' 130 white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld64\.so\.1" 131 fi 132 elif [[ "$OS" == osx ]]; then 133 dump_cmd='otool -L '"$1"' | fgrep dylib' 134 white_list="libz\.1\.dylib\|libc++.1.dylib\|libstdc++\.6\.dylib\|libSystem\.B\.dylib" 135 fi 136 if [[ -z "$white_list" || -z "$dump_cmd" ]]; then 137 fail "Unsupported platform $OS-$ARCH." 138 fi 139 echo "Checking for expected dependencies ..." 140 eval $dump_cmd | grep -i "$white_list" || fail "doesn't show any expected dependencies" 141 echo "Checking for unexpected dependencies ..." 142 eval $dump_cmd | grep -i -v "$white_list" 143 ret=$? 144 if [[ $ret == 0 ]]; then 145 fail "found unexpected dependencies (listed above)." 146 elif [[ $ret != 1 ]]; then 147 fail "Error when checking dependencies." 148 fi # grep returns 1 when "not found", which is what we expect 149 echo "Dependencies look good." 150 echo 151} 152 153FILE="build/artifacts/java_plugin/protoc-gen-grpc-java.exe" 154checkArch "$FILE" && checkDependencies "$FILE" 155