반응형

Macbook M1을 구입하고, 대체로 만족하면서 사용하고 있었는데

막상 go source code를 작성하고 compile하려고 생각해보니, 실제로 실행 파일(executable file)을 돌릴 대상 장비가 x86 cpu를 사용하는 경우가 대부분이라서 cross compile 필요성을 느꼈다.

아직 한번도 go cross compile을 하지 않았던터라, 이번 기회에 짧게 메모를 해본다.

 

cross compile 지원되는 OS와 CPU architecture 확인

$ go tool dist list
aix/ppc64
android/386
... 중간 생략 ...
darwin/amd64    <-- Intel Mac을 사용하는 경우
darwin/arm64    <-- M1 Mac을 사용하는 경우
...
linux/386
linux/amd64     <-- Intel Linux를 사용하는 경우 (아마 대부분 이 경우가 아닐까?)
linux/arm
linux/arm64
... 중간 생략 ...
windows/386
windows/amd64
windows/arm
windows/arm64
$

 

go cross compile

Case: Linux OS & Intel CPU

M1 Macbook에서 Linux OS에서 돌릴 executable file을 build하는 방법이다.

GOOS=linux  GOARCH=amd64 환경 변수만 설정하고, go build 명령을 수행하면 Linux OS에서 돌아가는 실행 파일이 만들어진다.

$ go mod init  andrew.space/myapp
$ go mod tidy
$ GOOS=linux GOARCH=amd64  go build 
$ ls
myapp
$

 

Case: Linux OS & ARM CPU

Intel Macbook에서 M1 Macbook에서 돌릴 executable file을 build하는 방법이다.

GOOS=darwin  GOARCH=arm64 환경 변수만 설정하고, go build 명령을 수행하면 M1 Mac OS에서 돌아가는 실행 파일이 만들어진다.

(여담이지만, 이미 M1 Mac OS는 OS 자체적으로 Intel->ARM 구조로 변환해주는 기능이 있어서 굳이 이렇게까지 열심히 Cross compile을 하지 않아도 된다)

$ go mod init  andrew.space/myapp
$ go mod tidy
$ GOOS=darwin GOARCH=arm64  go build 
$ ls
myapp
$

 

Case:  다양의 OS와 CPU에 대한 일괄적으로 Cross Compile하기

매번 대상 OS와 CPU에 맞춰서 Cross Compile하기 귀찮다면, 아래와 같이 모든 OS, CPU에 대해서 Cross compile하도록  script를 만든다.

#!/usr/local/bin/bash

archs=(amd64 arm64 ppc64)

for arch in ${archs[@]}
do
        env GOOS=linux GOARCH=${arch} go build -o myapp_${arch}
done

 

 

Tip:  .bashrc 파일에 GO 환경 변수 설정

위에서 설명한 $GOOS, $GOARCH 환경 변수를 매번 타이핑하기 싫다면

아래처럼 .bashrc 파일에 한번만 기록해놓자!!!

 

$  cat ~/.bashrc

... 중간 생략 ...

##
## For GoLang
##
export GOPATH=$(go env GOPATH)
export GO111MODULE=on
export GOOS=linux
export GOARCH=amd64

... 중간 생략 ...

$
반응형

처음으로 golang builder를 설치하고, App 개발을 시작하려면 App 개발을 위한 최상위 폴더를 생성해야 한다.

그리고 그 최상위 폴더에서 아래와 같이 초기화 작업을 해야 한다.

 

$  go mod init  andrew.space/myapp

# 위 명령에 대한 에러가 없다면, 아래의 명령을 수행한다.
# .go source code를 수정했다면 아래 명령을 수행할 것을 권한다.
# 왜냐고? .go에서 사용된 pkg 파일을 자동으로 찾아서 download해주기 때문이다.
$  go mod tidy

 

Go 언어 예제를 작성한다.

 

package main

import "fmt"

func main() {

    if 7%2 == 0 {
        fmt.Println("7 is even")
    } else {
        fmt.Println("7 is odd")
    }

    if 8%4 == 0 {
        fmt.Println("8 is divisible by 4")
    }

    if num := 9; num < 0 {
        fmt.Println(num, "is negative")
    } else if num < 10 {
        fmt.Println(num, "has 1 digit")
    } else {
        fmt.Println(num, "has multiple digits")
    }
}

 

위 예제 코드를 빌드한다.

 

$  go mod tidy

$  go build

$  ls
go.mod   main.go  myapp*

$  ./myapp
7 is odd
8 is divisible by 4
9 has 1 digit

$

+ Recent posts