LoginSignup
7
5

More than 5 years have passed since last update.

Golang って Solaris でビルドできるのか調べてみた(気にすんなよ。くよくよすんなよ)

Posted at

Golang って Solaris ではどうなのか調べてみたの続きになります。
ブートストラップに利用する Go 1.4.2 を Solaris 11.3 でビルドし、Go 1.5.3 を手に入れることがゴールになります。
(Solaris x86 環境が対象です)

作業ディレクトリ

$HOME/go ディレクトリを作業などもろもろ利用するディレクトリとします。

$ mkdir $HOME/go
$ cd $HOME/go

ビルドの準備

必要なパッケージをインストール。

# pkg install developer/versioning/git developer/gnu-binutils \
    developer/build/gnu-make developer/gcc-48

ソースコードの入手

Go 1.4.3 と Go 1.5.2 を下記から入手し、$HOME/go ディレクトリに配置。

$ wget https://storage.googleapis.com/golang/go1.4.3.src.tar.gz
$ wget https://storage.googleapis.com/golang/go1.5.2.src.tar.gz

まずは Go 1.4.3 のビルド

アーカイブを展開し、go1.4.3 という名前に変更。

$ gtar xvzf go1.4.3.src.tar.gz
$ mv go go1.4.3
$ cd go1.4.3/src
$ PATH=/usr/gnu/bin:$PATH
$ export PATH

make.bash を実行

$ ./make.bash
# Building C bootstrap tool.
cmd/dist

# Building compilers and Go bootstrap tool for host, solaris/amd64.
lib9
libbio
liblink
:
testing/iotest
testing/quick
text/scanner


---
Installed Go for solaris/amd64 in /export/home/kazus/go/go1.4.3
Installed commands in /export/home/kazus/go/go1.4.3/bin

以上で、Go 1.4.3 のビルドは完了。

$ $HOME/go/go1.4.3/bin/go version
go version go1.4.3 solaris/amd64

このディレクトリをそのまま利用します。

Go 1.5.2 のビルド

Go 1.5 のビルドには、Go 1.4.3 が必要になるので、展開した Go 1.4.3 のディレクトリを $GOROOT_BOOTSTRAP に設定します。

$ GOROOT_BOOTSTRAP=$HOME/go/go1.4.3; export GOROOT_BOOTSTRAP

アーカイブを展開し、go1.5.2 という名前に変更。

$ gtar xvzf go1.5.2.src.tar.gz
$ mv go go1.5.2

go1.5.2/src に移動して make.bash を実行

$ cd go1.5.2/src
$ ./make.bash

##### Building Go bootstrap tool.
cmd/dist

##### Building Go toolchain using /export/home/kazus/go/go1.4.3.
bootstrap/internal/obj
bootstrap/asm/internal/flags
:
:
---
Installed Go for solaris/amd64 in /export/home/kazus/go/go1.5.2
Installed commands in /export/home/kazus/go/go1.5.2/bin

以上で、Go 1.5.2 のビルドは完了。

$ $HOME/go/go1.5.2/bin/go version
go version go1.5.2 solaris/amd64

GOPATH と GOROOT

ひとまず、出来上がった go1.5.2 の go コマンドに PATH を通しておきます。
これで、何も考えずに go コマンドを実行できるようになりました。

$ PATH=$HOME/go/go1.5.2/bin:$PATH; export PATH

続いて、ビルドした go コマンドが持っている環境変数を確認してみます。

$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="solaris"
GOOS="solaris"
GOPATH=""
GORACE=""
GOROOT="/export/home/kazus/go/go1.5.2"
GOTOOLDIR="/export/home/kazus/go/go1.5.2/pkg/tool/solaris_amd64"
GO15VENDOREXPERIMENT=""
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

$GOROOT が埋め込まれているをことを確認できるので、$GOPATH のみを設定します。
$GOPATH に指定されたディレクトリはワーキングディレクトリとして利用され、$GOPATH/src にパッケージ、pkg にビルドされたライブラリ、bin に実行可能バイナリなどが格納されます。
このあたりは、特にココ!という場所は無いようなのでお好きなようにって感じでしょうか。
自身で作成したパッケージなどの構成にも関わるので、じっくり調べてみるのも良いかと思います。

$ GOPATH=$HOME/go; export GOPATH

もう一度、go env を実行してみると、GOPATH に先ほど設定した $GOPATH の値が入っていることがわかります。

