Biên dịch chéo Đi trên OSX?


142

Tôi đang cố gắng biên dịch chéo một ứng dụng đi trên OSX để xây dựng nhị phân cho windows và linux. Tôi đã đọc tất cả những gì tôi có thể tìm thấy trên mạng. Ví dụ gần nhất mà tôi đã tìm thấy đã được xuất bản trên (ngoài nhiều cuộc thảo luận còn dang dở trong danh sách gửi thư của go-nut):

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

nhưng nó không hoạt động trên cài đặt của tôi. Tôi đã đi 1.0.2. Vì 1.0.2 khá gần đây đối với tôi, tất cả các ví dụ trên không áp dụng cho phiên bản này.

Đã thử làm ./make.bash --no-cleanvới các vars ENV được đặt thành 386 / windows, nó thực sự xây dựng, tuy nhiên nó xây dựng để cài đặt của tôi darwin/amd64và hoàn toàn bỏ qua những gì được đặt trong ENV giả sử xây dựng trình biên dịch khác nhau.

Bất kỳ lời khuyên làm thế nào nó có thể được thực hiện (nếu nó có thể được thực hiện ở tất cả)?


song song với điều này, tôi đã hỏi cùng một câu hỏi trong danh sách gửi thư của golang-nut, và với sự giúp đỡ và kiên nhẫn của mọi người, công thức cuối cùng đã được nấu chín ... đây là chủ đề thảo luận: Groups.google.com/forum/?fromgroups=# ! topic / golang-nut / Nhận có một vài bước và kết luận, tôi đã sai trên đường đi, nhưng bây giờ công thức có vẻ khá đơn giản - 3 bước và một số lần lặp.
ljgww

Bây giờ tôi sẽ tóm tắt lại, tôi đi lang thang về lý do tại sao các vars ENV không kích hoạt việc biên dịch chính xác - có thể vì tôi đã làm sudo(có thể tôi sẽ nhận được ENV unix khác nhau khi sudo-ing vì vậy GOOS & GOARCH sẽ không khả dụng nếu chúng không được thực hiện nội tuyến)
ljgww

re: jdi - Tôi chỉ cố gắng biên dịch ứng dụng "mockup" của mình thành win / lin nhị phân trên mac, nhưng để làm được điều đó, tôi đã phải tự xây dựng cho mỗi kết hợp nền tảng / bộ xử lý. (chưa thể trả lời câu hỏi của riêng tôi - chưa có đủ danh tiếng ở đây)
ljgww

1
Bạn đã gõ chính xác những gì nó nói trong ví dụ? CGO_ENABLED=0 GOOS=windows GOARCH=amd64 ./make.bash- nếu bạn đã cố chia nó thành nhiều dòng thì biến môi trường sẽ không được xuất ra phù hợp với các triệu chứng
Nick Craig-Wood

Hãy chắc chắn rằng bạn không nhầm lẫn máy chủ và kiến ​​trúc đích. Bạn sẽ thấy đầu ra này: "# Trình biên dịch xây dựng và công cụ bootstrap cho máy chủ, darwin / amd64." "# Xây dựng gói và lệnh cho máy chủ, darwin / amd64." "# Xây dựng gói và lệnh cho windows / 386."
Sam

Câu trả lời:


157

Với Go 1.5 dường như họ đã cải thiện quá trình biên dịch chéo, có nghĩa là nó được xây dựng ngay bây giờ. Không ./make.bash-ing hoặc brew-ing yêu cầu. Quá trình này được mô tả ở đây nhưng đối với TLDR-ers (như tôi) ra khỏi đó: bạn chỉ cần thiết lập GOOSvà các GOARCHbiến môi trường và chạy đi xây dựng.

Đối với những người sao chép thậm chí lười biếng hơn (như tôi) ngoài kia, hãy làm điều gì đó như thế này nếu bạn đang sử dụng hệ thống * nix:

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

Bạn thậm chí đã học được envmẹo, cho phép bạn chỉ đặt các biến môi trường cho lệnh đó, hoàn toàn miễn phí.


4
Các envlệnh chạy duy nhất mà cuộc gọi trong một môi trường tùy chỉnh và 'reset' nó sau khi nó được thực hiện. Ví dụ chạy export GOOS=windows, sau đó lệnh có hoặc không có envecho $GOOSsau đó. Với envGOOS đã không thay đổi.
leondepeon

3
điều tương tự cũng đúng (ít nhất là trong Bash) mà không có env. Tôi chạy export GOOS=windowsrồi GOOS=linux bash -c 'echo "GOOS: $GOOS"'sau đó echo "GOOS: $GOOS". Liệu envcung cấp khả năng tương thích cao hơn với các phương ngữ vỏ khác hoặc với các nền tảng khác? Nếu không nó có vẻ thừa ở đây.
davidchambers

