Перекрестная компиляция Перейти на OSX?

Я пытаюсь перекрестно скомпилировать приложение go на OSX для создания двоичных файлов для windows и linux. Я прочитал все, что мог найти в сети. Самый близкий пример, который я нашел, был опубликован (помимо многих незавершенных обсуждений в списке рассылки орехов):

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

пока он не работает при моей установке. Я иду 1.0.2. Поскольку 1.0.2 довольно недавно, мне кажется, что все приведенные выше примеры не относятся к этой версии.

Пытался сделать ./make.bash --no-clean с ENV vars, установленным на 386/windows, он строит go, однако он строит для моей установки, которая является darwin/amd64, и полностью игнорирует то, что установлено в ENV, что предполагает создание другого компилятора.

Кто-нибудь советует, как это можно сделать (если это вообще можно сделать)?

Ответ 1

С Go 1.5 они, похоже, улучшили процесс кросс-компиляции, то есть теперь он встроен. Нет необходимости ./make.bash -ing или brew. Этот процесс описан здесь, но для TL;DR-ers (например, я): вы просто устанавливаете переменные среды GOOS и GOARCH и запускаете построить.

Для даже более ленивых копировальных пастеров (таких как я), сделайте что-нибудь подобное, если вы находитесь в системе * nix:

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

Вы даже узнали трюк env, который позволяет вам устанавливать только переменные среды только для этой команды.

Ответ 2

Благодаря доброжелательной и терпеливой помощи от голанг-орехов, рецепт следующий:

1) Нужно скомпилировать компилятор Go для разных целевых платформ и архитектур. Это делается из папки src в go. В моем случае установка Go находится в /usr/local/go чтобы скомпилировать компилятор, который вам нужно выпустить make utility. Прежде чем делать это, вам нужно знать некоторые оговорки.

Существует проблема с библиотекой CGO при кросс-компиляции, поэтому необходимо отключить библиотеку CGO.

Компиляция выполняется путем изменения местоположения в исходном каталоге, поскольку компиляция должна выполняться в этой папке

cd /usr/local/go/src

затем скомпилируйте компилятор Go:

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

Вам нужно повторить этот шаг для каждой ОС и архитектуры, которую вы хотите перекрестно скомпилировать, изменив параметры GOOS и GOARCH.

Если вы работаете в пользовательском режиме, как и я, sudo необходим, потому что компилятор Go находится в системном каталоге. В противном случае вам необходимо войти в систему как суперпользователь. На Mac вам может потребоваться включить/настроить SU-доступ (по умолчанию он недоступен), но если вам удалось установить Go, возможно, у вас уже есть root-доступ.

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 switch указывает, чтобы сделать выходной файл похожим на старые компиляторы для c/c++, поэтому выше используемого appname.linux может быть любое другое расширение.

Ответ 3

Если вы используете Homebrew в OS X, тогда у вас есть более простое решение:

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

или..

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

Используйте reinstall, если у вас уже установлен go.

Ответ 4

Вы можете сделать это довольно легко, используя Docker, поэтому никаких дополнительных libs не требуется. Просто запустите эту команду:

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

Ответ 5

для людей, которым требуется CGO, и перекрестная компиляция из таргетинга OSX окна

Мне понадобилось CGO при компиляции для окон с моего mac, так как я импортировал 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. Компиляция компилятора требует компилятора (странного предложения) компиляции 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, используйте mingw, чтобы скомпилировать наши окна таргетинга файлов с включенным CGO:

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

Ответ 6

Процесс создания исполняемых файлов для многих платформ может быть немного утомительным, поэтому я предлагаю использовать скрипт:

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

gist - go-executable-build.sh