# 1.3 Goのコマンド ## Goのコマンド Go言語は完全なコマンド操作ツールセットを持つ言語です。コマンドラインで`go`を実行することでそれらを確認することができます: ![](images/1.1.mac.png?raw=true) 図1.3 Goコマンドで詳細情報を表示 これらのコマンドは我々が普段コードを書いている時に非常に役立つものです。次に普段使用するコマンドを理解していきましょう。 ## go build このコマンドは主にソースコードのコンパイルに用いられます。パッケージのコンパイル作業中、もし必要であれば、同時に関連パッケージもコンパイルすることができます。 - もし普通のパッケージであれば、我々が1.2章で書いた`mypath`パッケージのように、`go build`を実行したあと、何のファイルも生成しません。もし`$GOPATH/pkg`の下に対応するファイルを生成する必要があれば、`go install`を実行してください。 - もしそれが`main`パッケージであれば、`go build`を実行したあと、カレントディレクトリの下に実行可能ファイルが生成されます。もし`$GOPATH/bin`の下に対応するファイルを生成する必要があれば、`go install`を実行するか、`go build -o パス/a.exe`を実行してください。 - もしあるプロジェクトディレクトリに複数のファイルがある場合で、単一のファイルのみコンパイルしたい場合は、`go build`を実行する際にファイル名を追加することができます。例えば`go build a.go`です。`go build`コマンドはデフォルトでカレントディレクトリにある全てのgoファイルをコンパイルしようと試みます。 - コンパイル後に出力されるファイル名を指定することもできます。1.2章の`mathapp`アプリケーションでは`go build -o astaxie.exe`と指定できます。デフォルトはpackage名(mainパッケージではない)になるか、ソースファイルのファイル名(mainパッケージ)になります。 (注:実際はpackage名は[Go言語の規格](https://golang.org/ref/spec)においてコード中の"package"に続く名前になります。この名前はファイル名と異なっていても構いません。デフォルトで生成される実行可能ファイル名はディレクトリ名。 - go buildはディレクトリ内の"\_"または"."ではじまるgoファイルを無視します。 - もしあなたのソースコードが異なるオペレーティングシステムに対応する場合は異なる処理が必要となります。ですので異なるオペレーティングシステムの名称にもとづいてファイルを命名することができます。例えば配列を読み込むプログラムがあったとして、異なるオペレーティングシステムに対して以下のようなソースファイルがあるかもしれません。 array_linux.go array_darwin.go array_windows.go array_freebsd.go `go build`の際、システム名の末尾のファイルから選択的にコンパイルすることができます(Linux、Darwin、Windows、Freebsd) 引数の紹介 - `-o` 出力するファイル名を指定します。パスが含まれていても構いません。例えば `go build -o a/b/c` - `-i` パッケージをインストールします。コンパイル+`go install` - `-a` すでに最新であるパッケージを全て更新します。ただし標準パッケージには適用されません。 - `-n` 実行が必要なコンパイルコマンドを出力します。ただし、実行はされません。これにより低レイヤーで一体何が実行されているのかを簡単に知る事ができます。 - `-p n` マルチプロセスで実行可能なコンパイル数を指定します。デフォルトはCPU数です。 - `-race` コンパイルを行う際にレースコンディションの自動検出を行います。64bitマシンでのみ対応しています。 - `-v` 現在コンパイル中のパッケージ名を出力します。 - `-work` コンパイル時の一時ディレクトリ名を出力し、すでに存在する場合は削除しなくなります。 - `-x` 実行しているコマンドを出力します。`-n`の結果とよく似ていますが、この場合は実行します。 - `-ccflags 'arg list'` オプションを5c, 6c, 8cに渡してコールします。 - `-compiler name` コンパイラを指定します。gccgoか、またはgcです。 - `-gccgoflags 'arg list'` オプションをgccgoリンカに渡してコールします。 - `-gcflags 'arg list'` オプションを5g, 6g, 8gに渡してコールします - `-installsuffix suffix` デフォルトのインストールパッケージと区別するため、このサフィックスを利用して依存するパッケージをインストールします。`-race`をオプションに指定した場合はデフォルトで`-installsuffix race`が有効になっています。`-n`コマンドで確かめることができますよ。 - `-ldflags 'flag list'` オプションを5l, 6l, 8lに渡してコールします。 - `-tags 'tag list'` コンパイル時にこれらのtagをつけることができます。tagの詳細な制限事項に関しては [Build Constraints](http://golang.org/pkg/go/build/) を参考にして下さい。 ## go clean このコマンドは現在のソースコードパッケージと関連するソースパッケージのなかでコンパイラが生成したファイルを取り除く操作を行います。これらのファイルはすなわち: _obj/ 旧objectディレクトリ、MakeFilesが作成する。 _test/ 旧testディレクトリ,Makefilesが作成する。 _testmain.go 旧gotestファイル,Makefilesが作成する。 test.out 旧testログ,Makefilesが作成する。 build.out 旧testログ,Makefilesが作成する。 *.[568ao] objectファイル,Makefilesが作成する。 DIR(.exe) go buildが作成する。 DIR.test(.exe) go test -cが作成する。 MAINFILE(.exe) go build MAINFILE.goが作成する。 *.so SWIG によって生成される。 私は基本的にこのコマンドを使ってコンパイルファイルを掃除します。ローカルでテストを行う場合これらのコンパイルファイルはシステムと関係があるだけで、コードの管理には必要ありません。 $ go clean -i -n cd /Users/astaxie/develop/gopath/src/mathapp rm -f mathapp mathapp.exe mathapp.test mathapp.test.exe app app.exe rm -f /Users/astaxie/develop/gopath/bin/mathapp 引数紹介 - `-i` go installがインストールするファイル等の、関係するインストールパッケージと実行可能ファイルを取り除きます。 - `-n` 実行する必要のある削除コマンドを出力します。ただし実行はされません。これにより低レイヤで何が実行されているのかを簡単に知ることができます。 - `-r` importによってインポートされたパッケージを再帰的に削除します。 - `-x` 実行される詳細なコマンドを出力します。`-n`出力の実行版です。 ## go fmt 読者にC/C++の経験があればご存知かもしれませんが、コードにK&Rスタイルを選択するかANSIスタイルを選択するかは常に論争となっていました。goでは、コードに標準のスタイルがあります。すでに培われた習慣やその他が原因となって我々は常にANSIスタイルまたはその他のより自分にあったスタイルでコードを書いて来ました。これは他の人がコードを閲覧する際に不必要な負担を与えます。そのためgoはコードのスタイルを強制し(例えば左大括弧はかならず行末に置く)、このスタイルに従わなければコンパイルが通りません。整形の時間の節約するため、goツールは`go fmt`コマンドを提供しています。これはあなたの書いたコードを整形するのに役立ちます。あなたの書いたコードは標準のスタイルに修正されますが、我々は普段このコマンドを使いません。なぜなら開発ツールには一般的に保存時に自動的に整形を行ってくれるからです。この機能は実際には低レイヤでは`go fmt`を呼んでいます。この次の章で2つのツールをご紹介しましょう。この2つのツールはどれもファイルを保存する際に`go fmt`機能を自動化させます。 go fmtコマンドを使うにあたって実際にはgofmtがコールされますが、-wオプションが必要になります。さもなければ、整形結果はファイルに書き込まれません。gofmt -w -l src、ですべての項目を整形することができます。 go fmtはgofmtの上位レイヤーのパッケージされたコマンドです。より個人的なフォーマットスタイルが欲しい場合は [gofmt](http://golang.org/cmd/gofmt/) を参考にしてください。 gofmtの引数紹介 - `-l` フォーマットする必要のあるファイルを表示します。 - `-w` 修正された内容を標準出力に書き出すのではなく、直接そのままファイルに書き込みます。 - `-r` “a[b:len(a)] -> a[b:]”のような重複したルールを追加します。大量に変換を行う際に便利です。 - `-s` ファイルのソースコードを簡素化します。 - `-d` ファイルに書き込まず、フォーマット前後のdiffを表示します。デフォルトはfalseです。 - `-e` 全ての文法エラーを標準出力に書き出します。もしこのラベルを使わなかった場合は異なる10行のエラーまでしか表示しません。 - `-cpuprofile` テストモードをサポートします。対応するするcpufile指定のファイルに書き出します。 ## go get このコマンドは動的にリモートコードパッケージを取得するために用いられます。現在BitBucket、GitHub、Google CodeとLaunchpadをサポートしています。このコマンドは内部で実際には2ステップの操作に分かれます:第1ステップはソースコードパッケージのダウンロード、第2ステップは`go install`の実行です。ソースコードパッケージのダウンロードを行うgoツールは異なるドメインにしたがって自動的に異なるコードツールを用います。対応関係は以下の通りです: BitBucket (Mercurial Git) GitHub (Git) Google Code Project Hosting (Git, Mercurial, Subversion) Launchpad (Bazaar) そのため、`go get`を正常に動作させるためには、あらかじめ適切なソースコード管理ツールがインストールされていると同時にこれらのコマンドがあなたのPATHに入っていなければなりません。実は`go get`はカスタムドメインの機能をサポートしています。具体的な内容は`go help remote`を参照ください。 引数紹介: - `-d` ダウンロードするだけでインストールしません。 - `-f` `-u`オプションを与えた時だけ有効になります。`-u`オプションはimportの中の各パッケージが既に取得されているかを検証しなくなります。ローカルにforkしたパッケージに対して特に便利です。 - `-fix` ソースコードをダウンロードするとまずfixを実行してから他の事を行うようになります。 - `-t` テストを実行する為に必要となるパッケージも同時にダウンロードします。 - `-u` パッケージとその依存パッケージをネットワークから強制的に更新します。 - `-v` 実行しているコマンドを表示します。 ## go install このコマンドは実際には内部で2ステップの操作に分かれます。第1ステップはリザルトファイルの生成(実行可能ファイルまたはaパッケージ)、第2ステップはコンパイルし終わった結果を`$GOPATH/pkg`または`$GOPATH/bin`に移動する操作です。 引数は`go build`のコンパイルオプションをサポートしています。みなさんは`-v`オプションだけ覚えていただければ結構です。これにより低レイヤーの実行状況をいつでも確認することができます。 ## go test このコマンドを実行すると、ソースコードディレクトリ以下の`*_test.go`ファイルが自動的にロードされ、テスト用の実行可能ファイルが生成/実行されます。出力される情報は以下のようなものになります ok archive/tar 0.011s FAIL archive/zip 0.022s ok compress/gzip 0.033s ... デフォルトの状態で、オプションを追加する必要はありません。自動的にあなたのソースコードパッケージ以下のすべてのtestファイルがテストされます。もちろんオプションを追加しても構いません。詳細は`go help testflag`を確認してください。 ここでは良く使われるオプションについてご紹介します: - `-bench regexp` 指定したbenchmarksを実行します。例えば `-bench=.` - `-cover` テストカバー率を起動します。 - `-run regexp` regexpにマッチする関数だけを実行します。例えば `-run=Array` とすることで名前がArrayから始まる関数だけを実行します。 - `-v` テストの詳細なコマンドを表示します。 ## go tool `go tool`にはいくつものコマンドがあります。ここでは2つだけご紹介します。fixと vetです。 - `go tool fix .` は以前の古いバージョンを新しいバージョンに修復します。例えば、go1以前の古いバージョンのコードをgo1に焼き直したり、APIを変化させるといったことです。 - `go tool vet directory|files` はカレントディレクトリのコードが正しいコードであるか分析するために使用されます。例えばfmt.Printfをコールする際のオプションが正しくなかったり、関数の途中でreturnされたことによって到達不可能なコードが残っていないかといった事です。 ## go generate このコマンドはGo1.4になって初めてデザインされました。コンパイル前にある種のコードを自動で生成する目的に使用されます。`go generate`と`go build`は全く異なるコマンドです。ソースコード中の特殊なコメントをを分析することで、対応するコマンドを実行します。これらのコマンドは明確に何の依存も存在しません。この機能を使用する場合には必ず次の事を念頭に置いてください。`go generate`はあなたの為に存在します。あなたのパッケージを使用する誰かの為のものではありません。これはある一定のコードを生成するためにあります。 簡単な例をご紹介します。例えば我々が度々`yacc`を使ってコードを生成していたとしましょう。その場合以下のようなコマンドをいつも使用することになります: go tool yacc -o gopher.go -p parser gopher.y -o は出力するファイル名を指定します。-pはパッケージ名を指定します。これは単独のコマンドであり、もし`go generate`によってこのコマンドを実行する場合は当然ディレクトリの任意の`xxx.go`ファイルの任意の位置に以下のコメントを一行追加します。 //go:generate go tool yacc -o gopher.go -p parser gopher.y 注意すべきは、`//go:generate`に空白が含まれていない点です。これは固定のフォーマットで、ソースファイルを舐める時はこのフォーマットに従って判断されます。 これにより以下のようなコマンドによって、生成・コンパイル・テストを行うことができます。もし`gopher.y`ファイルに修正が発生した場合は、再度`go generate`を実行することでファイルを上書きすればよいことになります。 $ go generate $ go build $ go test ## godoc Go1.2バージョンより以前は`go doc`コマンドがサポートされていましたが、今後は全てgodocコマンドに移されました。このようにインストールします`go get golang.org/x/tools/cmd/godoc` 多くの人がgoにはサードパーティのドキュメントが必要無いと謳っています。なぜなら例えばchmハンドブックのように(もっとも私はすでに[chmマニュアル](https://github.com/astaxie/godoc)を作っていますが)、この中にはとても強力なドキュメントツールが含まれているからです。 どのように対応するpackageのドキュメントを確認すればよいでしょうか? 例えばbuiltinパッケージであれば、`go doc builtin`と実行します。 もしhttpパッケージであれば、`go doc net/http`と実行してください。 パッケージの中の関数を確認する場合は`godoc fmt Printf`としてください。 対応するコードを確認する場合は、`godoc -src fmt Printf`とします。 コマンドラインでコマンドを実行します。 godoc -http=:ポート番号 例えば`godoc -http=:8080`として、ブラウザで`127.0.0.1:8080`を開くと、golang.orgのローカルのcopy版を見ることができます。これを通してpkgドキュメントなどの他の内容を確認することができます。もしあなたがGOPATHを設定されていれば、pkgカテゴリの中で、標準パッケージのドキュメントのみならず、ローカルの`GOPATH`のすべての項目に関連するドキュメントをリストアップすることができます。これはグレートファイアーウォールの中にいるユーザにとっては非常にありがたい選択です。 ## その他のコマンド goは他にも様々なツールを提供しています。例えば以下のツール go version はgoの現在のバージョンを確認します。 go env は現在のgoの環境変数を確認します。 go list は現在インストールされている全てのpackageをリストアップします。 go run はGoプログラムのコンパイルと実行を行います。 これらのツールはまだ多くのオプションがあり、ひとつひとつはご紹介しませんが、ユーザは`go help コマンド`で更に詳しいヘルプ情報を取得することができます。 ## links * [目次]() * 前へ: [GOPATHとワーキングディレクトリ](<01.2.md>) * 次へ: [Goの開発ツール](<01.4.md>)