크로스 컴파일 OSX로 이동 하시겠습니까?


142

Windows 및 Linux 용 바이너리를 빌드하기 위해 OSX에서 go 앱을 크로스 컴파일하려고합니다. 나는 인터넷에서 찾을 수있는 모든 것을 읽었습니다. 내가 찾은 가장 가까운 예가 게시되었습니다 (gonuts 메일 링리스트에 대한 많은 미완성 토론 제외).

http://solovyov.net/en/2012/03/09/cross-compiling-go/

그러나 내 설치에서 작동하지 않습니다. 나는 1.0.2 갔다. 1.0.2가 최신 버전이므로 위의 모든 예제가이 버전에 적용되지 않는 것으로 보입니다.

./make.bash --no-cleanENV vars를 386 / windows로 설정 하려고 시도 했지만 빌드가 진행되지만 설치를 위해 빌드가 진행되며 darwin/amd64다른 컴파일러를 빌드한다고 가정하는 ENV에 설정된 것을 완전히 무시합니다.

어떻게 할 수 있는지 조언합니다 (완전히 할 수 있다면)?


이것과 병행하여 golang-nuts 메일 링리스트에서 같은 질문을했습니다. 그리고 사람들의 친절한 도움과 인내심으로 최종 레시피가 요리되었습니다 ... 이것은 토론 스레드입니다 : groups.google.com/forum/?fromgroups=# ! topic / golang-nuts /… 여러 단계와 결론이 있었는데, 도중에 잘못되었지만 레시피는 매우 간단 해 보입니다. 3 단계와 몇 가지 반복입니다.
ljgww

이제 요약을 살펴 보니 ENV vars가 올바른 컴파일을 트리거하지 않은 이유에 대해 방황합니다. 아마도 내가했기 때문에 sudo(아마도 suxing 할 때 다른 유닉스 ENV를 얻었으므로 GOOS & GOARCH를 사용할 수 없을 경우 사용하지 못할 것입니다) 인라인)
ljgww

다시 : jdi-난 그냥 내 "mockup"go 응용 프로그램을 컴파일 Mac에서 바이너리 / 승리 바이너리를 컴파일하려고했지만, 그렇게하려면 플랫폼 / 프로세서의 각 조합에 대해 자체 빌드해야했습니다. (아직 내 자신의 질문에 대답 할 수 없습니다-여기에 평판이 충분하지 않음)
ljgww

1
예제에서 말한 내용을 정확히 입력 했습니까? CGO_ENABLED=0 GOOS=windows GOARCH=amd64 ./make.bash-여러 줄로 나누려고하면 증상에 맞는 환경 변수가 내보내지지 않습니다.
Nick Craig-Wood

호스트 및 대상 아키텍처를 혼동하지 않아야합니다. "# 호스트, darwin / amd64 용 컴파일러 및 Go 부트 스트랩 도구 빌드"출력이 표시됩니다. "# 호스트 darwin / amd64에 대한 패키지 및 명령 빌드" "# windows / 386 용 패키지 및 명령 빌드."
Sam

답변:


157

Go 1.5에서는 크로스 컴파일 프로세스가 개선 된 것 같습니다. 즉, 현재 내장되어 있습니다. 어떤 ./make.bash-ing하거나 brew필요 -ing. 프로세스는 여기에 나와 있지만 나와 같은 TLDR 사용자를 위해 설명 되어 있습니다. GOOSGOARCH환경 변수를 설정 하고 이동 빌드를 실행하십시오.

저와 같은 게으른 복사 붙여 넣기를 위해 * nix 시스템을 사용하는 경우 다음과 같이하십시오.

env GOOS=linux GOARCH=arm go build -v github.com/path/to/your/app

심지어 env그 명령에 대해서만 환경 변수를 완전히 무료로 설정할 수 있는 트릭을 배웠습니다 .


4
env명령은 사용자 정의 환경에서만 해당 호출을 실행하고 완료된 후 '재설정'합니다. 예를 들어 실행을 위해 export GOOS=windows함께 또는없이 다음 명령 envecho $GOOS이후. envGOOS 와 함께 변경되지 않았습니다.
leondepeon