kazus@solaris:~/go$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="solaris"
GOOS="solaris"
GOPATH="/export/home/kazus/go"
GORACE=""
GOROOT="/export/home/kazus/go/go1.5.2"
GOTOOLDIR="/export/home/kazus/go/go1.5.2/pkg/tool/solaris_amd64"
GO15VENDOREXPERIMENT=""
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

Hello, World!

How to Write Go Code などを参考に Hello,World! を実行してみます。
ソースはコピペで。

package main

import "fmt"

func main() {
    fmt.Printf("Hello, world.\n")
}

go run で実行できます。
(一時的にワーキングディレクトリに実行可能ファイルを作成し、実行後は消去します。)

$ go run hello.go
hello, world

実行可能なバイナリを作成するには、go build を利用します。

$ go build hello.go
$ ls -al
total 2312
drwxr-xr-x  2 kazus staff       4 Jan 11 16:24 .
drwxr-xr-x 14 kazus staff      23 Jan 11 16:21 ..
-rwxr-xr-x  1 kazus staff 2349856 Jan 11 16:24 hello
-rw-r--r--  1 kazus staff      77 Jan 11 16:22 hello.go

$ ./hello
hello, world

go build 時に -x オプションをつけることで、何が行われているか詳細を知ることができます。

$ go build -x hello.go
WORK=/tmp/go-build595923179
mkdir -p $WORK/command-line-arguments/_obj/
mkdir -p $WORK/command-line-arguments/_obj/exe/
cd /export/home/kazus/go/test
/export/home/kazus/go/go1.5.2/pkg/tool/solaris_amd64/compile -o $WORK/command-line-arguments.a -trimpath $WORK -p main -complete -buildid f68da26c4308377ead5ac41ebd2a70f05db675c6 -D _/export/home/kazus/go/test -I $WORK -pack ./hello.go
cd .
/export/home/kazus/go/go1.5.2/pkg/tool/solaris_amd64/link -o $WORK/command-line-arguments/_obj/exe/a.out -L $WORK -extld=gcc -buildmode=exe -buildid=f68da26c4308377ead5ac41ebd2a70f05db675c6 $WORK/command-line-arguments.a
cp $WORK/command-line-arguments/_obj/exe/a.out hello

まとめ

以上で Go 1.5 の環境を手に入れることができました。
あとは、もう好きにやっちゃってください。

下記は、お時間あればどうぞ。

ポータビリティ問題?

platform 依存の low-level interactions を利用した実装が多く見られるので、ポータビリティが損なわれているんじゃないか問題を Solaris 観点で。
確かに、Terminal 系のプログラムで ioctl 使っているものに遭遇して乗り越えられないもの多数

何かインストールしてみよう

この記事を参考に ccat, pt, peco にチャレンジしてみた
* あるとちょっと便利なコマンドラインツール3つ

pt - The Platinum Searcher:

https://github.com/monochromegane/the_platinum_searcher
Go言語で作られたパターン検索ツール。

pt が依存している Terminal パッケージ が、Solaris に対応していないためインストールできず。
が、FreeBSD や Darwin (OS X) では CGO (Go から C の関数を呼び出すことができる)という仕組みを使ったものも提供されていたため、見よう見まねでごにょごにょしたら Solaris でも動くものが出来上がったので Pull Request してみた。
1.5 のリリースノートに書かれていた The Solaris port now has full support for cgo を覚えていたので、そこからたどってみた。
というわけで、今日から Solaris でも pt 使えます。

$ go get github.com/monochromegane/the_platinum_searcher/...
$ $GOPATH/bin/pt --help

ccat - ccat is the colorizing cat:

https://github.com/jingweno/ccat
syntax highlighting をサポートした cat コマンド

やってみる。

$ go get -u github.com/jingweno/ccat
# github.com/jingweno/ccat
jingweno/ccat/ccat.go:22: undefined: isatty.IsTerminal

ccat パッケージに含まれ、かつ depend している go-isatty パッケージが Solaris をサポートしていないため、undefined: isatty.IsTerminal でエラーとなる。
本家では Solaris をサポートしたパッケージを配布しているので、ccat.go を下記のように書き換える、もう一度、go get -u github.com/jingweno/ccat すればインストールできる。

