2019/11/17

[golang]久々のgolang (4) - 実行ファイル名

こういう構成でビルドした。
main()はmain.goにある。

image

$ cd $GOPATH/src/main
$ go mod init
$ go build
$ ls
ex.go  go.mod  go.sum  main  main.go

実行ファイル名がmainなのはいただけないな、とディレクトリ名を変更した。

$ rm main
$ cd ..
$ mv main gogoex

image

$ go build
$ ls
ex.go  go.mod  go.sum  main  main.go

あれ、mainのままになっているのはなぜだ?
実行ファイル名はmain()を含んでいるファイルのディレクトリ名になると思っていたのだが。

 

go.modの1行目を見ると、こうなっていた。

module main

これを、変更した。

module gogoex

そしてビルド。

$ rm main
$ go build
$ ls
ex.go  gogoex  go.mod  go.sum  main.go

ディレクトリ名よりもgo.modの方が強いのか!
というよりも、実行ファイル名の決定にgo.modが使われるのか。

 

Go Modulesの説明が長いので、理由を探す気力が湧かなかった。
go getなどで更新されるわけでもないので、わざとそうしているのだろうか?
やらかしそうな気がするので、注意しておこう。

ただ、単にモジュール名として使われるだけなら便利かもしれん。
ディレクトリはmain()が入っているのでmain/にしたい、とか。


と、単純に考えてディレクトリ構成を変更していたのだが、ビルドができなくなった。
直下にはgoファイルを置かず、中でディレクトリを作って分けたいのだが。。。

image

~/Golang/go/src/example$ go build
can't load package: package example: no Go files in /home/xxx/Golang/go/src/example

まあ、ないよね。

 

$ go build ./*

これだとエラーは出ずに終わるのだが、実行ファイルが生成されていないようだ。

 

$ go build ./main/main.go
$ ./main/command-line-arguments
I am masao.

なぜか"command-line-arguments"という実行ファイル名ができる。
そして実行できてしまう。

$ go build -o mmm ./main/main.go
$ ls
ex  main  mmm

gccと同じように-oは使えるようだ。

もしや、go.modの"module"はここで使われるものなのでは?

$ go mod init
$ vi go.mod
(適当にmoduleの名前を変更)
$ go build ./main/main.go
build command-line-arguments: cannot load example/ex: malformed module path "example/ex": missing dot in first path element

moduleの名前を変更しないと、main/command-line-argumentsができるが、変更するとエラーになる。

 

どこかで...という形式を使うのを見たことがある。

$ go install -v ./...
$ ls $GOPATH/bin
main

もしかしたらmain/go.modを置くといいのでは?とやってみたのだが、変わらん。
そもそも、./...とか関係あるのかどうかわからんし。

 

んー、適当じゃダメだな。


go build

https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies

-oはいいとして、ビルド対象の指定方法を知りたいのだ。
[packages]と書いてあるが、.goファイルのリストでもよいらしい。
-vするとコンパイルしたパッケージの名前が表示されるらしい。

$ go build -v ./main/
go build: build output "main" already exists and is a directory

なるほど、ディレクトリと同じ名前になるから生成できなかったというわけか。
golang-standards/project-layoutというものを見てみると、cmd/の中にアプリ名のディレクトリを作るというのが定番らしい。逆らう理由もないのでそうしてみよう。

image

$ go build -v cmd/gogoex/main.go
$ ls
cmd  ex  main

むう、まだディレクトリ名になってくれないのか・・・。

When compiling a single main package, build writes the resulting executable to an output file named after the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe') or the source code directory ('go build unix/sam' writes 'sam' or 'sam.exe').

実行ファイル名は、goのファイル名からとるときとディレクトリ名から取るときがあるのか。

$ go build -v ./cmd/gogoex
example/cmd/gogoex
$ ls
cmd  ex  gogoex

なるほど、これでいいんだ。
最初の./を省略するとフルのパッケージ名として解釈しようとするので、相対パスの要領で"cmd/gogoex"とするとエラーになる。
ここなら、example/cmd/gogoex、と指定すれば良い。

 

go install

https://golang.org/cmd/go/#hdr-Compile_and_install_packages_and_dependencies

go buildは実行ファイルをその場に置いておくが、go buildは$GOPATH/bin/に移動させるようだ。

 

go clean

https://golang.org/cmd/go/#hdr-Remove_object_files_and_cached_files

cleanがよくわからん。
前回などは"go build"としてビルドしていて、それは"go clean"で実行ファイルが削除できていた。
でも、今回のようにパッケージ名を指定すると、どこのファイルも消してくれたように見えない。
"from package source directories"とあるから、$GOPATH/pkg/の方を消すのかな?
この程度のサンプルだとよくわからんな。


まあ、実行ファイル名関係についてはこのくらいでよかろう。
Makefileを使う場合もあるらしいし、また調べることになるだろう。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。