duanji1026 2019-04-05 10:00
浏览 35

如何快速构建/安装交叉编译的嵌套包?

I have a repository with a group of nested go packages organized as follows:

$GOPATH/src/
  - mypackage/common/utils.go
  - mypackage/app1/main.go
  - mypackage/app2/main.go
  ...

It compiles to a handful of binaries. For releasing, I'm cross-compiling for a multitude of platforms/archs (I deploy repeatedly with a different GOOS and GOARCH). I'm trying to write the compilation results to a directory of my choice, but I'm fighting with the toolchain.

I can:

  1. Combine GOBIN and go install when compiling for my own architecture (i.e. not cross compiling):

    # build + output all binaries in /somedir/bin
    # this works great when compiling for my local architecture.
    GOBIN=/somedir/bin go install mypackage/app1 mypackage/app2 mypackage/app3
    

    But unfortunately, GOBIN conflicts with cross-compilation e.g:

    # Throws: "cannot install cross-compiled binaries when GOBIN is set"
    GOBIN=/somedir/bin GOARCH=amdm64 GOOS=darwin go install mypackage/app1 mypackage/app2
    
  2. Use go build with GOOS=X and GOARCH=Y for each subpackage

    # cross compile one of the binaries
    cd /output/darwin-386-bin/ && \
    GOOS=darwin GOARCH=386 go build mypackage/app1
    
    # but if given multiple binaries, there is no output. (as documented)
    GOOS=darwin GOARCH=386 go build mypackage/app1 mypackage/app2
    

    When go build is given multiple packages, it no longer emits binaries -- it just checks that the code compiles. To emit all the binaries, it seems I have to run go build once for each subpackage, so it takes longer, esp when building with -a.

    Another possible issue with using go build like this, is that it's potentially mixing binaries and intermediary results across multiple architectures in the same workspace. But maybe that's just a matter of taste. Hopefully the toolchain keeps cached results separate for different architectures.

How is this handled in practice? Should I treat each subpackage as an individual package, despite their shared common code (would it then be safe to build them all in parallel)?

Related articles:

  • 写回答

1条回答 默认 最新

  • dongpo1846 2019-04-05 10:06
    关注

    What I'm about to suggest feels like a hack at best, but it might work for you if you're cross-compiling stuff in a container or an isolated build environment.

    You can drop the GOBIN from the install command:

    # I'm not on this platform, so this is a cross compile
    GOOS=darwin GOARCH=amd64 go install mypackage/app1 mypackage/app2
    

    Assuming your package is in $GOPATH/src/mypackage the above command will install the two binaries to:

    $GOPATH/bin/darwin_amd64/{app1, app2}
    

    and the .a compile dependency files in:

    $GOPATH/pkg/darwin_amd64/mypackage/{app1,app2,common}
    

    If you're running this in a for loop for all the platforms you plan on supporting, one nuisance with this process is that when you pass GOOS=x GOARCH=y matching your local architecture (i.e. not cross compiling), then the executables will be placed directly in $GOPATH/bin/ and not $GOPATH/bin/x_y/.

    (packages on the other hand always end up in $GOPATH/pkg/x_y/, cross compilation or not).

    To determine your local architecture, you can follow steps in this answer: https://stackoverflow.com/a/35669816/5556676 .

    Simulating GOBIN=/foo/bin GOOS=x GOARCH=y go install mypackage/app{1,2,3}

    Changing $GOPATH has little effect on where go install writes output. With some go commands, like go get, you tweak where packages are installed by adding a new component at the front of $GOPATH. But in go 1.9, go install will always copy binaries in the bin/ folder that's a sibling of the src/ which contains the packages to install.

    Instead of using GOBIN=/foo/bin, you can pretend your source files are in /foo/src/mypackage (you may use a symlink), and then do GOPATH=/foo GOOS=x GOARCH=y go install mypackage/app{1,2,3}. This will put binaries in /foo/bin, because of the behavior I describe in the previous paragraph.

    It's probably simpler to just grab the binaries from where you expect them to be though, than mucking with copying source trees around.

    评论

报告相同问题?

悬赏问题

  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?