PHpullh
학습 라이브러리/Go/빌드 태그 & 크로스 컴파일

GO · 성능

빌드 태그 & 크로스 컴파일

Go의 빌드 태그(//go:build)로 플랫폼별 코드를 분리하고, 환경 변수로 손쉽게 크로스 컴파일합니다. CGO 없이 정적 바이너리를 생성하여 Docker scratch 이미지나 다른 OS용 배포가 가능합니다.

성능고급build-tagscross-compilestatic-binarydockerdeployment

핵심 설명

Go의 빌드 태그(//go:build)로 플랫폼별 코드를 분리하고, 환경 변수로 손쉽게 크로스 컴파일합니다. CGO 없이 정적 바이너리를 생성하여 Docker scratch 이미지나 다른 OS용 배포가 가능합니다.

Go code

package main

import (
	"fmt"
	"runtime"
)

// === 빌드 태그 예제 ===

// 파일: config_prod.go
// //go:build prod
// package main
// var AppMode = "production"

// 파일: config_dev.go
// //go:build !prod
// package main
// var AppMode = "development"

// 파일: platform_linux.go
// //go:build linux
// func platformInfo() string { return "Linux 최적화 경로 사용" }

// 파일: platform_windows.go
// //go:build windows
// func platformInfo() string { return "Windows API 사용" }

// 파일: platform_default.go
// //go:build !linux && !windows
// func platformInfo() string { return "범용 구현 사용" }

func main() {
	// 현재 빌드 정보
	fmt.Printf("OS:   %s\n", runtime.GOOS)
	fmt.Printf("Arch: %s\n", runtime.GOARCH)
	fmt.Printf("CPUs: %d\n", runtime.NumCPU())
	fmt.Printf("Go:   %s\n", runtime.Version())

	fmt.Println("\n=== 크로스 컴파일 명령어 ===")
	targets := []struct{ os, arch, desc string }{
		{"linux", "amd64", "Linux x86_64 서버"},
		{"linux", "arm64", "Linux ARM (AWS Graviton)"},
		{"darwin", "arm64", "macOS Apple Silicon"},
		{"windows", "amd64", "Windows x86_64"},
		{"linux", "amd64", "정적 바이너리 (Alpine/scratch)"},
	}

	for _, t := range targets {
		cmd := fmt.Sprintf("GOOS=%s GOARCH=%s go build -o app-%s-%s",
			t.os, t.arch, t.os, t.arch)
		if t.desc == "정적 바이너리 (Alpine/scratch)" {
			cmd = "CGO_ENABLED=0 " + cmd + "-static"
		}
		fmt.Printf("  %-50s # %s\n", cmd, t.desc)
	}

	fmt.Println("\n=== 빌드 태그 사용 ===")
	fmt.Println("  go build -tags prod           # 프로덕션 모드")
	fmt.Println("  go build -tags 'prod metrics'  # 여러 태그")
	fmt.Println("  go build -ldflags '-s -w'      # 디버그 정보 제거 (바이너리 축소)")

	fmt.Println("\n=== Dockerfile 예제 ===")
	dockerfile := "# Multi-stage 빌드\n" +
		"FROM golang:1.22-alpine AS builder\n" +
		"WORKDIR /app\n" +
		"COPY go.* ./\n" +
		"RUN go mod download\n" +
		"COPY . .\n" +
		"RUN CGO_ENABLED=0 go build -ldflags='-s -w' -o /server\n" +
		"FROM scratch\n" +
		"COPY --from=builder /server /server\n" +
		"ENTRYPOINT [\"/server\"]"
	fmt.Println(dockerfile)
}

학습 팁

Go 1.17+에서는 //go:build 형식을 사용하세요(기존 // +build는 deprecated). -ldflags="-s -w"로 바이너리 크기를 20~30% 줄일 수 있습니다.

주의할 점

CGO_ENABLED=0을 설정하지 않으면 C 라이브러리에 동적 링크되어 Alpine이나 scratch 이미지에서 실행되지 않습니다. 또한 net 패키지가 기본적으로 cgo를 사용하므로 주의하세요.

자주 묻는 질문

빌드 태그 & 크로스 컴파일란 무엇인가요?

Go의 빌드 태그( //go:build )로 플랫폼별 코드를 분리하고, 환경 변수로 손쉽게 크로스 컴파일합니다. CGO 없이 정적 바이너리를 생성하여 Docker scratch 이미지나 다른 OS용 배포가 가능합니다.

빌드 태그 & 크로스 컴파일 학습 시 주의할 점은 무엇인가요?

CGO_ENABLED=0 을 설정하지 않으면 C 라이브러리에 동적 링크되어 Alpine이나 scratch 이미지에서 실행되지 않습니다. 또한 net 패키지가 기본적으로 cgo를 사용하므로 주의하세요.