web-dev-qa-db-fra.com

Compilation croisée Allez sur OSX?

J'essaie de compiler de manière croisée une application sur OSX pour créer des fichiers binaires pour Windows et Linux. J'ai tout lu sur ce que j'ai pu trouver sur le net. L'exemple le plus proche que j'ai trouvé a été publié (à part de nombreuses discussions inachevées sur la liste de diffusion Go-Nuts):

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

mais cela ne fonctionne pas sur mon installation. J'ai aller 1.0.2. Comme la version 1.0.2 est récente, il me semble que tous les exemples ci-dessus ne s'appliquent pas à cette version.

Essayé de faire ./make.bash --no-clean avec ENV vars défini sur 386/windows, sa construction est terminée, mais sa construction est utilisée pour mon installation qui est darwin/AMD64 et ignore complètement ce qui est défini dans ENV qui suppose de construire un compilateur différent.

Tout conseille comment cela peut être fait (si cela peut être fait du tout)?

127
ljgww

Avec Go 1.5, ils semblent avoir amélioré le processus de compilation croisée, ce qui signifie qu’il est désormais intégré. Non ./make.bashing ou brewing requis. Le processus est décrit ici mais pour les variables TLDR (comme moi): vous venez de définir les variables d'environnement GOOS et GOARCH, puis d'exécuter la compilation .

Pour les copieurs-pasteurs encore plus paresseux (comme moi), faites quelque chose comme ceci si vous êtes sur un système * nix:

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

Vous avez même appris l'astuce env, qui vous permet de définir des variables d'environnement uniquement pour cette commande, de manière totalement gratuite.

127
leondepeon

Grâce à l'aide aimable et patiente des noix de golang, la recette est la suivante:

1) Il faut compiler Go compilateur pour différentes plates-formes et architectures cibles. Cela se fait depuis le dossier src lors de l'installation. Dans mon cas, l'installation de Go se trouve dans /usr/local/go donc pour compiler un compilateur, vous devez lancer l'utilitaire make. Avant de faire cela, vous devez savoir certaines mises en garde.

Il y a un problème avec la bibliothèque CGO lors de la compilation croisée. Il est donc nécessaire de désactiver la bibliothèque CGO.

La compilation se fait en changeant d'emplacement en répertoire source, car la compilation doit être faite dans ce dossier

cd /usr/local/go/src

puis compilez le compilateur Go:

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

Vous devez répéter cette étape pour chaque système d'exploitation et chaque architecture que vous souhaitez compiler en modifiant les paramètres GOOS et GOARCH.

Si vous travaillez en mode utilisateur comme je le fais, Sudo est nécessaire car le compilateur Go est dans le répertoire système. Sinon, vous devez être connecté en tant que super utilisateur. Sur Mac, vous devrez peut-être activer/configurer l’accès au SU (il n’est pas disponible par défaut), mais si vous avez réussi à installer Go, vous avez peut-être déjà un accès root.

2) Une fois tous les compilateurs créés, vous pouvez facilement compiler votre application en utilisant les paramètres suivants, par exemple:

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

Changez le GOOS et GOARCH en cibles que vous souhaitez construire.

Si vous rencontrez des problèmes avec CGO, incluez CGO_ENABLED = 0 dans la ligne de commande. Notez également que les fichiers binaires pour Linux et mac n’ont pas d’extension. Vous pouvez donc ajouter une extension pour avoir des fichiers différents. L'option -o indique à Go de rendre le fichier de sortie similaire aux anciens compilateurs pour c/c ++. Ainsi, appname.linux utilisé ci-dessus peut être une autre extension.

134
ljgww

Si vous utilisez Homebrew sur OS X, vous avez une solution plus simple:

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

ou..

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

Utilisez reinstall si vous avez déjà installé go.

63
docwhat

Vous pouvez le faire assez facilement avec Docker, aucune librairie supplémentaire n’est donc requise. Il suffit de lancer cette commande:

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
'

Vous pouvez trouver plus de détails dans ce post: https://medium.com/iron-io-blog/how-to-cross-compile-go-programs-using-docker-beaa102a316d

21
Travis Reeder

pour les personnes qui ont besoin de [~ # ~] cgo [~ # ~] et d'une compilation croisée à partir de fenêtres de ciblage OSX

J'avais besoin de [~ # ~] cgo [~ # ~] activé lors de la compilation Windows de mon Mac depuis que j'avais importé le https: //github.com/mattn/go-sqlite et il en avait besoin. Compiler selon d'autres réponses m'a donné et erreur:

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

Si vous êtes comme moi et que vous devez compiler avec CGO. C'est ce que j'ai fait:

1.Nous allons effectuer une compilation croisée pour Windows avec une bibliothèque dépendant de CGO. Nous avons d’abord besoin d’un compilateur croisé installé comme mingw-w64

brew install mingw-w64

Cela l'installera probablement ici /usr/local/opt/mingw-w64/bin/.

2.Comme d’autres réponses, nous devons d’abord ajouter notre fenêtre Windows Arch à notre chaîne d’outils de compilation maintenant. La compilation d'un compilateur nécessite un compilateur (phrase bizarre) pour la compilation, le compilateur nécessite un compilateur pré-construit séparé. Nous pouvons télécharger un binaire pré-construit ou construire à partir du source dans un dossier, par exemple: ~/Documents/go maintenant nous pouvons améliorer notre compilateur Go, selon la réponse la plus fréquente, mais cette fois avec CGO_ENABLED=1 et notre compilateur séparé pré-construit GOROOT_BOOTSTRAP _ (Pooya est mon nom d'utilisateur):

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.Maintenant, lors de la compilation de notre code Go, utilisez mingw pour compiler nos fenêtres de ciblage de fichiers Go avec CGO activé:

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
5
Pouya Sanooei

Le processus de création d’exécutables pour de nombreuses plateformes peut être un peu fastidieux, je suggère donc d’utiliser un script:

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

J'ai vérifié ce script sur OSX uniquement

Gist - go-executable-build.sh

5
Dima Kozhevin