Go Build Toolchain
Go 프로젝트에서 자주 쓰는 빌드/검증 커맨드를 정리한다.
1. go mod tidy
tidy = "깔끔하게 정리하다". go.mod/go.sum을 깔끔하게 정리하는 명령어. 코드에서 실제로 import하는 패키지만 go.mod/go.sum에 남기고 나머지는 제거한다.
go mod tidy
하는 일:
- 코드에서 import하지만
go.mod에 없는 패키지 → 추가 go.mod에 있지만 코드에서 import하지 않는 패키지 → 제거go.sum에서 불필요한 체크섬 엔트리 → 제거
# 흐름
소스코드 스캔 → import 목록 수집 → go.mod 비교 → 추가/제거 → go.sum 갱신
CI에서 go mod tidy를 실행한 뒤 diff가 있으면 실패시키는 패턴이 일반적이다. 개발자가 의존성 정리를 빠뜨린 걸 잡아낸다.
go mod tidy
git diff --exit-code go.mod go.sum
관련 명령어
go mod download # go.mod 기준으로 의존성 다운로드 (정리는 안 함)
go mod verify # go.sum 체크섬 검증
go mod vendor # vendor/ 디렉토리에 의존성 복사
go mod graph # 의존성 그래프 출력
2. go vet
Go 소스코드의 정적 분석 도구. 컴파일은 되지만 버그일 가능성이 높은 코드를 잡아낸다.
go vet ./...
잡아내는 것들:
fmt.Printf포맷과 인자 타입 불일치- 도달 불가능한 코드
- 구조체 태그 오류
- 잘못된 sync 사용 (mutex 복사 등)
- 잘못된 context 사용
// go vet이 잡아내는 예시
// Printf 포맷 불일치
fmt.Printf("%d", "hello") // vet: wrong type for %d
// mutex 값 복사
var mu sync.Mutex
mu2 := mu // vet: assignment copies lock value
// 사용하지 않는 결과
fmt.Sprintf("hello") // vet: result not used
go vet은 컴파일러가 잡지 못하는 논리적 실수를 잡아주므로, CI에서 반드시 돌려야 한다.
go vet vs linter
| go vet | golangci-lint | |
|---|---|---|
| 범위 | Go 공식 도구, 보수적 | 여러 linter 통합 (vet 포함) |
| 오탐 | 거의 없음 | 설정에 따라 다름 |
| 용도 | 확실한 버그 감지 | 코드 스타일 + 버그 감지 |
3. go build
소스코드를 컴파일하여 바이너리를 생성한다.
go build ./... # 전체 패키지 빌드 (바이너리 생성 없이 컴파일 확인)
go build -o bin/myapp ./cmd/myapp # 바이너리 출력 경로 지정
빌드 과정
소스코드 파싱
→ import 의존성 해석
→ 패키지별 컴파일 (병렬)
→ 링킹
→ 바이너리 출력
Go는 패키지 단위로 컴파일하고, 변경되지 않은 패키지는 캐시를 재사용한다.
자주 쓰는 옵션
# 빌드 캐시 무시하고 전체 재빌드
go build -a ./...
# 빌드 시 ldflags로 변수 주입 (버전 정보 등)
go build -ldflags "-X main.version=1.0.0 -X main.commit=$(git rev-parse HEAD)" -o bin/myapp ./cmd/myapp
# CGO 비활성화 (순수 Go 바이너리, static linking)
CGO_ENABLED=0 go build -o bin/myapp ./cmd/myapp
# 크로스 컴파일
GOOS=linux GOARCH=amd64 go build -o bin/myapp ./cmd/myapp
ldflags 활용
빌드 시점에 변수 값을 주입할 수 있다. 버전, 커밋 해시, 빌드 시간 등을 바이너리에 심는 패턴.
package main
var (
version = "dev"
commit = "none"
)
func main() {
fmt.Printf("version: %s, commit: %s\n", version, commit)
}
go build -ldflags "-X main.version=1.2.3 -X main.commit=abc1234" -o bin/myapp
4. 일반적인 빌드 순서
go mod tidy # 1. 의존성 정리
go vet ./... # 2. 정적 분석
go test ./... # 3. 테스트
go build ./... # 4. 빌드
CI에서도 이 순서를 따르는 것이 일반적이다.