交叉编译Go OSX?

ljg*_*gww 129 compilation cross-compiling go

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

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

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

尝试将./make.bash --no-cleanENV变量设置为386/windows,它确实构建了go,但它构建用于我的安装,这darwin/amd64完全忽略了ENV中设置的构建不同编译器的内容.

有人建议如何做(如果可以完成)?

leo*_*eon 138

使用Go 1.5,它们似乎改进了交叉编译过程,这意味着它现在已经内置.不需要./make.bashbrew不需要.这里描述这个过程,但对于TLDR-ers(像我一样):你只需设置GOOSGOARCH环境变量并运行go build.

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

env GOOS=linux GOARCH=arm go build -v github.com/path/to/your/app
Run Code Online (Sandbox Code Playgroud)

你甚至学会了这个env技巧,它让你只为该命令设置环境变量,完全免费.

  • `env`命令仅在自定义环境中运行该调用,并在完成后'重置'它.例如,运行`export GOOS = windows`,然后运行带或不带`env`和`echo $ GOOS`的命令.使用`env`,GOOS没有改变. (4认同)
  • 没有"env"的情况也是如此(至少在Bash中).我运行`export GOOS = windows`然后`GOOS = linux bash -c'echo"GOOS:$ GOOS"'```echo"GOOS:$ GOOS"`.`env`是否与其他shell方言或其他平台提供更好的兼容性?如果不是这里似乎是多余的. (3认同)
  • @davidchambers在BASH中它们是等价的.而在其他一些Shell中,例如FISH shell,它不支持`FOO = bar cmd`,所以你必须使用`env FOO = bar cmd`.因此我认为使用`env FOO = bar cmd`的最大优点是兼容性. (2认同)

ljg*_*gww 136

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

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

交叉编译时存在关于CGO库的问题,因此需要禁用CGO库.

编译是通过将位置更改为源目录来完成的,因为编译必须在该文件夹中完成

cd /usr/local/go/src
Run Code Online (Sandbox Code Playgroud)

然后编译Go编译器:

sudo GOOS=windows GOARCH=386 CGO_ENABLED=0 ./make.bash --no-clean
Run Code Online (Sandbox Code Playgroud)

您需要通过更改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
Run Code Online (Sandbox Code Playgroud)

将GOOS和GOARCH更改为您要构建的目标.

如果您遇到CGO问题,请在命令行中包含CGO_ENABLED = 0.另请注意,linux和mac的二进制文件没有扩展名,因此您可以为了拥有不同的文件而添加扩展名.-o开关指示Go使输出文件类似于c/c ++的旧编译器,因此上面使用的appname.linux可以是任何其他扩展.

  • Homebrew中的Go包有一个选项"--cross-compile-all",它将自动构建所有交叉编译器. (29认同)
  • 很棒的提示@nimrodm!要重新编译你的go安装,你需要运行`brew重新安装go --cross-compile-all` (7认同)

doc*_*hat 63

如果你在OS X上使用Homebrew,那么你有一个更简单的解决方案:

$ brew install go --with-cc-common # Linux, Darwin, and Windows
Run Code Online (Sandbox Code Playgroud)

要么..

$ brew install go --with-cc-all # All the cross-compilers
Run Code Online (Sandbox Code Playgroud)

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

  • 从Go 1.5开始,没有单独的交叉编译器,你现在只使用标志https://tip.golang.org/doc/go1.5#compiler_and_tools (4认同)
  • 注意到更新的开关是:--cross-compile-all为所有支持的平台构建交叉编译器和运行时支持--cross-compile-common为darwin,linux和windows构建交叉编译器和运行时支持 (3认同)
  • `--cross-compile-all`现在是`--with-cc-all` (3认同)

Tra*_*der 22

您可以使用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
'
Run Code Online (Sandbox Code Playgroud)

您可以在以下文章中找到更多详细信息:https: //medium.com/iron-io-blog/how-to-cross-compile-go-programs-using-docker-beaa102a316d

  • 你不会只是为了这样安装Docker,但是如果你拥有它,这比替代方案更容易和更清洁. (7认同)

Dim*_*vin 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
Run Code Online (Sandbox Code Playgroud)

我仅在OSX上检查了此脚本

要点-go-executable-build.sh


Pou*_*oei 5

对于需要启用CGO并从OSX目标窗口进行交叉编译的人员

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

/usr/local/go/src/runtime/cgo/gcc_windows_amd64.c:8:10: fatal error: 'windows.h' file not found
Run Code Online (Sandbox Code Playgroud)

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

1.我们将使用CGO依赖库交叉编译Windows.首先我们需要安装一个交叉编译器mingw-w64

brew install mingw-w64
Run Code Online (Sandbox Code Playgroud)

这可能会在这里安装它/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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)