Bug 221297

Summary: lang/go: Fix arm build
Product: Ports & Packages Reporter: Hiroki Tagato <tagattie>
Component: Individual Port(s)Assignee: freebsd-ports-bugs (Nobody) <ports-bugs>
Status: Closed FIXED    
Severity: Affects Some People CC: ben, dmgk, freebsd-arm, garga, hsw, hyun, jlaffaye, linimon, mikael, paulzhol, swills, victorhooi
Priority: --- Keywords: easy, needs-qa
Version: LatestFlags: bugzilla: maintainer-feedback? (jlaffaye)
koobs: merge-quarterly?
Hardware: arm   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=205820
https://github.com/golang/go/issues/25770
Attachments:
Description Flags
A patch for Makefile
none
Updated patch
koobs: maintainer-approval+
Build log WITHOUT CGO_ENABLED=1
none
Build log WITH CGO_ENABLED=1
none
Updated patch for the current lang/go
none
Updated patch for the current lang/go v2
none
Updated patch for the current lang/go v3 dmgk: maintainer-approval?

Description Hiroki Tagato freebsd_committer freebsd_triage 2017-08-07 05:45:28 UTC
Created attachment 185109 [details]
A patch for Makefile

Crossbuilding of lang/go (using Poudriere) ends up with the following error:
=======================<phase: package        >============================
===>  Building package for go-1.8.3,1
pkg-static: Unable to access file /wrkdirs/usr/ports/lang/go/work/stage/usr/loca
l/go/pkg/freebsd_arm/runtime/cgo.a:No such file or directory
*** Error code 1

According to the Go source code at https://github.com/golang/go/blob/master/src/go/build/build.go#L307, "cgo must be explicitly enabled for cross compilation builds".

