YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

GoにMakefile要らないです

はじめに

こんにちは、Go界の藤原釜足です。Goのリリース直後に結構Goに触れた方だと「Goは結局ビルドにMakefileが必要だからだるい」という印象が残っていて、いまもGoを敬遠される方もいるのではないでしょうか。
しかしgo buildが出てからそんなことはないですよ。

テストケース

ワークスペース

たとえばこんなワークスペースを用意します。

% mkgenv test-go-build
% echo $GOPATH
/Users/ymotongpoo/src/go/test-go-build
% tree $GOPATH
/Users/ymotongpoo/src/go/test-go-build
├── activate
└── src
    ├── foo
    │   └── foo.go
    ├── main.go
    └── spam
        └── egg
            └── ham
                └── ham.go

ちなみにワークスペースの作成には拙作のツールであるgenvを使いました。

ソースコード

上の各ファイルはどうなっているかというと

  • main.go
package main

import (
	"fmt"
	"foo"
)

func main() {
	fmt.Println("Call a function far away")
	foo.Hello()
}
  • foo/foo.go
package foo

import (
	ham "spam/egg/ham"
)

func Hello() {
	ham.Hello()
}
  • spam/egg/ham/ham.go
package ham

import (
	"fmt"
)

func Hello() {
	fmt.Println("Called from far away!!")
}
ビルド

go buildコマンドで$GOPATH以下のソースの依存関係を解決してビルドしてくれます。

% go build -o test
% ./test
Call a function far away
Called from far away!!

実際はどうなるのか

Goの場合、3rd partyライブラリを使う場合には、go getもしくはgo installコマンドでそのレポジトリを指定すると、$GOPATHのsrcディレクトリ、及びpkgディレクトリに、ソースないし静的ライブラリを置いてくれます。
つまり実際のワークスペースでは次のようになります。たとえばgobuchoパッケージをgo getして、main.goを作成した場合。

% tree $GOPATH
/Users/ymotongpoo/src/go/test-go-build
├── activate
├── pkg
│   └── darwin_amd64
│       └── github.com
│           └── ymotongpoo
│               └── gobucho.a
└── src
    ├── github.com
    │   └── ymotongpoo
    │       └── gobucho
    │           ├── README
    │           ├── bucho.go
    │           ├── data.go
    │           └── gobucho
    │               └── main.go
    └── main.go

ここでmain.goはこんなかんじです。

  • main.go
package main

import (
	"fmt"
	bucho "github.com/ymotongpoo/gobucho"
)

func main() {
	status, _ := bucho.LatestStatus()
	fmt.Println(status)
}

これをビルドして実行してみます。

% go build -o bucho
% ./bucho
エアコン消すのわすれた気がする...

もちろんちゃんと動きました。

おわりに

というわけで、Makefile書かなくても手軽にビルドができますよ、というお知らせでした。
ちなみにこれ書いてて気がついたんですが、複数の3rd partyパッケージを取ってくるのはめんどくさいですね。genvの次の追加機能としてpip freezeやpip install -rと同等の機能を追加しようと思います。