3
없이도 (적어도 Bash에서는) 동일합니다 env. 나는 실행 export GOOS=windows한 후 GOOS=linux bash -c 'echo "GOOS: $GOOS"'다음 echo "GOOS: $GOOS". 않는 env다른 쉘 방언 또는 다른 플랫폼과 큰 호환성을 제공? 그렇지 않은 경우 여기에 불필요한 것처럼 보입니다.
davidchambers

2
@davidchambers BASH에서는 동일합니다. 다른 쉘 (예 : FISH 쉘)에서는 지원하지 않으므로을 FOO=bar cmd사용해야 env FOO=bar cmd합니다. 따라서 가장 큰 장점 env FOO=bar cmd은 호환성 이라고 생각합니다 .
PickBoy

1
바로 여기에 놀라운 답변입니다. 당신은 내 문제를 해결하고 저에게 새로운 트릭을 가르쳐 주었고 저를 괴롭 혔습니다.
T Blank

1
좋은 답변, 감사합니다! heroku (intel x86)에서 사용하기 위해 컴파일하기 위해 라인을 약간 수정했으며 env GOOS=linux GOARCH=386 go build -v github.com/path/to/your/app챔피언처럼 작동합니다
Ira Herman

136

golang-nuts의 친절하고 환자의 도움 덕분에 조리법은 다음과 같습니다.

1) 다른 대상 플랫폼과 아키텍처에 맞게 Go 컴파일러를 컴파일해야합니다. 이것은 go 설치의 src 폴더에서 수행됩니다. 필자의 경우 Go 설치가 /usr/local/go컴파일러를 컴파일하기 위해 위치 하므로 make유틸리티 를 실행해야 합니다. 이 작업을 수행하기 전에 몇 가지주의 사항을 알아야합니다.

크로스 컴파일시 CGO 라이브러리에 대한 문제가 있으므로 CGO 라이브러리를 비활성화해야합니다.

해당 폴더에서 컴파일을 수행해야하므로 소스 디렉토리로 위치를 변경하여 컴파일

cd /usr/local/go/src

그런 다음 Go 컴파일러를 컴파일하십시오.

sudo GOOS=windows GOARCH=386 CGO_ENABLED=0 ./make.bash --no-clean

GOOS 및 GOARCH 매개 변수를 변경하여 크로스 컴파일하려는 각 OS 및 아키텍처에 대해이 단계를 반복해야합니다.

내가하는 것처럼 사용자 모드로 작업하는 경우 Go 컴파일러가 시스템 디렉토리에 있기 때문에 sudo가 필요합니다. 그렇지 않으면 수퍼 유저로 로그인해야합니다. Mac에서는 SU 액세스를 활성화 / 구성해야 할 수 있지만 (기본적으로 제공되지 않음) Go를 설치 한 경우 이미 루트 액세스 권한이있을 수 있습니다.

2) 모든 크로스 컴파일러가 작성되면 다음 설정을 사용하여 애플리케이션을 행복하게 크로스 컴파일 할 수 있습니다.

GOOS=windows GOARCH=386 go build -o appname.exe appname.go

GOOS=linux GOARCH=386 CGO_ENABLED=0 go build -o appname.linux appname.go

GOOS 및 GOARCH를 빌드하려는 대상으로 변경하십시오.

CGO에 문제가 발생하면 명령 행에 CGO_ENABLED = 0을 포함하십시오. 또한 Linux 및 Mac 용 바이너리에는 확장명이 없으므로 다른 파일을 사용하기 위해 확장명을 추가 할 수 있습니다. -o 스위치는 출력 파일을 c / c ++의 이전 컴파일러와 비슷하게 만들도록 지시합니다. 따라서 위에서 사용 된 appname.linux는 다른 확장자 일 수 있습니다.


