프로그래밍 언어/Golang

Go: 개발 환경과 도구, 크로스 컴파일

환경변수

Go 를 사용하면서 알아두어야 할 일부 환경변수가 있는데, 알아보도록 하자. 콘솔에 go env 를 입력하면 아래와 같이 Go 에서 사용하는 환경변수 목록을 확인할 수 있다. 다 살펴볼 필요는 없지만, GOROOT, GOPATH, GOBIN, GOARCH, GOOS 정도는 알아두면 개발할 때 도움이 된다. 게다가 GOOS, GOAHCH크로스 컴파일(Cross-Compile)을 할 때도 지정하는 환경변수이기도 하다.

$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\user\AppData\Local\go-build
set GOENV=C:\Users\user\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\user\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\user\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\user\AppData\Local\Temp\go-build188464778=/tmp/go-build -gno-reco
rd-gcc-switches

GOROOT, GOPATH

GOROOT, GOPATH 환경변수는 Go 를 설치하고 난 이후 설정이 되어있거나 그렇지 않은 경우 반드시 설정해야한다. 이는 Go 의 개발환경을 구축할 때 가장 먼저 해야할 일이다.

GOROOT

GOROOT 는 go 바이너리가 포함되어 있는 폴더이며 bin, pkg, src 폴더로 구성되어 있다. bin 에는 go 바이너리가 포함되어 있고, src 에는 go 언어에서 사용하는 내장 패키지들이 있으며 pkg 에는 그러한 패키지들이 컴파일된 파일들이 담겨 있다. GOROOT 환경변수는 수동으로 설정해도 되지만, 설치시 자동으로 설정이 되어 있는 경우도 있다. 나의 경우에는 Windows 에서 개발을 진행하므로 대체로 GOROOT 는 C:\go 에 위치해있다.

GOPATH

GOPATH 에는 Go 프로젝트가 있는 워크스페이스를 등록해주면 되는데, 어느 디렉토리여도 상관없다. Go 언어로 개발할 때 실제로 들어갈 프로젝트나 패키지가 자리하고 있는 디렉토리이면 된다. GOROOT 와 마찬가지로 bin, pkg, src 폴더가 위치하며 그 의미는 같다. go get 으로 다른 외부 패키지를 설치하게 되면 GOPATHsrc 에 패키지가 설치된다. $USERPROFILEWindows 에서 유저의 홈 디렉토리를 의미한다.

go env -w GOPATH=$USERPROFILE\\go

GOBIN

GOBIN 같은 경우, 예를 들어 gore* 와 같이 Go 에서 기본적으로 제공하는 도구 이외에 다른 CLI 도구를 설치할 때 해당 도구의 바이너리가 위치하는 장소이다. 설정을 안 해도 괜찮긴 하지만 GOPATH\\bin 로 설정해두는 것도 나쁘지 않다.

go env -w GOBIN=$USERPROFILE\\go\\bin
*gore 는 go REPL(Read-Eval Print Loop)도구이다.

GOOS, GOARCH

GOOS 는 Go 를 설치하면 일반적으로 자동으로 설정되는데, 기본적으로는 Go 가 설치된 OS 를 따른다. 이는 go build 크로스 컴파일을 할 때 설정하면 되며 GOOS 에 설정하는 것은 linux, darwin, windowsOS 를 지칭하는 이름을 넣어준다. GOARCH 환경변수는 CPU 아키텍쳐를 명시하면 되고 368, amd64 를 주로 사용하게 된다. 이 둘을 사용하게 되면 Windows 에서도 Linux 앱을 빌드할 수 있다.

GOOS=linux GOARCH=amd64 go build

GOOS, GOARCH 에 설정할 수 있는 값은 아래의 문서를 참고해보면 알 수 있다.

 

https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63

 

Go (Golang) GOOS and GOARCH

Go (Golang) GOOS and GOARCH. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

도구

Go CLI 에는 여러가지 도구가 담겨있다. go help 를 사용하면 명령어 리스트를 볼 수 있다. VSCode Go 플러그인을 쓰거나, Goland IDE 를 사용하다보면 Go 코드를 자동으로 고쳐주거나, import 를 자동으로 코드에 넣어주는 것을 볼 수 있는데, 코드를 포맷팅 해주는 것에는 go fmt, 그리고 명령어에는 없지만 import 코드를 자동으로 넣어주는 것은 goimports 가 있다. goimports 는 일반적으로 우리가 직접 사용하지는 않는다.

$ go help
Go is a tool for managing Go source code.

Usage:

        go <command> [arguments]

The commands are:

        bug         start a bug report
        build       compile packages and dependencies
        clean       remove object files and cached files
        doc         show documentation for package or symbol
        env         print Go environment information
        fix         update packages to use new APIs
        fmt         gofmt (reformat) package sources
        generate    generate Go files by processing source
        get         download and install packages and dependencies
        install     compile and install packages and dependencies
        list        list packages or modules
        mod         module maintenance
        run         compile and run Go program
        test        test packages
        tool        run specified go tool
        version     print Go version
        vet         report likely mistakes in packages

VSCode Go 플러그인과 Goland IDE 에서 제공하는 이러한 기능들은 Go 도구들에 의해 가능한 것이다. 코드 포맷팅을 위한 go fmt 명령어에서 사용하는 것은 gofmt 이며, 버그가 발생 할만한 코드를 찾아주는 go vet 라는 것도 있다.

 

사용하다보면 어떤 도구는 이름이 비슷해서 헷갈릴 때가 있는데, 특히 go doc, godoc 이 그렇다. go doc 은 go 의 서브 커맨드 doc 을 의미하고 godoc 은 독립적인 도구로써 바이너리 이름자체가 godoc 인 것이다. 둘은 비슷하지만 go doc 의 경우 CLI 상에서 패키지와 함수 및 메서드, 타입의 사용법을 알아볼 때 사용하고, godoc 은 패키지를 문서화하여 웹상에서 보여줄 수 있다.

$ go doc fmt.Println
package fmt // import "fmt"

func Println(a ...interface{}) (n int, err error)
    Println formats using the default formats for its operands and writes to
    standard output. Spaces are always added between operands and a newline is
    appended. It returns the number of bytes written and any write error
    encountered.

그 외에 많이 사용하는 것은 패키지를 얻어올 때 사용하는 go get, 프로그램을 컴파일하여 하나의 바이너리로 출력할 수 있도록 해주는 go build, go install, 코드를 파일 단위로 실행할 수 있도록 만드는 go run, 테스트를 실행할 수 있는 go test 가 있다.