Home | History | Annotate | Download | only in testcshared
      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