LoginSignup
1
0

More than 3 years have passed since last update.

Goをソースからインストールする

Last updated at Posted at 2020-05-10

Go勉強の手始めに、まずはソースからインストール。

環境

  • Fedora release 31

インストール手順

ソースからインストールする際の公式ドキュメントはこちら

ツールチェインの入手

GoのコンパイラツールチェインはGoで記述されており、ツールチェインをビルドするにはGoのコンパイラが必要になる。

Goのコンパイルを行うには、この最初のビルドを行うツールチェイン (ブートストラップツールチェイン) が必要になる。
ブートストラップツールチェインもソースからコンパイルすることができるが、今回はビルド済のバイナリを入手する。

(Goをコンパイルするためにコンパイル済みのバイナリを手に入れるという行為には矛盾を感じるが)
ダウンロードページからバイナリを入手して展開する。

$ tar -xvzf go1.14.2.linux-amd64.tar.gz
$ mv go go1.14

環境変数をセットする。Goのコンパイラはツールチェインをビルドするためのブートストラップツールチェインを$GOROOT_BOOTSTRAPから探す。

$ export GOROOT_BOOTSTRAP=/home/hidakanoko/Dev/go/go1.14

コンパイル

Goのソースコードを適当な位置にクローンする。

$ cd /home/hidakanoko/Dev/go/
$ git clone https://go.googlesource.com/go goroot

適当なバージョンをチェックアウトする。

$ cd goroot
$ git checkout go1.14.2

コンパイルを実行する。テストなども走るらしく、時間がかかる。

$ cd src
$ ./make.bash

環境変数を設定してgoコマンドが通るか確認。

$ export PATH="$PATH:/home/hidakanoko/Dev/go/goroot/bin"
$ export GOROOT="/home/hidakanoko/Dev/go/goroot"
$ go version
go version go1.14.2 linux/amd64

無事成功。

動作確認

Goのソースをコンパイルしてみる。

test.go
package main

import "fmt"

func main() {
    fmt.Println("hello, world")
}

go runでソースのコンパイルと実行。

$ go run ~/Dev/go/test/test.go 
hello, world

コマンドのヘルプはgo help runでみられる。

$ go help run
usage: go run [build flags] [-exec xprog] package [arguments...]

(...省略)

ソースを弄ってコンパイルしてみる

せっかくなのでGoのソースを弄ってみる。

fmt.Printlnは引数で与えられた文字列に改行を付与して標準出力に書き出す。
https://golang.org/pkg/fmt/#Println

Printlnは./src/fmt/print.goに定義されている。

$ find ./ -name "*.go" | xargs grep "func Println"
(...省略)
./src/fmt/print.go:func Println(a ...interface{}) (n int, err error) {
(...省略)

Printlnの定義は次のようになっている。

src/fmt/print.go
 273 func Println(a ...interface{}) (n int, err error) {
 274         return Fprintln(os.Stdout, a...)
 275 }

a ...interface{}はあらゆる引数を受け付ける可変長引数。可変長引数の実体はsliceらしい。
https://golang.org/ref/spec#Passing_arguments_to_..._parameters

標準出力os.Stdoutと受け取ったa...を引数にしてFprintlnを呼び出している。

ここに与えられた引数に草を生やす関数Printlnwを追加してみる。

src/fmt/print.go
 277 // Printlnw formats using the default formats for its opedands and writes to standard output with weed.
 278 func Printlnw(a ...interface{}) (n int, err error) {
 279         b := append(a, "www")
 280         return Fprintln(os.Stdout, b...)
 281 }

appendsliceにアイテムを追加して新しいsliceを生成する。
https://golang.org/pkg/builtin/#append

コンパイルしてみるとAPI Checkのあたりで失敗する。どうも公開する関数をapi/ディレクトリにバージョン毎に定義しているらしのだが、詳細はちょっと調べたがよくわからなかった。

$ ./all.bash

(...省略)

##### API check
Error running API checker: exit status 1
Go version is "go1.14.2", ignoring -next /home/hidakanoko/Dev/go/goroot/api/next.txt
+pkg fmt, func Printlnw(...interface{}) (int, error)
exit status 1
2020/05/10 11:18:02 Failed: exit status 1
go tool dist: FAILED

しょうがないのでmake.bashでビルドだけ実行。

$ ./make.bash
(...省略)
Building packages and commands for linux/amd64.
---
Installed Go for linux/amd64 in /home/hidakanoko/Dev/go/goroot
Installed commands in /home/hidakanoko/Dev/go/goroot/bin

ビルド成功したので、テストプログラムを修正して実行してみる。

test.go
package main

import "fmt"

func main() {
        fmt.Printlnw("hello, world")
}

コンパイルと実行。

$ go run ~/Dev/go/test/test.go 
hello, world www

成功!!
Goの実行環境をDockerなどで用意する際は、こっそり草生やすバージョンと差し替えてメンバーの心をほっこりさせようと思う(怒られる)

1
0
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
1
0