app: call main.main on app startup
There is some cleanup to be done in this package now, but I'm deferring it until later in the cycle. We should probably also change the semantics slightly: main should be called for all-Go apps (that is, apps that use NativeActivity), but it would be more consistent with buildmode=c-shared and c-archive if we did not call main for Go shared libraries being included in Java android apps. Change-Id: I13ca797a478edb22b0c602c1ee6e616fe4fea1e6 Reviewed-on: https://go-review.googlesource.com/9016 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
parent
47553f4d42
commit
d77bba0a9f
|
@ -19,9 +19,6 @@
|
|||
#define LOG_INFO(...) __android_log_print(ANDROID_LOG_INFO, "Go", __VA_ARGS__)
|
||||
#define LOG_FATAL(...) __android_log_print(ANDROID_LOG_FATAL, "Go", __VA_ARGS__)
|
||||
|
||||
// Defined in the Go runtime.
|
||||
static int (*_rt0_arm_linux1)(int argc, char** argv);
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
current_vm = vm;
|
||||
current_ctx = NULL;
|
||||
|
@ -122,32 +119,11 @@ static const char* getenv_raw(const char *name) {
|
|||
|
||||
static void* init_go_runtime(void* unused) {
|
||||
init_from_context();
|
||||
|
||||
_rt0_arm_linux1 = (int (*)(int, char**))dlsym(RTLD_DEFAULT, "_rt0_arm_linux1");
|
||||
if (_rt0_arm_linux1 == NULL) {
|
||||
LOG_FATAL("missing _rt0_arm_linux1");
|
||||
uintptr_t mainPC = (uintptr_t)dlsym(RTLD_DEFAULT, "main.main");
|
||||
if (!mainPC) {
|
||||
LOG_FATAL("missing main.main");
|
||||
}
|
||||
|
||||
// Defensively heap-allocate argv0, for setenv.
|
||||
char* argv0 = strdup("gojni");
|
||||
|
||||
// Build argv, including the ELF auxiliary vector.
|
||||
struct {
|
||||
char* argv[2];
|
||||
const char* envp[4];
|
||||
uint32_t auxv[64];
|
||||
} x;
|
||||
x.argv[0] = argv0;
|
||||
x.argv[1] = NULL;
|
||||
x.envp[0] = getenv_raw("TMPDIR=");
|
||||
x.envp[1] = getenv_raw("PATH=");
|
||||
x.envp[2] = getenv_raw("LD_LIBRARY_PATH=");
|
||||
x.envp[3] = NULL;
|
||||
|
||||
build_auxv(x.auxv, sizeof(x.auxv)/sizeof(uint32_t));
|
||||
int32_t argc = 1;
|
||||
_rt0_arm_linux1(argc, x.argv);
|
||||
return NULL;
|
||||
callMain(mainPC);
|
||||
}
|
||||
|
||||
static void wait_go_runtime() {
|
||||
|
|
|
@ -69,9 +69,20 @@ import (
|
|||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/mobile/app/internal/callfn"
|
||||
"golang.org/x/mobile/geom"
|
||||
)
|
||||
|
||||
//export callMain
|
||||
func callMain(mainPC uintptr) {
|
||||
for _, name := range []string{"TMPDIR", "PATH", "LD_LIBRARY_PATH"} {
|
||||
n := C.CString(name)
|
||||
os.Setenv(name, C.GoString(C.getenv(n)))
|
||||
C.free(unsafe.Pointer(n))
|
||||
}
|
||||
callfn.CallFn(mainPC)
|
||||
}
|
||||
|
||||
//export onCreate
|
||||
func onCreate(activity *C.ANativeActivity) {
|
||||
C.asset_manager = activity.assetManager
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// 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.
|
||||
|
||||
// +build android,arm
|
||||
|
||||
// Package callfn provides an android entry point.
|
||||
//
|
||||
// It is a separate package from app because it contains Go assembly,
|
||||
// which does not compile in a package using cgo.
|
||||
package callfn
|
||||
|
||||
// CallFn calls a zero-argument function by its program counter.
|
||||
// It is only intended for calling main.main. Using it for
|
||||
// anything else will not end well.
|
||||
func CallFn(fn uintptr)
|
|
@ -0,0 +1,11 @@
|
|||
// 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 "textflag.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
TEXT ·CallFn(SB),$0-4
|
||||
MOVW fn+0(FP), R0
|
||||
BL (R0)
|
||||
RET
|
Loading…
Reference in New Issue