首页 文章

交叉编译Go OSX?

提问于
浏览
120

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

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

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

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

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

6 回答

  • 19

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

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

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

    您甚至学会了 env 技巧,它允许您只为该命令设置环境变量,完全免费 .

  • 63

    感谢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可以是任何其他扩展名 .

  • 2

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

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

    要么..

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

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

  • 113

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

  • 134

    对于需要启用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
    

    如果你像我一样,你必须用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

    为许多平台创建可执行文件的过程可以是a有点乏味,所以我建议使用一个脚本:

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

相关问题