Перекрестная компиляция Перейти на 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