From: Hyang-Ah Hana Kim Date: Thu, 23 Apr 2015 21:27:38 +0000 (-0400) Subject: misc/cgo/testcshared: add a c-shared test for android/arm. X-Git-Tag: go1.5beta1~925 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8566979972d51236c37b2823d2c0d52c6efe5406;p=gostls13.git misc/cgo/testcshared: add a c-shared test for android/arm. - main3.c tests main.main is exported when compiled for GOOS=android. - wait longer for main2.c (it's slow on android/arm) - rearranged test.bash Fixes #10070. Change-Id: I6e5a98d1c5fae776afa54ecb5da633b59b269316 Reviewed-on: https://go-review.googlesource.com/9296 Reviewed-by: David Crawshaw Run-TryBot: Hyang-Ah Hana Kim --- diff --git a/misc/cgo/testcshared/main2.c b/misc/cgo/testcshared/main2.c index 24bc62e757..402338339f 100644 --- a/misc/cgo/testcshared/main2.c +++ b/misc/cgo/testcshared/main2.c @@ -21,7 +21,7 @@ int main(void) { // The descriptor will be initialized in a thread, so we have to // give a chance to get opened. - for (i = 0; i < 10; i++) { + for (i = 0; i < 100; i++) { n = read(fd, buf, sizeof buf); if (n >= 0) break; diff --git a/misc/cgo/testcshared/main3.c b/misc/cgo/testcshared/main3.c new file mode 100644 index 0000000000..49cc0558a0 --- /dev/null +++ b/misc/cgo/testcshared/main3.c @@ -0,0 +1,29 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include +#include + +// Tests "main.main" is exported on android/arm, +// which golang.org/x/mobile/app depends on. +int main(int argc, char** argv) { + void* handle = dlopen(argv[1], RTLD_LAZY | RTLD_GLOBAL); + if (!handle) { + fprintf(stderr, "ERROR: failed to open the shared library: %s\n", + dlerror()); + return 2; + } + + uintptr_t main_fn = (uintptr_t)dlsym(handle, "main.main"); + if (!main_fn) { + fprintf(stderr, "ERROR: missing main.main: %s\n", dlerror()); + return 2; + } + + // TODO(hyangah): check that main.main can run. + + printf("PASS\n"); + return 0; +} diff --git a/misc/cgo/testcshared/src/libgo/libgo.go b/misc/cgo/testcshared/src/libgo/libgo.go index facf1fbd25..8a4bf795e9 100644 --- a/misc/cgo/testcshared/src/libgo/libgo.go +++ b/misc/cgo/testcshared/src/libgo/libgo.go @@ -23,7 +23,6 @@ func init() { func main() { ranMain = true - panic("FAIL: main ran") } //export DidInitRun diff --git a/misc/cgo/testcshared/test.bash b/misc/cgo/testcshared/test.bash index 1c2e3c23f2..ef8229542d 100755 --- a/misc/cgo/testcshared/test.bash +++ b/misc/cgo/testcshared/test.bash @@ -3,37 +3,98 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. +# For testing Android, this script requires adb to push and run compiled +# binaries on a target device. + set -e +if [ ! -f src/libgo/libgo.go ]; then + cwd=$(pwd) + echo 'misc/cgo/testcshared/test.bash is running in $cwd' 1>&2 + exit 1 +fi + +goos=$(go env GOOS) + +# Temporary directory on the android device. +androidpath=/data/local/tmp/testcshared-$$ + function cleanup() { - rm -f libgo.so libgo2.so testp testp2 + rm -f libgo.so libgo2.so testp testp2 testp3 + + if [ "$(go env GOOS)" == "android" ]; then + adb shell rm -rf $androidpath + fi } trap cleanup EXIT +if [ "$goos" == "android" ]; then + adb shell mkdir -p "$androidpath" +fi + +function run() { + case "$goos" in + "android") + local args=$@ + for ((i=0; i < ${#args}; i++)); do + args[$i]=${args[$i]//.\//${androidpath}\/} + args[$i]=${args[$i]//=./=${androidpath}} + done + echo $(adb shell ${args} | tr -d '\r') + ;; + *) + echo $(env $@) + ;; + esac +} + +function binpush() { + bin=${1} + if [ "$goos" == "android" ]; then + adb push "$bin" "${androidpath}/${bin}" 2>/dev/null + fi +} + GOPATH=$(pwd) go build -buildmode=c-shared -o libgo.so src/libgo/libgo.go +binpush libgo.so +# test0: exported symbols in shared lib are accessible. $(go env CC) $(go env GOGCCFLAGS) -o testp main0.c libgo.so -output=$(LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./testp) -# testp prints PASS at the end of its execution. +binpush testp +output=$(run LD_LIBRARY_PATH=. ./testp) if [ "$output" != "PASS" ]; then - echo "FAIL: got $output" + echo "FAIL test0 got ${output}" exit 1 fi +# test1: .so can be dynamically loaded and exported symbols are accessible. $(go env CC) $(go env GOGCCFLAGS) -o testp main1.c -ldl -output=$(./testp ./libgo.so) -# testp prints PASS at the end of its execution. +binpush testp +output=$(run ./testp ./libgo.so) if [ "$output" != "PASS" ]; then - echo "FAIL: got $output" + echo "FAIL test1 got ${output}" exit 1 fi +# test2: tests libgo2.so which does not export any functions. GOPATH=$(pwd) go build -buildmode=c-shared -o libgo2.so src/libgo2/libgo2.go - +binpush libgo2.so $(go env CC) $(go env GOGCCFLAGS) -o testp2 main2.c -Wl,--no-as-needed libgo2.so -output=$(LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./testp2) -# testp2 prints PASS at the end of its execution. +binpush testp2 +output=$(run LD_LIBRARY_PATH=. ./testp2) if [ "$output" != "PASS" ]; then - echo "FAIL: got $output" + echo "FAIL test2 got ${output}" exit 1 fi + +# test3: tests main.main is exported on android. +if [ "$goos" == "android" ]; then + $(go env CC) $(go env GOGCCFLAGS) -o testp3 main3.c -ldl + binpush testp3 + output=$(run ./testp ./libgo.so) + if [ "$output" != "PASS" ]; then + echo "FAIL test3 got ${output}" + exit 1 + fi +fi +echo "ok" diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go index 0479fd50ec..112e40a0f3 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -383,26 +383,25 @@ func (t *tester) extLink() bool { } func (t *tester) buildmode(mode string) bool { + pair := t.goos + "-" + t.goarch switch mode { case "c-archive": - switch { - case !t.extLink(): + if !t.extLink() { return false - case t.goos == "darwin": - switch t.goarch { - case "amd64", "arm", "arm64": - return true - default: - return false - } - case t.goos == "linux" && (t.goarch == "amd64" || t.goarch == "386"): + } + switch pair { + case "darwin-amd64", "darwin-arm", "darwin-arm64", + "linux-amd64", "linux-386": return true - default: - return false } + return false case "c-shared": - // TODO(hyangah): add linux/386. - return t.goos == "linux" && t.goarch == "amd64" + // TODO(hyangah): add linux-386. + switch pair { + case "linux-amd64", "android-arm": + return true + } + return false default: log.Fatal("internal error: unknown buildmode %s", mode) return false