2
@davidchambers Trong BASH chúng tương đương nhau. Mặc dù trong một số Shell khác, ví dụ như vỏ FISH, nó không hỗ trợ FOO=bar cmd, vì vậy bạn phải sử dụng env FOO=bar cmd. Do đó tôi nghĩ lợi thế lớn nhất để sử dụng env FOO=bar cmdlà khả năng tương thích.
PickBoy

1
Câu trả lời đáng kinh ngạc ngay tại đây. Bạn đã giải quyết vấn đề của tôi, dạy cho tôi một mẹo mới và khiến tôi cười thầm với chính mình.
T Trống

1
Câu trả lời tuyệt vời, cảm ơn bạn! Để biên dịch để sử dụng trên heroku (intel x86), tôi đã sửa đổi một chút dòng này env GOOS=linux GOARCH=386 go build -v github.com/path/to/your/appvà nó hoạt động giống như một nhà vô địch
Ira Herman

136

Nhờ sự giúp đỡ tử tế và kiên nhẫn từ hạt golang, công thức là như sau:

1) Người ta cần biên dịch trình biên dịch Go cho các nền tảng và kiến ​​trúc đích khác nhau. Điều này được thực hiện từ thư mục src trong cài đặt đi. Trong trường hợp của tôi, cài đặt Go được đặt trong /usr/local/gođó để biên dịch trình biên dịch bạn cần phát hànhmake tiện ích. Trước khi làm điều này bạn cần biết một số hãy cẩn thận.

Có một vấn đề về thư viện CGO khi biên dịch chéo vì vậy cần phải vô hiệu hóa thư viện CGO.

Quá trình biên dịch được thực hiện bằng cách thay đổi vị trí thành thư mục nguồn, vì việc biên dịch phải được thực hiện trong thư mục đó

cd /usr/local/go/src

sau đó biên dịch trình biên dịch Go:

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

Bạn cần lặp lại bước này cho từng HĐH và Kiến trúc mà bạn muốn biên dịch chéo bằng cách thay đổi các tham số GOOS và GOARCH.

Nếu bạn đang làm việc trong chế độ người dùng như tôi, sudo là cần thiết bởi vì trình biên dịch Go nằm trong thư mục hệ thống. Nếu không, bạn cần phải đăng nhập như siêu người dùng. Trên Mac, bạn có thể cần bật / cấu hình quyền truy cập SU (mặc định không có sẵn), nhưng nếu bạn đã quản lý để cài đặt Go, bạn có thể đã có quyền truy cập root.

2) Khi bạn đã xây dựng tất cả các trình biên dịch chéo, bạn có thể vui vẻ biên dịch chéo ứng dụng của mình bằng cách sử dụng các cài đặt sau chẳng hạn:

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

Thay đổi GOOS và GOARCH thành các mục tiêu bạn muốn xây dựng.

Nếu bạn gặp sự cố với CGO, hãy bao gồm CGO_ENABLED = 0 trong dòng lệnh. Cũng lưu ý rằng các tệp nhị phân cho linux và mac không có phần mở rộng để bạn có thể thêm phần mở rộng vì mục đích có các tệp khác nhau. -o switch hướng dẫn Đi để tạo tệp đầu ra tương tự như trình biên dịch cũ cho c / c ++, do đó, appname.linux được sử dụng có thể là bất kỳ tiện ích mở rộng nào khác.


Điều ban đầu làm tôi bối rối là trong phần đầu tiên của quá trình biên dịch, hãy nói: # Building compilers and Go bootstrap tool for host, darwin/amd64nhưng sau đó, nó thực sự kết thúc như sau: --- Installed Go for windows/386 in /usr/local/go Installed commands in /usr/local/go/binvì vậy người ta sẽ quan sát kết thúc thay vì bắt đầu biên dịch trình biên dịch.
ljgww

mọi thứ bắt đầu bằng cách cố gắng làm: $ GOARCH=386 GOOS=linux go build app.govà nhận lỗi # 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
Gói của Go trong Homebrew có tùy chọn "--cross-compile-all" sẽ tự động xây dựng tất cả các trình biên dịch chéo.
nimrodm

8
mẹo tuyệt vời @nimrodm! để biên dịch lại cài đặt đi của bạn, bạn cần chạybrew reinstall go --cross-compile-all
linqu

1
@ljgww 'sudo' không được cấu hình ENV. Tôi đã kết thúc bằng cách sử dụng chown on / usr / local / go / pkg / linux_amd64 /
Nuno Silva

