Golang って Solaris ではどうなのか調べてみた


Docker が Go で書かれているから。
来るべきその日に備えて。

[Installing Go from source](https://golang.org/doc/install/source) に記載されていますが、Go コンパイラのターゲット OS に Solaris は含まれています。  

> The compilers can target the DragonFly BSD, FreeBSD, Linux, NetBSD, OpenBSD, OS X (Darwin), Plan 9, `Solaris` and Windows operating systems.


# **リリースノートに垣間見る Solaris のサポート情報**

正式ではなく`experimental support` として、Go 1.3 から illumos Kernel や Solaris 11 がサポートされています。  

> **[Go 1.3 Release Notes](https://golang.org/doc/go1.3) (June 2014):**
> [Support for Solaris](https://golang.org/doc/go1.3#solaris)  
  * Go 1.3 now includes experimental support for Solaris on the amd64 (64-bit x86) architecture. It requires illumos, Solaris 11 or above.


> **[Go 1.4 Release Notes](https://golang.org/doc/go1.4) (December 2014):**  
  * 特に記載なし
> **[Go 1.5 Release Notes](<https://golang.org/doc/go1.5>) (August 2015):**  
  * The Solaris port now has full support for cgo and the packages net and crypto/x509, as well as a number of other fixes and improvements. 
  
特に言及されていないので、現在のリリース (Go 1.5)でも `experimental support` は継続中なのですかね  
[golang-dev](https://groups.google.com/forum/#!searchin/golang-dev/solaris%7Csort:date) で Solaris を話題にしている人がいないかちょっと調べてみました。

> * [gccgo backport of recent changes to mksysinfo.sh](https://groups.google.com/forum/#!searchin/golang-dev/solaris%7Csort:date/golang-dev/EtfGEK0zZDU/hH7PakddCwAJ)  
     `Solaris 12 specific;` とか書かれていたりします。
> * [Proposal for a dev.sparc64 branch for the solaris/sparc64 port](https://groups.google.com/forum/#!searchin/golang-dev/solaris/golang-dev/NRPm1ChhGAc/dQVN1vTw7MoJ)  
     solaris/sparc64 port for Go 1.6 のために dev.sparc64 branch を作成することについての提案

# **サポートされるインストラクション・セットは？**

[Installing Go from source](https://golang.org/doc/install/source)に記載がありますが、現時点では 5 つのインストラクションセット(CPU) をサポートしています。　　
Solaris という観点では、amd64 (x86-64) になりますね。  
SPARC へのポーティングは行われているようです。はやく dev.sparc64 branch できると良いですね。  


> The Go compilers support five instruction sets.   
  There are important differences in the quality of the compilers for the different architectures.  

* amd64 (also known as x86-64)  
A mature implementation. The compiler has an effective optimizer (registerizer) and generates good code (although gccgo can do noticeably better sometimes).
* 386 (x86 or x86-32)  
Comparable to the amd64 port.
* arm (ARM)  
Supports Linux, FreeBSD, NetBSD and Darwin binaries. Less widely used than the other ports.
* arm64 (AArch64)  
Supports Linux and Darwin binaries. New in 1.5 and not as well excercised as other ports.
* ppc64, ppc64le (64-bit PowerPC big- and little-endian)  
Supports Linux binaries. New in 1.5 and not as well excercised as other ports.


# **Go コンパイラ・ツールチェーンは、Go 言語で書かれている**  

> [Go 1.5 Bootstrap Plan](https://docs.google.com/document/d/1OaatvGhEAq7VseQ9kkavxKNAfepWy2yhPUBs96FGV28/edit?pref=2&pli=1)  
  Go 1.5 will use a toolchain written in Go (at least in part).  
  Question: how do you build Go if you need Go built already?  
  `Answer: building Go 1.5 will require having Go 1.4 available.`  


えっ。   
Go 1.5 から、Go コンパイラを手に入れるためには Go 1.4 が必須にするというプランに関するドキュメントです。  
“Goのソースツリーから，すべてのCプログラムを排除する方法”を検討していたそうです。  


>[Go 1.5のブートストラップ化を目指すGoogle](http://www.infoq.com/jp/news/2015/02/golang-15-bootstrapped)

そして、最新の　Go 1.5 は、このプランのとおり Go コンパイラが必要となりました。  

現在は、Go コンパイラに必要な toolchaine (ツールチェーン: プログラムを作成するために利用されるプログラムの集合体)として、`gc Go コンパイラと関連するツール群を利用する方法` と
`GCC バックエンドを利用した gccgo を利用する方法` の 2 つの方法が提供されている。  


> * gc Go コンパイラと関連するツール群を利用する方法  
    - [Installing Go from source](https://golang.org/doc/install/source)

> * GCC バックエンドを利用した gccgo  
    - [Setting up and using gccgo](https://golang.org/doc/install/gccgo)

Solaris で Go コンパイラを動かすもっとも簡単な方法としては、

  - まずは、Go コンパイラを必要としない Solaris をサポートした Go 1.4 をビルドする
  - できあがった Go コンパイラで Go 1.5 をビルドする

という流れになります。
そのため Solaris では、`gc Go コンパイラと関連するツール群を利用する方法` によるインストール手順を採用します。
ビルドは、次回 [Golang って Solaris でビルドできるのか調べてみた](http://qiita.com/satokaz/items/8e7874ab26623b0568ed) に続く・・・



# **おまけ**
[boltdb - Bolt is a pure Go key/value store](https://github.com/boltdb/bolt) が mmap を利用することに対応するパッチおよび[ユーザーの仮想メモリ領域が特定のパターンで使用されることをカーネルに通知し、メモリおよびスレッドの配置を最適化する madvice()](https://docs.oracle.com/cd/E57200_01/html/E58571/gpaci.html) をサポートするパッチを作成している人も。  

>- Issue: 
  - [ x/sys/unix: Solaris lacks Flock (plus related constants) #11113 ](https://github.com/golang/go/issues/11113)
  - Here is the complete patch for x/sys:   
     <http://www.bonsai.com/ken/public/xsys_solaris.patch>
  - Here is the complete patch for bolt:  
     <http://www.bonsai.com/ken/public/bolt_solaris.patch>

また、Solaris 上の Go コンパイラでは SYS_IOCTL が未定義のため syscall.Syscall(syscall.SYS_IOCTL,...) のようにシステムコールの直接呼び出しが書かれたコードはエラーになってしまうというのもあります。
上記の Issue に解決策が記載されていました。  

ただ、いろいろ調べているとこのような書き方はプラットフォームのポータビリティを無視しているという意見もあり、ちょっと脱線していますが色々と面白い話にも遭遇しました。
> [On Go, Portability, and System Interfaces](http://garrett.damore.org/2015/09/on-go-portability-and-system-interfaces.html)


# 参考情報
* [Go 1.5 on Solaris 11 x86](http://qiita.com/ryumei/items/e547b0f9a0f7463ea209)
* [Go言語の初心者が見ると幸せになれる場所](http://qiita.com/tenntenn/items/0e33a4959250d1a55045)
* <http://golang.jp>
* [Google Git: The Go Programming Language](https://go.googlesource.com/go)
* <https://golang.org>
* [The Go Project](https://golang.org/project/)