diff --git a/ccat.go b/ccat.go
index eae8a8e..b4a67b7 100644
--- a/ccat.go
+++ b/ccat.go
@@ -7,7 +7,7 @@ import (
        "os"
        "syscall"

-       "github.com/jingweno/ccat/Godeps/_workspace/src/github.com/mattn/go-isatty"
+       "github.com/mattn/go-isatty"
 )

 type CCatPrinter interface {

もう一回

$ go get -fix -v -u github.com/jingweno/ccat
github.com/jingweno/ccat (download)
github.com/mattn/go-isatty (download)
Fetching https://golang.org/x/sys/unix?go-get=1
Parsing meta tags from https://golang.org/x/sys/unix?go-get=1 (status code 200)
get "golang.org/x/sys/unix": found meta tag main.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at https://golang.org/x/sys/unix?go-get=1
get "golang.org/x/sys/unix": verifying non-authoritative meta tag
Fetching https://golang.org/x/sys?go-get=1
Parsing meta tags from https://golang.org/x/sys?go-get=1 (status code 200)
golang.org/x/sys (download)
github.com/jingweno/ccat

ccat コマンドが $GOPATH/bin に作成されている。

$ ls $GOPATH/bin/ccat
/export/home/kazus/go/bin/ccat*

peco - Simplistic interactive filtering tool

これが、超絶便利そうだったのでインストールしてみたかったが Solaris をサポートしていない termbox への依存が激しくくじけました。
かわりに Python で実装された percol 置いときますね。

boom - HTTP(S) load generator, ApacheBench (ab) replacement, written in Go:

$ go get github.com/rakyll/boom

下記のエラーが出力されるので、pb/pb.go に patch を適用します。

# github.com/rakyll/pb
../src/github.com/rakyll/pb/pb.go:168: undefined: terminalWidth

パッチ:

$ git diff
diff --git a/pb_nix.go b/pb_nix.go
index 1f606aa..45bcfb0 100644
--- a/pb_nix.go
+++ b/pb_nix.go
@@ -1,4 +1,4 @@
-// +build linux darwin freebsd
+// +build linux darwin freebsd solaris

 package pb

もう、一回。
今度は undefined: syscall.SYS_IOCTL が出ました。
ちょっとこれを CGO 対応させるスキルがありません。

$ go get github.com/rakyll/boom
# github.com/rakyll/pb
./pb_nix.go:26: undefined: syscall.SYS_IOCTL

正しい手法ではないですが、go1.5.2 のソースを修正します。
書き換えたら go 1.5.2 のビルド手順と同じ make.bash を実行してください。

diff -cNr go/src/syscall/zsysnum_solaris_amd64.go go1.5.2/src/syscall/zsysnum_solaris_amd64.go
*** go/src/syscall/zsysnum_solaris_amd64.go     Thu Dec  3 09:53:02 2015
--- go1.5.2/src/syscall/zsysnum_solaris_amd64.go        Mon Jan 11 23:14:32 2016
***************
*** 8,13 ****
--- 8,14 ----

  // TODO(aram): remove these before Go 1.3.
  const (
+       SYS_IOCTL  = 54
        SYS_EXECVE = 59
        SYS_FCNTL  = 62
  )

修正を加えたビルドが完了したら、また go get を実行します。

$ go get github.com/rakyll/boom

これで、$GOROOT/bin に boom バイナリが作成されているはず。

動作しました。

$ $GOPATH/bin/boom -n 10000 -c 100 -m POST http://192.168.100.15:8080
10000 / 10000 Booooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo! 100.00 %

Summary:
  Total:        5.1659 secs.
  Slowest:      1.2772 secs.
  Fastest:      0.0025 secs.
  Average:      0.0428 secs.
  Requests/sec: 1935.7703
  Total Data Received:  12670000 bytes.
  Response Size per Request:    1267 bytes.

Status code distribution:
  [404] 10000 responses

Response time histogram:
  0.003 [1]     |
  0.130 [9902]  |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
  0.257 [18]    |
  0.385 [2]     |
  0.512 [0]     |
  0.640 [0]     |
  0.767 [0]     |
  0.895 [0]     |
  1.022 [0]     |
  1.150 [26]    |
  1.277 [51]    |

Latency distribution:
  10% in 0.0170 secs.
  25% in 0.0232 secs.
  50% in 0.0310 secs.
  75% in 0.0425 secs.
  90% in 0.0543 secs.
  95% in 0.0650 secs.
  99% in 0.1263 secs.

参考

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5