63

Nếu bạn sử dụng Homebrew trên OS X, thì bạn có một giải pháp đơn giản hơn:

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

hoặc là..

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

Sử dụng reinstallnếu bạn đã gocài đặt.


3
Lưu ý các công tắc được cập nhật là: --cross-compile-all Xây dựng trình biên dịch chéo và hỗ trợ thời gian chạy cho tất cả các nền tảng được hỗ trợ --cross-compile-common Xây dựng trình biên dịch chéo và hỗ trợ thời gian chạy cho darwin, linux và windows
Chip Tol

3
--cross-compile-allbây giờ--with-cc-all
gianebao

@ sheek06 - đã sửa. Cảm ơn!
docwhat

1
Những lá cờ không còn tồn tại từ những gì tôi có thể nói. Tùy chọn duy nhất có liên quan mà tôi thấy là --without-cgo :(
ndegges

5
Kể từ Go 1.5, không có trình biên dịch chéo riêng biệt, bạn chỉ sử dụng các cờ bây giờ tip.golang.org/doc/go1.5#compiler_and_tools
chuckus

24

Bạn có thể làm điều này khá dễ dàng bằng cách sử dụng Docker, vì vậy không cần thêm libs. Chỉ cần chạy lệnh này:

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
'

Bạn có thể tìm thêm chi tiết trong bài đăng này: https://medium.com/iron-io-blog/how-to-cross-compile-go-programs-USE-docker-beaa102a316d


1
Tại sao bất cứ ai cũng muốn cài đặt Docker để làm điều này khi họ chỉ có thể thực hiện một vòng lặp shell env GOOS=x GOARCH=y go install something/...và kết thúc với các nhị phân thích hợp bên dưới $GOPATH/bin/$GOOS_$GOARCH?? Và BTW, Go hỗ trợ nhiều hơn ba hệ điều hành bạn liệt kê, tại sao không có tình yêu dành cho BSD?
Dave C

8
Bạn sẽ không cài đặt Docker chỉ để làm điều này, nhưng nếu bạn có nó, việc này dễ dàng và sạch sẽ hơn các giải pháp thay thế.
Travis Reeder

7

Quá trình tạo các tệp thực thi cho nhiều nền tảng có thể hơi tẻ nhạt, vì vậy tôi khuyên bạn nên sử dụng một tập lệnh:

#!/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

Tôi chỉ kiểm tra tập lệnh này trên OSX

ý chính - go-executable-build.sh


Chính xác những gì tôi đang tìm kiếm ... Tôi đã cập bến nó :) gist.github.com/marcellodesales/ Khăn
Marcello de Sales

6

dành cho những người cần kích hoạt CGO và biên dịch chéo từ các cửa sổ nhắm mục tiêu OSX

Tôi cần kích hoạt CGO trong khi biên dịch cho windows từ máy Mac của mình vì tôi đã nhập https://github.com/mattn/go-sqlite3 và nó cần nó. Biên dịch theo các câu trả lời khác đã cho tôi và lỗi:

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

Nếu bạn giống tôi và bạn phải biên dịch với CGO. Đây là những gì tôi đã làm:

1. Chúng tôi sẽ biên dịch chéo cho các cửa sổ với thư viện phụ thuộc CGO. Đầu tiên chúng ta cần một trình biên dịch chéo được cài đặt nhưmingw-w64

brew install mingw-w64

Điều này có thể sẽ cài đặt nó ở đây /usr/local/opt/mingw-w64/bin/ .

2.Chỉ cần các câu trả lời khác, trước tiên chúng ta cần thêm vòm cửa sổ vào chuỗi công cụ biên dịch đi của chúng tôi ngay bây giờ. Biên dịch một trình biên dịch cần một trình biên dịch (câu lạ) biên dịch đi trình biên dịch cần một trình biên dịch dựng sẵn riêng biệt. Chúng tôi có thể tải xuống tệp nhị phân dựng sẵn hoặc xây dựng từ nguồn trong thư mục, ví dụ: ~/Documents/go bây giờ chúng tôi có thể cải thiện trình biên dịch Go của mình, theo câu trả lời hàng đầu nhưng lần này với CGO_ENABLED=1và trình biên dịch dựng sẵn riêng biệt GOROOT_BOOTSTRAP(Pooya là tên người dùng của tôi):

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.Bây giờ trong khi biên dịch sử dụng mã Go của chúng tôi mingwđể biên dịch các cửa sổ nhắm mục tiêu tệp đi của chúng tôi với CGO được bật:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.