1 #!/usr/bin/env bash 2 # Copyright 2015 The Go Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style 4 # license that can be found in the LICENSE file. 5 6 # For testing Android, this script requires adb to push and run compiled 7 # binaries on a target device. 8 9 set -e 10 11 if [ ! -f src/libgo/libgo.go ]; then 12 cwd=$(pwd) 13 echo "misc/cgo/testcshared/test.bash is running in $cwd" 1>&2 14 exit 1 15 fi 16 17 goos=$(go env GOOS) 18 goarch=$(go env GOARCH) 19 goroot=$(go env GOROOT) 20 if [ ! -d "$goroot" ]; then 21 echo 'misc/cgo/testcshared/test.bash cannot find GOROOT' 1>&2 22 echo '$GOROOT:' "$GOROOT" 1>&2 23 echo 'go env GOROOT:' "$goroot" 1>&2 24 exit 1 25 fi 26 27 # Directory where cgo headers and outputs will be installed. 28 # The installation directory format varies depending on the platform. 29 installdir=pkg/${goos}_${goarch}_testcshared_shared 30 if [ "${goos}" == "darwin" ]; then 31 installdir=pkg/${goos}_${goarch}_testcshared 32 fi 33 34 # Temporary directory on the android device. 35 androidpath=/data/local/tmp/testcshared-$$ 36 37 function cleanup() { 38 rm -f libgo.$libext libgo2.$libext libgo4.$libext libgo5.$libext 39 rm -f libgo.h libgo4.h libgo5.h 40 rm -f testp testp2 testp3 testp4 testp5 41 rm -rf pkg "${goroot}/${installdir}" 42 43 if [ "$goos" == "android" ]; then 44 adb shell rm -rf "$androidpath" 45 fi 46 } 47 trap cleanup EXIT 48 49 if [ "$goos" == "android" ]; then 50 adb shell mkdir -p "$androidpath" 51 fi 52 53 function run() { 54 case "$goos" in 55 "android") 56 local args=$@ 57 output=$(adb shell "cd ${androidpath}; $@") 58 output=$(echo $output|tr -d '\r') 59 case $output in 60 *PASS) echo "PASS";; 61 *) echo "$output";; 62 esac 63 ;; 64 *) 65 echo $(env $@) 66 ;; 67 esac 68 } 69 70 function binpush() { 71 bin=${1} 72 if [ "$goos" == "android" ]; then 73 adb push "$bin" "${androidpath}/${bin}" 2>/dev/null 74 fi 75 } 76 77 rm -rf pkg 78 79 suffix="-installsuffix testcshared" 80 81 libext="so" 82 if [ "$goos" == "darwin" ]; then 83 libext="dylib" 84 fi 85 86 # Create the header files. 87 GOPATH=$(pwd) go install -buildmode=c-shared $suffix libgo 88 89 GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo.$libext src/libgo/libgo.go 90 binpush libgo.$libext 91 92 if [ "$goos" == "linux" ] || [ "$goos" == "android" ] ; then 93 if readelf -d libgo.$libext | grep TEXTREL >/dev/null; then 94 echo "libgo.$libext has TEXTREL set" 95 exit 1 96 fi 97 fi 98 99 GOGCCFLAGS=$(go env GOGCCFLAGS) 100 if [ "$goos" == "android" ]; then 101 GOGCCFLAGS="${GOGCCFLAGS} -pie" 102 fi 103 104 status=0 105 106 # test0: exported symbols in shared lib are accessible. 107 # TODO(iant): using _shared here shouldn't really be necessary. 108 $(go env CC) ${GOGCCFLAGS} -I ${installdir} -o testp main0.c ./libgo.$libext 109 binpush testp 110 111 output=$(run LD_LIBRARY_PATH=. ./testp) 112 if [ "$output" != "PASS" ]; then 113 echo "FAIL test0 got ${output}" 114 status=1 115 fi 116 117 # test1: shared library can be dynamically loaded and exported symbols are accessible. 118 $(go env CC) ${GOGCCFLAGS} -o testp main1.c -ldl 119 binpush testp 120 output=$(run ./testp ./libgo.$libext) 121 if [ "$output" != "PASS" ]; then 122 echo "FAIL test1 got ${output}" 123 status=1 124 fi 125 126 # test2: tests libgo2 which does not export any functions. 127 GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo2.$libext libgo2 128 binpush libgo2.$libext 129 linkflags="-Wl,--no-as-needed" 130 if [ "$goos" == "darwin" ]; then 131 linkflags="" 132 fi 133 $(go env CC) ${GOGCCFLAGS} -o testp2 main2.c $linkflags libgo2.$libext 134 binpush testp2 135 output=$(run LD_LIBRARY_PATH=. ./testp2) 136 if [ "$output" != "PASS" ]; then 137 echo "FAIL test2 got ${output}" 138 status=1 139 fi 140 141 # test3: tests main.main is exported on android. 142 if [ "$goos" == "android" ]; then 143 $(go env CC) ${GOGCCFLAGS} -o testp3 main3.c -ldl 144 binpush testp3 145 output=$(run ./testp ./libgo.so) 146 if [ "$output" != "PASS" ]; then 147 echo "FAIL test3 got ${output}" 148 status=1 149 fi 150 fi 151 152 # test4: tests signal handlers 153 GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo4.$libext libgo4 154 binpush libgo4.$libext 155 $(go env CC) ${GOGCCFLAGS} -pthread -o testp4 main4.c -ldl 156 binpush testp4 157 output=$(run ./testp4 ./libgo4.$libext 2>&1) 158 if test "$output" != "PASS"; then 159 echo "FAIL test4 got ${output}" 160 if test "$goos" != "android"; then 161 echo "re-running test4 in verbose mode" 162 ./testp4 ./libgo4.$libext verbose 163 fi 164 status=1 165 fi 166 167 # test5: tests signal handlers with os/signal.Notify 168 GOPATH=$(pwd) go build -buildmode=c-shared $suffix -o libgo5.$libext libgo5 169 binpush libgo5.$libext 170 $(go env CC) ${GOGCCFLAGS} -pthread -o testp5 main5.c -ldl 171 binpush testp5 172 output=$(run ./testp5 ./libgo5.$libext 2>&1) 173 if test "$output" != "PASS"; then 174 echo "FAIL test5 got ${output}" 175 if test "$goos" != "android"; then 176 echo "re-running test5 in verbose mode" 177 ./testp5 ./libgo5.$libext verbose 178 fi 179 status=1 180 fi 181 182 if test $status = 0; then 183 echo "ok" 184 fi 185 186 exit $status 187