Go moduleを使い始めたばかりでbuild
が通らず困った話
Hello Worldを終えて、少しすると、main.go
で定義していた関数を別のディレクトリに切り出したくなる時がくると思います。
その時にbuild
通らず、解決するのに時間がかかりました。
go module
を使わず、GOPATH
配下にプロジェクトのディレクトリを作る際と、goのmodules
を使う時で外部パッケージの呼び出し方のパスの指定方法に違いがあります。現状、Web上の情報も古い情報の方が多く、
結構、盲点であると思いましたので、覚書として残します。
$ go version
>> go version go1.13.4 darwin/amd64
何が困ったか?
piyo
├── go.mod
├── go.sum
└── main.go
package main
import "fmt"
main(){
hoge()
fuga()
return nil
}
func hoge() {
fmt.Println("hogehoge")
}
func fuga() {
fmt.Println("fugafuga")
}
上記のようなプロジェクトを下記のように、関数を別のディレクトリへ分割したい。
piyo
├── go.mod
├── go.sum
├── main.go
└── cmd
├── hoge.go
└── fuga.go
なので、次のようにファイルを分割した。
package main
import (
"fmt"
"./cmd"
)
main(){
cmd.hoge()
cmd.fuga()
return nil
}
package cmd
func Hoge() { // パッケージ外部から呼ばれるので関数名の先頭を大文字にする。
fmt.Println("hogehoge")
}
package cmd
func Fuga() { // パッケージ外部から呼ばれるので関数名の先頭を大文字にする。
fmt.Println("fugafuga")
}
ここで、build
するとエラーが出てbuild
出来ない!
$ go build
>> build _/Users/username/workspace_golang/github.com/username/piyo/cmd: cannot find module for path _/Users/username/workspace_golang/github.com/username/piyo/cmd
... cannot find module for path ...
という事は、piyo
ディレクトリを見つける事が出来ないという事っぽいけど。。。
結論からいうと、importするパッケージを相対パスでは無く、絶対パスでしてすればbuild
が通りました!
もう少し詳しく再現してみる。
Go modulesを使う
Goでは、modulesというものがgo 11.1
から使えるようになりました。
詳しい内容は、様々な記事や公式ドキュメントにありますが、今までと何が違うかというとGOPATH
の外にいても外部のパッケージを使えるという事であると思います。
必ずGOPATH
傘下にプロジェクトのディレクトリを作らなくてならないのは、不自由だなと思いますので、これはいいと取り入れて行きます。
$ mkdir workspace_golang
$ cd workspace_golang
$ mkdir piyo
$ cd piyo
$ go mod init github.com/username/piyo
このようにGOPATH
の外のhomeディレクトリ
直下にworkspace_golang
という勉強用ディレクトリを作成し、そこにプロジェクトのディレクリを作成しました。
buildが通ったmain.go
package main
import (
"fmt"
- "./cmd"
+ "github.com/username/piyo/cmd
)
main(){
cmd.hoge()
cmd.fuga()
return nil
}
結論
go moduleを使ったら外部パッケージから関数等を呼ぶときは絶対パスで呼ぶ!