I tried attached the patch and crossbuilding succeeded without an error.
(GOARM=7 is to cope with the bug #205820)

I'm not sure how I can know host arch of crossbuilding (target arch is ${ARCH}), so I just simply put the line there, which should be better only when crossbuilding.

Thanks,
Hiroki Tagato
Comment 1 Hiroki Tagato freebsd_committer freebsd_triage 2017-09-11 11:09:01 UTC
My initial comment "cross-building of go requires explicit GCO_ENABLED=1" was a misconception. It was not a cross-building but an emulated-building (by Poudriere/Qemu user-mode emulation). So please disregard my first comment.

However, explicit "CGO_ENABLED=1" still seems necessary even when native-building.

I tried to build go 1.9 on a Raspberry Pi 2 (11.1-RELEASE) and the build ended up with the following message (The full log is attached go-1.9,1-without-cgo-enabled.log):

====> Checking for pkg-plist issues (check-plist)
===> Parsing plist
===> Checking for items in STAGEDIR missing from pkg-plist
===> Checking for items in pkg-plist which are not in STAGEDIR
Error: Missing: go/pkg/%%opsys_ARCH%%/runtime/cgo.a
===> Error: Plist issues found.
*** Error code 1

Stop.
make: stopped in /usr/ports/lang/go
====>> Error: check-plist failures detected

Applying the patch (lang-go.diff) make the build succeed. The successful build log is go-1.9,1-with-cgo-enabled.log.

P.S. GOARM=7 is also necessary on RPI2 environment.

Thanks,
Hiroki Tagato
Comment 2 Hiroki Tagato freebsd_committer freebsd_triage 2017-09-11 11:10:50 UTC
Created attachment 186252 [details]
Updated patch
Comment 3 Hiroki Tagato freebsd_committer freebsd_triage 2017-09-11 11:11:35 UTC
Created attachment 186253 [details]
Build log WITHOUT CGO_ENABLED=1
Comment 4 Hiroki Tagato freebsd_committer freebsd_triage 2017-09-11 11:12:12 UTC
Created attachment 186254 [details]
Build log WITH CGO_ENABLED=1
Comment 5 Christopher Hall 2017-10-25 03:58:23 UTC
I had to add these environment values to be able to build a working go compiler on RaspberryPi FreeBSD 12.0-CURRENT #0 r323985 2017-09-26 snapshot.
Without the above patch none of the C interface libraries would compile.

During the build of the lang/go14 bootstrap tool I noticed some errors like:
"-t not found"
because its build script has some bash specific code.  I did patch the lang/go14 to use "/usr/local/bin/bash make.bash" before I built go 1.9.  I do not know
if leaving lang/go14 unchanged would produce a working go-1.9.  All compiles were done on Raspberry Pi, no cross compile used.
Comment 6 Mark Linimon freebsd_committer freebsd_triage 2018-03-15 14:48:11 UTC
I can confirm that the GOARM=7 patch is necessary.  I had not seen this PR before, so I came up with the patch independently.  However, my build does fail with a plist error.

I will try it again with the full patch.
Comment 7 Kubilay Kocak freebsd_committer freebsd_triage 2018-08-06 05:28:42 UTC
Comment on attachment 186252 [details]
Updated patch

Approved by: portmgr (maintainer timeout, 11+ months)
Comment 8 Kubilay Kocak freebsd_committer freebsd_triage 2018-08-06 05:29:12 UTC
Open to take
Comment 9 Mikael Urankar freebsd_committer freebsd_triage 2018-08-06 06:57:56 UTC
fwiw, mmel@ has a patch: http://build.humusoft.cz/patches/lang/go/go.diff
Comment 10 Julien Laffaye freebsd_committer freebsd_triage 2018-08-08 21:13:08 UTC
Is this patch submitted to upstream ?
Comment 11 Hyun Hwang 2018-09-19 20:46:52 UTC
*** Bug 231436 has been marked as a duplicate of this bug. ***
Comment 12 Yuval Pavel Zholkover 2018-09-23 16:42:23 UTC
Hi,

I maintain the FreeBSD/arm builder, I just wanted to add some quick notes:

As per https://golang.org/doc/install/source#go14, when go 1.4 is used as the bootstrap toolchain, you must set CGO_ENABLED=0.
Also it's recommended to use https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz or the git branch release-branch.go1.4 directly.
In release-branch.go1.4 CGO_ENABLED=0 is set by default since:
https://github.com/golang/go/commit/94221a06124fe0d0f7ed45a355c72e46ed0e891b.

GOARM=7 is required when running on a multi-core processor. This is because the dmb instruction is used for memory barriers in various points, and it is an ARMv7 instruction (the ARMv6 variant "mcr p15, 0, %0, c7, c10, 5" was deemed too slow and wasn't used).
The check is performed at _runtime_, the dmb instruction is always compiled in.
For GOARM < 7 the dmb instruction is skipped as it is assumed to be single-core system - this is tested at startup and you get the "runtime: this system has multiple CPUs and must use atomic synchronization instructions. Recompile using GOARM=7." message otherwise.
Comment 13 Steve Wills freebsd_committer freebsd_triage 2018-10-19 12:17:46 UTC
I've tested this and it doesn't build in poudriere via qemu for some reason that I haven't figured out, but it does build on the native hardware. Can we go ahead and commit this?
Comment 14 Yuval Pavel Zholkover 2018-10-19 16:24:23 UTC
(In reply to Steve Wills from comment #13)
Are you using poudriere via qemu on a 64-bit host by any chance?
It could be due to:
https://github.com/golang/go/issues/25770
Comment 15 Steve Wills freebsd_committer freebsd_triage 2018-10-19 19:12:34 UTC
(In reply to Yuval Pavel Zholkover from comment #14)
Yep, qemu running on amd64.
Comment 16 Victor hooi 2018-11-09 05:23:21 UTC
I'm trying to understand this bug.

To confirm - this is to get Go working on ARM64, right?

And this will allow Go packages like Telegraf to work on ARM64, right

I'm trying to use Telegraf in order to pull metrics on pfSense:

https://www.reddit.com/r/PFSENSE/comments/8ufp0x/cant_find_telegraf_package_sg3100_pfsense_243/

However, the issue is that pfSense is based on FreeBSD, and this is running on the Netgate SG-3100 (which is ARM64). Hence, Telegraf isn't available as a package.

How far away is this bug from being fixed?
Comment 17 Mikael Urankar freebsd_committer freebsd_triage 2018-11-09 10:49:24 UTC
(In reply to Victor hooi from comment #16)
No it's for armv6/armv7.
Comment 18 Victor hooi 2018-11-09 19:15:56 UTC
Sorry, I was incorrect before - I think the SG-3100 might actually be ARM7 (according to https://www.netgate.com/solutions/pfsense/sg-3100.html).

So I guess this fix would cover it.

However, is it quite a long way off, or is it close?
Comment 19 Yuval Pavel Zholkover 2018-11-11 19:59:13 UTC
I think you should commit the patch as is, the poudriere failure is due to wrong qemu-user emulation. I highly doubt it will be addressed upstream in Go.
Comment 20 Mikael Urankar freebsd_committer freebsd_triage 2019-03-23 17:33:19 UTC
When can we expect to have lang/go for armv7 ? The 1st PR for this issue was opened 3 years ago now (205820), it's probably time to do something?
Comment 21 Dmitri Goutnik freebsd_committer freebsd_triage 2019-04-12 16:00:25 UTC
Created attachment 203615 [details]
Updated patch for the current lang/go

- Set CGO_ENABLED=1 unconditionally. CGO_ENABLED already defaults to 1 on all supported archs except ARM [1], so effectively this change just enables it on ARM.

- Set GOARM from ARCH for ARM archs. The appropriate GOARM value is supposed to be chosen automatically when compiling on target hardware but on FreeBSD, it is always set to "5" due to the code [2] from a 4 years old commit. I don't know if "FreeBSD has broken VFP support." is still true, maybe a FreeBSD/ARM expert can chime in on that.

QA:

Builds fine in poudriere on 12a, 12i and 11a but otherwise untested - lang/go doesn't currently build in poudriere/qemu on amd64 hosts (comment #14) and qemu-sbruno is marked as BROKEN on i386. 

[1] https://github.com/golang/go/blob/master/src/cmd/dist/build.go#L1486
[2] https://github.com/golang/go/blob/master/src/cmd/dist/util.go#L400
Comment 22 Dmitri Goutnik freebsd_committer freebsd_triage 2019-04-12 20:18:33 UTC
Mk/Uses/go.mk ARM support enhancements: https://reviews.freebsd.org/D19892
Comment 23 Yuval Pavel Zholkover 2019-04-13 11:09:18 UTC
(In reply to Dmitri Goutnik from comment #21)

proper VFP detection is merged in Go 1.12 (https://github.com/golang/go/commit/2e8c31b3d2afce1c1c7b0c6af9cc4a9f296af299) but it relies on the AT_HWCAP ELF auxiliary vector tag which is not available in FreeBSD 10.3 still officially supported by Go 1.12.

It would be best if the Go packages for FreeBSD 11.2/12.0 would also carry this patch:
https://github.com/golang/go/commit/3b6216ed0601c81fe42c2a4738d419afccb62163

As for poudriere builds on amd64, if I read https://wiki.freebsd.org/QemuUserModeHowTo correctly:
  
  "For 32-bit targets (i.e. armv6) use an 32-bit host (i.e. i386) or compat-32. It may be possible to emulate 32-bit targets on a 64-bit host in the future but currently that is not possible."

The qemu-user-static needs to be built as an i386 binary so it would trigger COMPAT_FREEBSD32 syscalls.
I'm not familiar with qemu-sbruno, unfortunately.
Comment 24 Dmitri Goutnik freebsd_committer freebsd_triage 2019-04-13 13:42:07 UTC
Created attachment 203640 [details]
Updated patch for the current lang/go v2

Add https://github.com/golang/go/commit/3b6216ed0601c81fe42c2a4738d419afccb62163 patch
Comment 25 Dmitri Goutnik freebsd_committer freebsd_triage 2019-04-13 13:53:16 UTC
(In reply to Yuval Pavel Zholkover from comment #23)

Thanks for the clarification. Could you please also shed some light on why cgo was not enabled by default on freebsd/arm? Are there any drawbacks to enabling it by default?

Regarding qemu-user-static, its master port (emulators/qemu-sbruno) is currently marked as BROKEN for i386. I'll try to remove BROKEN and see if I can get lang/go built in poudriere in i386 VM. Unfortunately, I don't have any real ARM hardware to test this port on.
Comment 26 Mikael Urankar freebsd_committer freebsd_triage 2019-04-13 14:23:06 UTC
(In reply to Dmitri Goutnik from comment #25)
don't waste your time with qemu-sbruno, it's broken and can't build go, rust or ghc and many other ports

put that in the Makefile:
ifdef QEMU_EMULATING
IGNORE= fails to build with qemu-user-static
.endif
Comment 27 Yuval Pavel Zholkover 2019-04-14 07:14:03 UTC
(In reply to Dmitri Goutnik from comment #25)

I've been running the builder with CGO_ENABLED=1 for a couple of years now. I think the defaults for cgo false were introduced as false for a bunch of targets as part of an unrelated commit to allow the go tool to list source files in packages and nobody bothered to update it since.

I've sent https://golang.org/cl/171727 and https://golang.org/cl/171728 to address these. If merged the'd be part of Go 1.13.
Comment 28 Dmitri Goutnik freebsd_committer freebsd_triage 2019-04-14 12:16:52 UTC
Created attachment 203671 [details]
Updated patch for the current lang/go v3

- Disable building in qemu-user-static. While it can work with right setup (single-CPU i386 host), it doesn't produce useful packages because of Go runtime checks.

- Fix test target

QA:
  poudriere testport OK (112a, 120a, 120i)
Comment 29 Dmitri Goutnik freebsd_committer freebsd_triage 2019-04-14 14:11:36 UTC
(In reply to Yuval Pavel Zholkover from comment #27)
Thanks!
Comment 30 Victor hooi 2019-04-23 19:23:42 UTC
I'm trying to interpret the last few comments, but I'm still confused.

What is the current status of this bug, or is it blocking on something?

(I'm just a user - but would really love this to work as it's blocking things like the Telegraf package working on pfSense - https://github.com/pfsense/FreeBSD-ports/pull/627).
Comment 31 commit-hook freebsd_committer freebsd_triage 2019-04-23 21:19:39 UTC
A commit references this bug:

Author: jlaffaye
Date: Tue Apr 23 21:18:38 UTC 2019
New revision: 499797
URL: https://svnweb.freebsd.org/changeset/ports/499797

Log:
  - Update to 1.12.4
  - Various ARM improvements [1]
  - Disable building in qemu-user-static [1]
  - Fix test target [1]

  PR:		221297
  Submitted by:	Dmitri Goutnik <dg@syrec.org> [1]

Changes:
  head/lang/go/Makefile
  head/lang/go/distinfo