概要
元ネタは以下。
上のページの内容は、mainパッケージのものを配置するために main ってディレクトリ作って
その中に、main パッケージのものを入れました。その後で、いつもどおりにトップディレクトリで
go build
ってやったら、
$ go build can't load package: package github.com/devlights/go-main-pkg-dir: unknown import path "github.com/devlights/go-main-pkg-dir": cannot find module providing package github.com/devlights/go-main-pkg-dir
ってエラー出てビルドできないんだけど何で?って内容です。
なんでメモ残そうかと思ったかというと、Go言語勉強し始めたときに自分でも、この状態になってしまったのでw
今でもたまに go build したときに、同じエラーメッセージ出たりしてます。。
Go言語では一つのディレクトリの中には一つのパッケージしか存在できない
Go言語、最初に勉強し始めたときに作るサンプルってだいたい以下のような形してると思います。
$ tree . ├── go.mod ├── lib.go └── main.go
パッケージ用のディレクトリなんて無しで、直下に main.go
置いているパターン。
main.go
、lib.go
ともに main パッケージに属している。
この場合
go build
って打つと、素直にビルド成功。
で、ちょっと言語の勉強しだすと以下のような言語仕様を見かける。
Goでは、一つのディレクトリの中に一つのパッケージしか存在できない
なるほどってなって、んじゃ main パッケージのものは main の下に入れようってなります(私はなりましたw
んで、構成がこうなる
$ tree . ├── go.mod └── main ├── lib.go └── main.go
この状態になって、さっきと同じようにトップディレクトリで go build
ってやると件のエラーが出ます。
今は理由もわかるんですが、勉強し始めの頃は意味が分かっていませんでした。
誤解の元は、go build
ってやると、再帰で実行したディレクトリから下も含めて全部見てくれていると思ってたせい。
だって、以下のような構成の場合
$ tree . ├── go.mod ├── main.go └── pkg └── lib └── lib.go
go build
って同じようにやっても、ちゃんとビルド出来るのですからw
サブパッケージ扱いの lib.go
は自動的にビルド対象に入る。
普段、dotnet とかやってるのもあって、エントリーポイントを持つファイルとかは勝手に探してくれると勘違いしてました.
上のサイトでもちゃんと説明してくださってます。
The reason is that Go packages must all be in the same folder. When you run go build from /root/folder/, go build looks for .go files in that folder to build a package. go build does not traverse the directory structure from the current directory and build subpackages.
ってことで、正しくはこうですね。
$ cd main
$ go build
それか、
$ go build -o xxx ./main
それか、パッケージ直指定
$ go build -o xxx name/of/package/main
そもそも main
ってディレクトリ掘って、配置しておくってのが、今考えるとあまりやらないですが。
(cmdディレクトリ掘って、下にアプリケーション名を掘って、その下に main.go 置くパターンが最近個人的に多いです)
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場