🤖
Go でビルドしたファイルに実行権限が付与されない
原因
ビルド対象に main パッケージが存在しない。
解決策
パッケージ名が間違っている場合は main に変更する。
もしくは main パッケージを作成する。
状況
ここからは蛇足です。
go build コマンドでビルドした際のビルドファイルの状況を見ていきます。
main パッケージをビルド
まずは通常の main パッケージのビルドを見てみましょう。
app ディレクトリ配下に main.go を作成したとします。
// app/main.go
package main
import "fmt"
main() {
fmt.Println("hello")
}
このファイルを go build コマンドでビルドしてしましょう。
$ ls -l
drwxr-xr-x 3 root root 96 Sep 5 00:34 app
-rw-r--r-- 1 root root 57 Sep 4 23:30 go.mod
$ go build app/main.go
$ ls -l
drwxr-xr-x 3 root root 96 Sep 5 00:34 app
-rw-r--r-- 1 root root 57 Sep 4 23:30 go.mod
-rw-r--r-- 1 root root 1821419 Sep 5 00:38 main
カレントディレクトリ配下にビルド元ファイルと同じ名前で main ファイルが作成されていますね。
実行権限も付与されています。
良さそうですね。
main パッケージ以外をビルド
では次に main パッケージ以外のビルドを見てみます。
前章との差分はパッケージ名が app になっているのみです。
// app/main.go
package app
import "fmt"
main() {
fmt.Println("hello")
}
こちらをビルドしてみましょう。
$ ls -l
drwxr-xr-x 3 root root 96 Sep 5 00:34 app
-rw-r--r-- 1 root root 57 Sep 4 23:30 go.mod
$ go build app/main.go
$ ls -l
drwxr-xr-x 3 root root 96 Sep 5 00:34 app
-rw-r--r-- 1 root root 57 Sep 4 23:30 go.mod
なんと、ビルドファイルが作成されないんですね。
そもそも go では main パッケージがなければビルドされないようになっています。
main パッケージ以外を -o オプションでビルド
では次に、 -o オプションをつけて無理やりビルドファイルを作成してみます。
// app/main.go
package app
import "fmt"
main() {
fmt.Println("hello")
}
$ ls -l
drwxr-xr-x 3 root root 96 Sep 5 00:34 app
-rw-r--r-- 1 root root 57 Sep 4 23:30 go.mod
$ go build -o main app/main.go
$ ls -l
drwxr-xr-x 3 root root 96 Sep 5 00:34 app
-rw-r--r-- 1 root root 57 Sep 4 23:30 go.mod
-rw-r--r-- 1 root root 1821419 Sep 5 00:38 main
このパターンのときに、ビルドファイルは作成されるけど実行権限が付与されない、といった状況が発生するんですね。
main パッケージがないビルドファイルを無理やり実行
ここからはさらにお試しとして、前回作成した実行権限がないビルドファイルに、実行権限を付与して無理やり実行してみます。
$ ls -l
drwxr-xr-x 3 root root 96 Sep 5 00:40 app
-rw-r--r-- 1 root root 57 Sep 4 23:30 go.mod
-rw-r--r-- 1 root root 1821419 Sep 5 00:38 main
$ chmod +x main
$ go run main
package main is not in GOROOT (/usr/local/go/src/main)
実行はできますが、main パッケージがないよとエラーが出ていますね。
まとめ
自分はいきなり「main パッケージ以外を -o オプションでビルド」する状況に遭遇していしまったので、少々混乱しました。
どなたかの助けになれば幸いです。
Discussion