理由あってGo言語を使うことになったので勉強中。
環境構築
とりあえずWSL2上でGo言語開発環境を作成する。
インストール
$ sudo apt update
$ sudo apt upgrade -y
$ sudo apt install -y golang-go
インストール後確認
$ go version
go version go1.18.1 linux/amd64
$ go env GOROOT
/usr/lib/go-1.18
$ go env GOBIN
(出力なし)
GOBINはデフォルトで$GOROOT/binになるらしい。個人環境なので今回は未設定にする。Buildサーバなど共用で使う環境の場合$HOMEの下にgoディレクトリを作成してそこに設定するのが良いらしい?
サンプル作成
プロジェクトルート作成
$ mkdir go_lang_sample
$ cd go_lang_sample
とりあえず標準出力するプログラムをコーディング...そうHello worldである。
$ vi main.go
内容
package main
import "fmt"
func main() {
fmt.Println("hello go")
}
実行
$ go run main.go
hello go
バイナリジェネレート
$ go build main.go
$ ls -l
-rwxr-xr-x 1 x x 1758417 Oct 28 08:56 main
-rw-r--r-- 1 x x 69 Oct 28 08:49 main.go
$ ./main
hello go
生成されたバイナリを見てみる
$ file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=tCA68fbwmaBGF2DhQaa2/UIAEBKiamDIFylGztcuJ/PdZUaMTfyMY9U1yRa7Mt/UYZftBc0pC1EWaw8P6i-, not stripped
$ $ readelf -h main
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x45bfa0
Start of program headers: 64 (bytes into file)
Start of section headers: 456 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 7
Size of section headers: 64 (bytes)
Number of section headers: 23
Section header string table index: 3
C言語と比較
$ mkdir tmp
$ cd tmp
$ vi main.c
#include <stdio.h>
void main(int argc, char *argv) {
printf("hello c\n");
}
$ gcc main.c -o main
$ ls -l
-rwxr-xr-x 1 x x 15960 Oct 28 09:01 main
-rw-r--r-- 1 x x 78 Oct 28 09:01 main.c
$ readelf -h main
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Position-Independent Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1060
Start of program headers: 64 (bytes into file)
Start of section headers: 13976 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 30
Go言語のほうがファイルサイズ大きい、GCとかするっぽいのでそこら辺のライブラリが入っているのだろう
という事で教えてチャットGPT!
Go言語のビルドファイルとC言語のビルドファイルでファイルサイズに差があるのはなぁぜなぁぜ?
Go言語のビルドファイルとC言語のビルドファイルでファイルサイズに差がある主な理由は、言語の設計と実行環境の違いによります。以下はいくつかの主要な要因です:
静的リンクとダイナミックリンク: C言語のビルドファイルは通常、静的リンクされた実行可能ファイルを生成します。これは、すべての依存関係が実行可能ファイルに組み込まれることを意味します。Go言語は通常、ダイナミックリンクをサポートし、実行可能ファイルはGoランタイムライブラリに依存します。したがって、Goプログラムは通常、実行時にライブラリをロードする必要があるため、実行可能ファイルは比較的小さくなります。
コードの最適化: コンパイラによって生成されるコードの最適化レベルや方法にも差があります。コンパイラは、プログラムのパフォーマンスとサイズのトレードオフを調整するために異なるオプションを使用できます。言語ごとにコンパイラの最適化戦略が異なり、これが実行可能ファイルのサイズに影響を与えます。
言語機能の違い: GoとCは異なる言語であり、それぞれ独自の機能セットを持っています。Goは並行処理やメモリセーフティなどの高度な機能を提供するため、それらの機能に関連するコードが実行可能ファイルに含まれる可能性があります。