Androidアプリを作るのは難しそうだったのでjavascript化して何かに使えないか模索してみます。バイナリ化してexecするより汎用性は上がるはず。
Windowsだけでやりたかったけど、無理だったのでUbuntuで実行します。
Windowsでのgopherjs
windows10で実行してみるとこうなりました。
1 2 3 4 |
> go get github.com/gopherjs/gopherjs > gopherjs build routen.go [31m/src/syscall/syscall_nonlinux.go:5:18: undeclared name: SYS_EXIT [39m[31m/src/syscall/syscall.go:53:39: too few arguments in call to Syscall |
linuxでGOの導入からやります。
初期設定
仮想環境を利用して64bitのUbuntuを使いました。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ sudo apt update $ sudo apt upgrade //go getに必要 $ sudo apt install git //GO本体 $ sudo apt install golang-go //=>go version go1.10.4 linux/amd64 $ go get github.com/gopherjs/gopherjs # github.com/gopherjs/gopherjs/compiler src/github.com/gopherjs/gopherjs/compiler/compiler.go:20:9: undefined: ___GOPHERJS_REQUIRES_GO_VERSION_1_11___ |
GOを普通に入れるとバージョンが古いと怒られました。
リポジトリを追加して1.11を入れます。
1 2 3 4 5 |
$ sudo add-apt-repository ppa:gophers/archive $ sudo apt update $ sudo apt install golang-1.11-go $ go version go version go1.10.4 linux/amd64 //変わらない |
installやupgradeなどをしてもうまくいかないので1から設定しなおします。
1 2 3 4 5 6 7 |
$ sudo apt remove golang-go $ sudo apt remove golang-1.11-go $ sudo apt autoremove $ sudo apt install golang-1.11-go $ sudo ln -s /usr/lib/go-1.11/bin/go /usr/bin/go $ go version go version go1.11.5 linux/amd64 |
更新後はgopherjsのgetもうまくいきました。
getしたプログラムはデフォルトだと動かないのでパスを追加します。
1 |
$ export PATH="$PATH:$HOME/go/bin" |
exportはログインごとに消えるので.bashrc
にGOPATH
と一緒に追記しておきます。
1 2 3 |
# set my env export PATH="$PATH:$HOME/go/bin" export GOPATH="$HOME/go" |
変換テスト
gopherjs run
のためにnode.jsをインストールしておきます。
1 |
$ sudo apt install npm nodejs |
適当なテストプログラムを書いてみてどうなるか見てみる。
1 2 3 4 5 6 7 8 9 |
package main import "fmt" func sub(){ fmt.Println("sub") } func main(){ fmt.Println("main") sub() } |
gopherjsはgoと同じように使えます。
1 2 3 4 5 6 |
$ gopherjs run tes.go gopherjs: Source maps disabled. Install source-map-support module for nice stack traces. See https://github.com/gopherjs/gopherjs#gopherjs-run-gopherjs-test. main sub $ gopherjs build tes.go // => tes.jsとtes.js.mapが作られます |
2万行近いスクリプト(1MB)が出来てちょっと驚きました。
多分この辺がコア部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
sub = function() { var _r, $s, $r; /* */ $s = 0; var $f, $c = false; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; _r = $f._r; $s = $f.$s; $r = $f.$r; } s: while (true) { switch ($s) { case 0: _r = fmt.Println(new sliceType([new $String("sub")])); /* */ $s = 1; case 1: if($c) { $c = false; _r = _r.$blk(); } if (_r && _r.$blk !== undefined) { break s; } _r; $s = -1; return; /* */ } return; } if ($f === undefined) { $f = { $blk: sub }; } $f._r = _r; $f.$s = $s; $f.$r = $r; return $f; }; main = function() { var _r, $s, $r; /* */ $s = 0; var $f, $c = false; if (this !== undefined && this.$blk !== undefined) { $f = this; $c = true; _r = $f._r; $s = $f.$s; $r = $f.$r; } s: while (true) { switch ($s) { case 0: _r = fmt.Println(new sliceType([new $String("main")])); /* */ $s = 1; case 1: if($c) { $c = false; _r = _r.$blk(); } if (_r && _r.$blk !== undefined) { break s; } _r; $r = sub(); /* */ $s = 2; case 2: if($c) { $c = false; $r = $r.$blk(); } if ($r && $r.$blk !== undefined) { break s; } $s = -1; return; /* */ } return; } if ($f === undefined) { $f = { $blk: main }; } $f._r = _r; $f.$s = $s; $f.$r = $r; return $f; }; |
さっぱりわからん。
次に画像処理で使ったものを走らせてみました。
1 2 3 |
warning: system calls not available, see https://github.com/gopherjs/gopherjs/blob/master/doc/syscalls.md error:file open test.jpg: permission denied |
os.Open()
部分でエラーが起きるのでsyscall
をつくりなおします。
1 2 3 4 5 |
cd $GOPATH/src/github.com/gopherjs/gopherjs/node-syscall/ npm install --global node-gyp node-gyp rebuild mkdir -p ~/.node_libraries/ cp build/Release/syscall.node ~/.node_libraries/syscall.node |
これでファイル入出力もできました。
javascriptから呼び出す
サンプルをちょっと弄ったgoファイルと、それを使うjsファイルを作ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package main import "github.com/gopherjs/gopherjs/js" func main() { js.Global.Set("getStr",GetStr) js.Global.Set("pet", map[string]interface{}{ "New": New, }) } func GetStr()(string){ return "string from GO" } type Pet struct { name string } func New(name string) *js.Object { return js.MakeWrapper(&Pet{name}) } func (p *Pet) Name() string { return p.name } func (p *Pet) SetName(name string) { p.name = name } |
1 2 3 4 |
const jsjs = require("./js.js"); console.log("use"); console.log(pet.New("NEKO").Name()); console.log(getStr()); |
実行するとGOで定義した構造体と関数を使えました。
1 2 3 4 5 |
$ gopherjs build js.go $ node jsuse.js use NEKO string from GO |
Node.jsで使うことを想定しているようなので用途は限定的ですが、何かに使えるかもしれないので覚えておきます。