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


142

Я намагаюсь перехресно скласти додаток go на OSX для створення бінарних файлів для Windows та Linux. Я прочитав усе, що міг знайти в мережі. Найближчий приклад, який я знайшов, був опублікований (окрім багатьох незавершених дискусій у списку розсилки go-nuts):

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

але це не працює на моїй установці. Я маю йти 1.0.2. Оскільки 1.0.2 зовсім недавно, мені здається, що всі наведені вище приклади не стосуються цієї версії.

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

Хтось радить, як це можна зробити (якщо це взагалі можна зробити)?


Паралельно з цим я задав те саме питання у списку розсилки голанг-горіхів, і за доброї допомоги та терпіння людей там приготували остаточний рецепт ... це тема дискусії: groups.google.com/forum/?fromgroups=# ! тема / голанг-горіхи /… було кілька кроків та висновків, я помилився в дорозі, але зараз рецепт здається досить простим - 3 кроки та кілька ітерацій.
ljgww

Тепер, коли я переглядаю резюме, я замислююся над тим, чому ENV vars не запустив правильну компіляцію - можливо, тому що я це зробив sudo(швидше за все, я отримаю різні unix ENV, коли sudo-ing, тому GOOS & GOARCH не будуть доступні, якщо вони не будуть зроблені inline)
ljgww

re: jdi - Я просто намагався скласти свою програму "макет" go, щоб виграти / lin бінарні файли на mac, але для цього мені довелося будувати перехід для кожної комбінації платформи / процесора. (поки не можу відповісти на моє запитання - маючи тут недостатньо репутації)
ljgww

1
Ви ввели саме те, що сказано в прикладі? CGO_ENABLED=0 GOOS=windows GOARCH=amd64 ./make.bash- якщо ви намагалися розділити його на кілька рядків, змінна середовища не експортується, що відповідає симптомам
Нік Крейг-Вуд

Переконайтеся, що ви не плутаєте архітектуру хостів і цілей. Ви повинні побачити такий результат: "# Компіляція побудови та інструмент" Завантажити завантаження "для хоста, darwin / amd64." "# Побудова пакунків та команд для хоста, darwin / amd64." "# Побудова пакунків та команд для windows / 386."
Сем

Відповіді:


157

З Go 1.5 вони, схоже, покращили процес крос-компіляції, тобто він вбудований зараз. Ніякого необхідності ./make.bashчи brewнеобхідності. Процес описаний тут , але для TLDR-рів (як я) там: ви просто встановити GOOSі GOARCHзмінні оточення і запуск йде збирання.

Для рівних лазерних копіювальних пастерів (як я) там зробіть щось подібне, якщо ви перебуваєте в системі * nix:

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

Ви навіть навчилися envхитрості, яка дозволила вам встановлювати змінні середовища лише для цієї команди, абсолютно безкоштовно.


4
У envкоманді виконується тільки , що виклик в призначеній для користувача середовищі , і «скидає» це після того, як це робиться. Наприклад, запустіть export GOOS=windows, потім команда з або без envі echo $GOOSпісля. З envGOOS не змінився.
leondepeon

3
те ж саме (принаймні, у Баша) без env. Я побіг , export GOOS=windowsто GOOS=linux bash -c 'echo "GOOS: $GOOS"'потім echo "GOOS: $GOOS". Чи envзабезпечує більша сумісність з іншими діалектами оболонок або з іншими платформами? Якщо ні, то тут здається зайвим.
davidchambers

2
@davidchambers У BASH вони рівноцінні. Перебуваючи в іншій оболонці, наприклад, FISH shell, вона не підтримує FOO=bar cmd, тому вам доведеться використовувати env FOO=bar cmd. Тому я думаю, що найбільшою перевагою використання env FOO=bar cmdє сумісність.
PickBoy

1
Неймовірна відповідь тут. Ви вирішили мою проблему, навчили мене новій хитрість і змусили мене посміхнутися.
T Пустий

1
Чудова відповідь, дякую! Для того, щоб компілювати для використання на heroku (intel x86), я трохи змінив лінійку, env GOOS=linux GOARCH=386 go build -v github.com/path/to/your/appі вона працює на зразок чемпіона
Іра Герман

136

Завдяки доброї та терплячої допомоги голанг-горіхів, рецепт наступний:

1) Потрібно скласти компілятор Go для різних цільових платформ та архітектур. Це робиться з папки src при установці go. У моєму випадку інсталяція Go розміщена в, /usr/local/goтаким чином, щоб скласти компілятор, вам потрібно випустити makeутиліту. Перш ніж це зробити, потрібно знати деякі застереження.

Існує проблема з бібліотекою CGO при перехресному компілюванні, тому потрібно відключити бібліотеку CGO.

Компіляція проводиться шляхом зміни місця розташування на вихідний dir, оскільки компіляція повинна здійснюватися в цій папці

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, можливо, ви вже маєте кореневий доступ.

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 може бути будь-яким іншим розширенням.


Спочатку мене бентежило те, що в першій частині компіляції make говорить: # 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
У пакеті Go на Homebrew є опція "--cross-compile-all", яка автоматично будує всі крос-компілятори.
nimrodm

8
чудова порада @nimrodm! щоб перекомпілювати свою установку go, потрібно запуститиbrew reinstall go --cross-compile-all
linqu

1
@ljgww 'sudo' не налаштовано ENV. Я в кінцевому рахунку використовував chown on / usr / local / go / pkg / linux_amd64 /
Nuno Silva

63

Якщо ви використовуєте 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встановили.


3
Відзначаючи оновлені перемикачі: опції -cross-компіляції все збірки крос-компілятори і підтримка виконання для всіх підтримуваних платформ опції -cross-компіляції загального побудувати крос-компіляторів і підтримки виконання Дарвіну, Linux і вікна
Chip Тол

3
--cross-compile-allзараз--with-cc-all
gianebao

@ sheeks06 - виправлено. Дякую!
док

1
Ці прапори вже не існують із того, що я можу сказати. Єдиний відповідний варіант, який я бачу, це --without-cgo :(
rdegges

5
Оскільки Go 1.5 не існує окремих крос-компіляторів, ви використовуєте лише прапори зараз tip.golang.org/doc/go1.5#compiler_and_tools
chuckus

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 підтримує більше трьох перерахованих вами ОС, чому б не любити BSD?
Дейв С

8
Ви б не встановили Docker просто для цього, але якщо у вас є, це простіше і чіткіше, ніж альтернативи.
Тревіс Редер

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

gist - go-executable-build.sh


Точно те, що я шукав ... я докерізував це :) gist.github.com/marcellodesales/…
Marcello de Sales

6

для людей, яким потрібна підтримка CGO та перехресна компіляція з ОС Windows, орієнтована на націлювання

Мені була потрібна підтримка CGO під час компіляції для Windows з мого 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.Ми збираємося перетнути компіляцію для Windows із залежною від CGO бібліотекою. Спочатку нам потрібен крос-компілятор, встановлений на зразокmingw-w64

brew install mingw-w64

Це, ймовірно, буде встановлено тут /usr/local/opt/mingw-w64/bin/.

2. Як і інші відповіді, нам спочатку потрібно додати арку Windows до нашого інструментального інструмента компілятора 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для збирання вікон, орієнтованих на файл go з увімкненою 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.