처음에 혼란 스러웠던 것은 컴파일의 첫 번째 부분에서 다음과 같이 말합니다. # Building compilers and Go bootstrap tool for host, darwin/amd64그러나 나중에 실제로는 다음과 같이 끝납니다. --- Installed Go for windows/386 in /usr/local/go Installed commands in /usr/local/go/bin그래서 컴파일러 컴파일을 시작하기보다는 끝을 관찰해야합니다.
ljgww

모든 시도를 시작으로 시작하고 $ GOARCH=386 GOOS=linux go build app.go오류가 발생 # runtime /usr/local/go/src/pkg/runtime/extern.go:137: undefined: theGoos /usr/local/go/src/pkg/runtime/extern.go:137: cannot use theGoos as type string in const initializer
ljgww

30
Homebrew의 Go 패키지에는 모든 크로스 컴파일러를 자동으로 빌드하는 "--cross-compile-all"옵션이 있습니다.
nimrodm

8
좋은 팁 @ nimrodm! go 설치를 다시 컴파일하려면 다음을 실행해야합니다brew reinstall go --cross-compile-all
linqu

1
@ljgww 'sudo'에 ENV가 구성되어 있지 않습니다. 나는 / usr / local / go / pkg / linux_amd64 /에서 chown을 사용하여 끝났다
Nuno Silva

63

OS X에서 Homebrew 를 사용 하는 경우 더 간단한 솔루션이 있습니다.

$ brew install go --with-cc-common # Linux, Darwin, and Windows

또는..

$ brew install go --with-cc-all # All the cross-compilers

reinstall이미 go설치 한 경우 사용하십시오 .


3
업데이트 된 스위치는 다음과 같습니다. --cross-compile-all 지원되는 모든 플랫폼에 대해 크로스 컴파일러 및 런타임 지원 빌드 --cross-compile-common darwin, Linux 및 Windows에 대한 크로스 컴파일러 및 런타임 지원 빌드
Chip Tol

3
--cross-compile-all지금--with-cc-all
gianebao

@ sheeks06-고정되었습니다. 감사!
docwhat

