我正在尝试在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中设置的假设构建不同的编译器。
有人建议如何做(如果可以的话)?
答案 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(像我一样):您只需设置brew
和GOOS
环境变量并运行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上检查了此脚本