交叉编译Go OSX?

时间:2012-08-28 23:16:30

标签: go compilation cross-compiling

我正在尝试在OSX上交叉编译一个go app来为windows和linux构建二进制文件。我已经阅读了网上可以找到的所有内容。我发现的最近的例子已经发表(除了许多关于坚果邮件列表的未完成的讨论):

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

但它对我的安装无效。我去了1.0.2。由于1.0.2是最新版本,因此我认为以上所有示例都不适用于此版本。

尝试使用设置为386 / windows的ENV vars进行./make.bash --no-clean,它确实构建了go,但是它的构建用于我的darwin/amd64安装并且完全忽略在ENV中设置的假设构建不同的编译器。

有人建议如何做(如果可以的话)?

6 个答案:

答案 0 :(得分:134)

感谢golang-nuts的亲切和耐心的帮助,配方如下:

1)需要针对不同的目标平台和体系结构编译Go编译器。这是在go安装中从src文件夹完成的。在我的案例中,Go安装位于/usr/local/go,因此编译需要发出make实用程序的编译器。在此之前,您需要了解一些注意事项。

交叉编译时存在关于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指示Go为c / c ++制作类似于旧编译器的输出文件,因此上面使用的appname.linux可以是任何其他扩展。

答案 1 :(得分:119)

使用Go 1.5,它们似乎改进了交叉编译过程,这意味着它现在已经内置。无需lines = [] with open("ABC.txt","r") as filein: for line in filein: lines.append(line.strip('\n')) print lines - 或./make.bash。该过程描述为here但对于TLDR-ers(像我一样):您只需设置brewGOOS环境变量并运行go build。

对于那些更加懒散的复制贴纸(像我一样),如果你在* nix系统上做这样的事情:

GOARCH

您甚至学会了env GOOS=linux GOARCH=arm go build -v github.com/path/to/your/app 技巧,它只允许您为该命令设置环境变量,完全免费。

答案 2 :(得分:63)

如果您在OS X上使用Homebrew,那么您可以使用更简单的解决方案:

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

或..

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

如果您已安装reinstall,请使用go

答案 3 :(得分:19)

您可以使用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

答案 4 :(得分:5)

  

适用于需要启用 CGO 并从OSX定位交叉编译的人员   窗

我需要 CGO 启用,因为我导入https://github.com/mattn/go-sqlite3并且需要它,因此从我的mac编译窗口时。 根据其他答案编译给了我和错误:

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

如果你像我一样,你必须用CGO编译。这就是我所做的:

1.我们将使用CGO依赖库交叉编译windows。首先,我们需要安装像mingw-w64

这样的交叉编译器
brew install mingw-w64

这可能会在/usr/local/opt/mingw-w64/bin/安装。

2.就像其他答案一样,我们首先需要将windows arch添加到我们的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的go文件定位窗口:

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 :(得分:3)

为许多平台创建可执行文件的过程可能有点乏味,因此我建议使用脚本:

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