1
이 플래그는 더 이상 내가 말할 수있는 것에서 존재하지 않습니다. 내가 볼 수있는 유일한 관련 옵션은 --without-cgo :(
rdegges

5
Go 1.5부터는 별도의 크로스 컴파일러가 없으므로 이제 tip.golang.org/doc/go1.5#compiler_and_tools
chuckus Juls

24

Docker를 사용하면이 작업을 쉽게 수행 할 수 있으므로 추가 라이브러리가 필요하지 않습니다. 이 명령을 실행하십시오.

docker run --rm -it -v "$GOPATH":/go -w /go/src/github.com/iron-io/ironcli golang:1.4.2-cross sh -c '
for GOOS in darwin linux windows; do
  for GOARCH in 386 amd64; do
    echo "Building $GOOS-$GOARCH"
    export GOOS=$GOOS
    export GOARCH=$GOARCH
    go build -o bin/ironcli-$GOOS-$GOARCH
  done
done
'

이 게시물에서 자세한 내용을 찾을 수 있습니다 : https://medium.com/iron-io-blog/how-to-cross-compile-go-programs-using-docker-beaa102a316d


1
왜 누군가가 Docker를 설치하여 쉘 루프를 수행 env GOOS=x GOARCH=y go install something/...하고 적절한 바이너리를 사용할 수있을 때이 작업을 수행하려고합니까 $GOPATH/bin/$GOOS_$GOARCH?? 그리고 BTW, Go는 당신이 나열한 3 가지 이상의 OS를 지원합니다. 왜 BSD에 대한 사랑이 없습니까?
Dave C

8
Docker를 설치 하여이 작업을 수행하지는 않지만 대안이있는 경우보다 쉽고 깨끗합니다.
Travis Reeder

7

많은 플랫폼에서 실행 파일을 만드는 과정은 약간 지루할 수 있으므로 스크립트를 사용하는 것이 좋습니다.

#!/usr/bin/env bash

package=$1
if [[ -z "$package" ]]; then
  echo "usage: $0 <package-name>"
  exit 1
fi
package_name=$package

#the full list of the platforms: https://golang.org/doc/install/source#environment
platforms=(
"darwin/386"
"dragonfly/amd64"
"freebsd/386"
"freebsd/amd64"
"freebsd/arm"
"linux/386"
"linux/amd64"
"linux/arm"
"linux/arm64"
"netbsd/386"
"netbsd/amd64"
"netbsd/arm"
"openbsd/386"
"openbsd/amd64"
"openbsd/arm"
"plan9/386"
"plan9/amd64"
"solaris/amd64"
"windows/amd64"
"windows/386" )

for platform in "${platforms[@]}"
do
    platform_split=(${platform//\// })
    GOOS=${platform_split[0]}
    GOARCH=${platform_split[1]}
    output_name=$package_name'-'$GOOS'-'$GOARCH
    if [ $GOOS = "windows" ]; then
        output_name+='.exe'
    fi

    env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
    if [ $? -ne 0 ]; then
        echo 'An error has occurred! Aborting the script execution...'
        exit 1
    fi
done

OSX에서만이 스크립트를 확인했습니다.

요점-go- executable-build.sh


정확히 무엇을 내가 그것을 :) dockerized이 ... 찾고 있었다 gist.github.com/marcellodesales/...
마르첼로 드 판매

6

OSX 타겟팅 창에서 CGO를 활성화하고 크로스 컴파일 해야하는 사람들을 위해

나는 필요 CGO는 내가 가져온했기 때문에 내 Mac에서 Windows 용 컴파일하는 동안 사용할 수 https://github.com/mattn/go-sqlite3 하고 그것을 필요로했다. 다른 답변에 따라 컴파일하면 오류가 발생했습니다.

/usr/local/go/src/runtime/cgo/gcc_windows_amd64.c:8:10: fatal error: 'windows.h' file not found

당신이 나와 같고 CGO로 컴파일해야한다면. 이것이 내가 한 일입니다.

1. CGO 종속 라이브러리가있는 창을 위해 크로스 컴파일 할 것입니다. 먼저 다음과 같이 설치된 크로스 컴파일러가 필요합니다mingw-w64

brew install mingw-w64

아마도 여기에 설치 될 것입니다 /usr/local/opt/mingw-w64/bin/.

2. 다른 답변과 마찬가지로 지금 우리의 go arch를 go 컴파일러 툴체인에 추가해야합니다. 컴파일러를 컴파일하려면 컴파일러 (이상한 문장)가 필요합니다. 컴파일러를 컴파일하려면 별도의 사전 빌드 된 컴파일러가 필요합니다. 우리는 미리 빌드 된 바이너리를 다운로드하거나 폴더의 소스에서 빌드 ~/Documents/go 할 수 있습니다 : 이제 우리는 최고 답변에 따라 Go 컴파일러를 향상시킬 수 있지만 이번에는 CGO_ENABLED=1별도의 사전 빌드 컴파일러 와 함께 GOROOT_BOOTSTRAP(Pooya는 내 사용자 이름입니다) :

cd /usr/local/go/src
sudo GOOS=windows GOARCH=amd64 CGO_ENABLED=1 GOROOT_BOOTSTRAP=/Users/Pooya/Documents/go ./make.bash --no-clean
sudo GOOS=windows GOARCH=386 CGO_ENABLED=1 GOROOT_BOOTSTRAP=/Users/Pooya/Documents/go ./make.bash --no-clean

3. Go 코드를 컴파일하는 동안 mingwCGO가 활성화 된 go 파일 타겟팅 창을 컴파일 하는 데 사용합니다.

GOOS="windows" GOARCH="386" CGO_ENABLED="1" CC="/usr/local/opt/mingw-w64/bin/i686-w64-mingw32-gcc" go build hello.go
GOOS="windows" GOARCH="amd64" CGO_ENABLED="1" CC="/usr/local/opt/mingw-w64/bin/x86_64-w64-mingw32-gcc" go build hello.go
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.