tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

golang cross-builds



The attached patch teaches pkgsrc to cross-build lang/go123 and
golang-based packages.  I have done some manual tests of native and
cross builds, and I think the parts that are not conditional on
USE_CROSS_COMPILE are relatively low-risk changes, but this is a
high-importance target so I won't commit this right away without
review.  Details in the attachment.  Feedback welcome!
From 3a2ec1f0fabef9417bfb17bf3aaa360805b2c032 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Sun, 19 Jan 2025 20:29:09 +0000
Subject: [PATCH] lang/go: Add cross-build support.

This adds cross-build support for lang/go123 and for the Go-related
infrastructure in pkgsrc.  (We could do older versions of Go too with
a little more work.)

Noteworthy changes that are not conditional on USE_CROSS_COMPILE:

1. lang/go/version.mk is rearranged to be more data-driven than
   conditional-driven.  Making it data-driven makes it easier to
   define both GOARCH and GOHOSTARCH from the same tables when
   MACHINE_ARCH and NATIVE_MACHINE_ARCH are not the same.

   This is a likely source of broken edge cases.  I went through the
   old conditional logic and hand-checked all the conditions but I
   could have made a mistake.

2. go-module.mk and go-package.mk define GOPATH_BIN to be `bin' for
   native builds, and `bin/${GO_PLATFORM}' for cross builds -- this
   is the subdirectory of GOPATH where the Go toolchain puts binaries
   so that packages with custom do-install targets can avoid any need
   for USE_CROSS_COMPILE conditionals.

   The default do-install targets use pax slightly differently now to
   avoid the need for USE_CROSS_COMPILE conditionals.  I think the
   logic is equivalent for native builds but this is worth reviewing.

3. lang/go123 no longer depends on bash and Perl at runtime.  As far
   as I can tell, this was just a kludge to pacify check-interpreter
   complaints in the copy of the source code that Go ships under
   ${PREFIX}/go123/src.  We don't need to replace the interpreter at
   build-time -- most of these scripts are not run at all during the
   build, and the handful that remain (make.bash, run.bash) are run
   with ${BASH}.  Instead, we CHECK_INTERPRETER_SKIP them in the
   installed copy of the source code.
---
 lang/go/bootstrap.mk  |  2 +-
 lang/go/go-module.mk  | 23 ++++++++++++-
 lang/go/go-package.mk | 23 ++++++++++++-
 lang/go/version.mk    | 75 ++++++++++++++++++++++++++++---------------
 lang/go123/Makefile   | 68 ++++++++++++++++++++++-----------------
 5 files changed, 133 insertions(+), 58 deletions(-)

diff --git a/lang/go/bootstrap.mk b/lang/go/bootstrap.mk
index b6c47907b4eb..495b4da7acd6 100644
--- a/lang/go/bootstrap.mk
+++ b/lang/go/bootstrap.mk
@@ -1,7 +1,7 @@
 # $NetBSD: bootstrap.mk,v 1.13 2024/08/03 19:28:29 bsiegert Exp $
 
 .if !defined(GOROOT_BOOTSTRAP) || !exists(${GOROOT_BOOTSTRAP}/bin/go)
-.  if ${MACHINE_ARCH} == "aarch64" || \
+.  if (${MACHINE_ARCH} == "aarch64" && ${USE_CROSS_COMPILE:tl} == "no") || \
     (${OPSYS} == "Darwin" && ${OPSYS_VERSION} >= 120000) || \
     (${OPSYS} == "FreeBSD" && ${OPSYS_VERSION} >= 140000) || \
     (${OPSYS} == "SunOS" && ${OS_VARIANT} != "Solaris")
diff --git a/lang/go/go-module.mk b/lang/go/go-module.mk
index 957c1680d190..11be874ca6e3 100644
--- a/lang/go/go-module.mk
+++ b/lang/go/go-module.mk
@@ -53,6 +53,26 @@ MAKE_ENV+=	GOPATH=${WRKDIR}/.gopath GOPROXY=file://${WRKDIR}/.goproxy
 MAKE_ENV+=	GOCACHE=${GO_CACHE_DIR} GOTMPDIR=${GO_CACHE_DIR}
 MAKE_ENV+=	GOTOOLCHAIN=local
 
+.include "../../mk/bsd.fast.prefs.mk"
+
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+
+MAKE_ENV+=	GOHOSTARCH=${GOHOSTARCH}
+MAKE_ENV+=	GOARCH=${GOARCH}
+MAKE_ENV+=	GOOS=${GOOS}
+
+# TOOLBASE-relative .go source code paths get baked into binaries.
+# Pooh.
+CHECK_WRKREF_SKIP+=	bin/*
+
+GOPATH_BIN=	bin/${GO_PLATFORM}
+
+.else
+
+GOPATH_BIN=	bin
+
+.endif
+
 post-extract: ${GO_CACHE_DIR}
 ${GO_CACHE_DIR}:
 	@${MKDIR} ${.TARGET}
@@ -72,7 +92,8 @@ do-test:
 
 .if !target(do-install)
 do-install:
-	${RUN} cd ${WRKDIR}/.gopath && [ ! -d bin ] || ${PAX} -rw bin ${DESTDIR}${PREFIX}
+	${RUN} cd ${WRKDIR}/.gopath && [ ! -d ${GOPATH_BIN} ] || \
+		{ cd ${GOPATH_BIN} && ${PAX} -rw . ${DESTDIR}${PREFIX}/bin; }
 .endif
 
 .PHONY: print-go-modules show-go-modules
diff --git a/lang/go/go-package.mk b/lang/go/go-package.mk
index ab7580084d06..868aa0bf2e85 100644
--- a/lang/go/go-package.mk
+++ b/lang/go/go-package.mk
@@ -77,6 +77,26 @@ MAKE_ENV+=	GOCACHE=${GO_CACHE_DIR} GOTMPDIR=${GO_CACHE_DIR}
 MAKE_ENV+=	GO111MODULE=off
 MAKE_ENV+=	GOTOOLCHAIN=local
 
+.include "../../mk/bsd.fast.prefs.mk"
+
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+
+MAKE_ENV+=	GOHOSTARCH=${GOHOSTARCH}
+MAKE_ENV+=	GOARCH=${GOARCH}
+MAKE_ENV+=	GOOS=${GOOS}
+
+# TOOLBASE-relative .go source code paths get baked into binaries.
+# Pooh.
+CHECK_WRKREF_SKIP+=	bin/*
+
+GOPATH_BIN=	bin/${GO_PLATFORM}
+
+.else
+
+GOPATH_BIN=	bin
+
+.endif
+
 .if !target(post-extract)
 post-extract:
 	${RUN} ${MKDIR} ${WRKSRC}
@@ -100,7 +120,8 @@ do-test:
 
 .if !target(do-install)
 do-install:
-	${RUN} cd ${WRKDIR}; [ ! -d bin ] || ${PAX} -rw bin ${DESTDIR}${PREFIX}
+	${RUN} cd ${WRKDIR}; [ ! -d ${GOPATH_BIN} ] || \
+		{ cd ${GOPATH_BIN}; ${PAX} -rw . ${DESTDIR}${PREFIX}/bin; }
 	${RUN} cd ${WRKDIR}; [ ! -d pkg ] || ${PAX} -rw src pkg ${DESTDIR}${PREFIX}/gopkg
 .endif
 
diff --git a/lang/go/version.mk b/lang/go/version.mk
index 2dcbe73d4b55..85d36e025e17 100644
--- a/lang/go/version.mk
+++ b/lang/go/version.mk
@@ -30,39 +30,56 @@ GO=			${TOOLBASE}/go${GOVERSSUFFIX}/bin/go
 # Build dependency for Go
 GO_PACKAGE_DEP=		go${GOVERSSUFFIX}-${GO${GOVERSSUFFIX}_VERSION}*:../../lang/go${GOVERSSUFFIX}
 
-ONLY_FOR_PLATFORM?=	*-*-i386 *-*-x86_64 *-*-earmv[67]hf *-*-aarch64
+#ONLY_FOR_PLATFORM?=	*-*-i386 *-*-x86_64 *-*-earmv[67]hf *-*-aarch64
 
 NOT_FOR_PLATFORM=	SunOS-*-i386
-.if ${MACHINE_ARCH} == "i386"
-GOARCH=			386
-GOCHAR=			8
-.elif ${MACHINE_ARCH} == "x86_64"
-GOARCH=			amd64
-GOCHAR=			6
-# go118 hardcodes GOARCH=arm64 even when running in an x86_64 chroot
-.  if ${OPSYS} == "Darwin"
-GOOPT+=			GOHOSTARCH=amd64
-.  endif
-.elif ${MACHINE_ARCH} == "earmv6hf" || ${MACHINE_ARCH} == "earmv7hf"
-GOARCH=			arm
-GOCHAR=			5
-.elif ${MACHINE_ARCH} == "aarch64"
-GOARCH=			arm64
-GOOPT=			GOARM=7
+
+GOARCH.aarch64=		arm64
+GOARCH.earmv6hf=	arm
+GOARCH.earmv7hf=	arm
+GOARCH.i386=		386
+GOARCH.powerpc64=	ppc64
+GOARCH.powerpc64le=	ppc64le
+GOARCH.powerpc=		ppc
+GOARCH.x86_64=		amd64
+
+GOCHAR.earmv6hf=	5
+GOCHAR.earmv7hf=	5
+GOCHAR.i386=		8
+GOCHAR.x86_64=		6
+
+GOOPT.aarch64=		GOARM=7
+GOOPT.earmv6hf=		GOARM=6
+GOOPT.earmv7hf=		GOARM=7
+
+GOARCH=			${GOARCH.${MACHINE_ARCH}:U${MACHINE_ARCH}}
+NATIVE_GOARCH=		${GOARCH.${NATIVE_MACHINE_ARCH}:U${NATIVE_MACHINE_ARCH}}
+
+GOCHAR=			${GOCHAR.${MACHINE_ARCH}:U}
+
+GOOPT=			${GOOPT.${MACHINE_ARCH}:U}
+
+# go118 hardcodes GOARCH=arm64 even when running in an x86_64 chroot.
 # GOHOSTARCH is being misdetected as arm on NetBSD. Unclear why.
-GOOPT+=			GOHOSTARCH=arm64
-.endif
-.if ${MACHINE_ARCH} == "earmv6hf"
-GOOPT=			GOARM=6
-.elif ${MACHINE_ARCH} == "earmv7hf"
-GOOPT=			GOARM=7
+.if (${OPSYS} == "Darwin" && ${NATIVE_MACHINE_ARCH} == "x86_64") || \
+    ${MACHINE_ARCH} == "aarch64" || \
+    ${USE_CROSS_COMPILE:tl} == "yes"
+GOOPT+=			GOHOSTARCH=${NATIVE_GOARCH}
 .endif
 
 .if ${OPSYS} == "SunOS" && ${OS_VARIANT} != "Solaris"
-GO_PLATFORM=		illumos_${GOARCH}
+GOOS=			illumos
+.else
+GOOS=			${LOWER_OPSYS}
+.endif
+GO_PLATFORM=		${GOOS}_${GOARCH}
+
+.if ${NATIVE_OPSYS} == "Sunos" && ${NATIVE_OS_VARIANT} != "Solaris"
+NATIVE_GOOS=		illumos
 .else
-GO_PLATFORM=		${LOWER_OPSYS}_${GOARCH}
+NATIVE_GOOS=		${NATIVE_LOWER_OPSYS}
 .endif
+NATIVE_GO_PLATFORM=	${NATIVE_GOOS}_${NATIVE_GOARCH}
 
 PLIST_SUBST+=		GO_PLATFORM=${GO_PLATFORM:Q} GOARCH=${GOARCH:Q}
 PLIST_SUBST+=		GOCHAR=${GOCHAR:Q}
@@ -71,3 +88,11 @@ PRINT_PLIST_AWK+=	{ sub("/${GO_PLATFORM}/", "/$${GO_PLATFORM}/") }
 
 TOOLS_CREATE+=		go
 TOOLS_PATH.go=		${GO}
+
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+GOOPT+=			GOARCH=${GOARCH}
+GOOPT+=			GOOS=${LOWER_OPSYS}
+GOOPT+=			CC=${NATIVE_CC:Q}
+GOOPT+=			CC_FOR_TARGET=${CC:Q}
+GOOPT+=			CXX_FOR_TARGET=${CXX:Q}
+.endif
diff --git a/lang/go123/Makefile b/lang/go123/Makefile
index 8207bc7cbca6..157a3e4aea0b 100644
--- a/lang/go123/Makefile
+++ b/lang/go123/Makefile
@@ -18,7 +18,7 @@ COMMENT=	The Go programming language
 LICENSE=	modified-bsd
 
 WRKSRC=		${WRKDIR}/go
-USE_TOOLS+=	bash:run perl:run pax
+USE_TOOLS+=	bash perl pax
 
 # Patch to stop requiring /proc to be mounted on NetBSD
 PATCH_SITES=		https://github.com/golang/go/commit/
@@ -31,35 +31,35 @@ BUILDLINK_PASSTHRU_DIRS+= ${TMPDIR}
 
 INSTALLATION_DIRS=	bin go${GOVERSSUFFIX}
 
-REPLACE_BASH+=	lib/time/update.bash
-REPLACE_BASH+=	misc/wasm/go_js_wasm_exec
-REPLACE_BASH+=	misc/wasm/go_wasip1_wasm_exec
-REPLACE_BASH+=	src/all.bash
-REPLACE_BASH+=	src/bootstrap.bash
-REPLACE_BASH+=	src/buildall.bash
-REPLACE_BASH+=	src/clean.bash
-REPLACE_BASH+=	src/cmd/compile/internal/ssa/_gen/cover.bash
-REPLACE_BASH+=	src/cmd/vendor/golang.org/x/sys/plan9/mkall.sh
-REPLACE_BASH+=	src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh
-REPLACE_BASH+=	src/cmd/vendor/golang.org/x/sys/unix/mkall.sh
-REPLACE_BASH+=	src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh
-REPLACE_BASH+=	src/cmd/vendor/golang.org/x/sys/windows/mkerrors.bash
-REPLACE_BASH+=	src/cmd/vendor/golang.org/x/sys/windows/mkknownfolderids.bash
-REPLACE_BASH+=	src/crypto/internal/boring/build.sh
-REPLACE_BASH+=	src/crypto/internal/boring/build-boring.sh
-REPLACE_BASH+=	src/crypto/internal/boring/build-goboring.sh
-REPLACE_BASH+=	src/go/doc/comment/mkstd.sh
-REPLACE_BASH+=	src/cmp.bash
-REPLACE_BASH+=	src/make.bash
-REPLACE_BASH+=	src/race.bash
-REPLACE_BASH+=	src/run.bash
-REPLACE_BASH+=	src/runtime/race/mkcgo.sh
-REPLACE_BASH+=	src/syscall/mkall.sh
-REPLACE_BASH+=	src/syscall/mkerrors.sh
-REPLACE_BASH+=	src/syscall/mksysnum_plan9.sh
-
-REPLACE_PERL+=	src/regexp/syntax/make_perl_groups.pl
-REPLACE_PERL+=	src/syscall/*.pl
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/lib/time/update.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/misc/wasm/go_js_wasm_exec
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/misc/wasm/go_wasip1_wasm_exec
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/all.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/bootstrap.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/buildall.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/clean.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/cmd/compile/internal/ssa/_gen/cover.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/cmd/vendor/golang.org/x/sys/plan9/mkall.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/cmd/vendor/golang.org/x/sys/windows/mkerrors.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/cmd/vendor/golang.org/x/sys/windows/mkknownfolderids.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/crypto/internal/boring/build.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/crypto/internal/boring/build-boring.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/crypto/internal/boring/build-goboring.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/go/doc/comment/mkstd.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/cmp.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/make.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/race.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/run.bash
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/runtime/race/mkcgo.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/syscall/mkall.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/syscall/mkerrors.sh
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/syscall/mksysnum_plan9.sh
+
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/regexp/syntax/make_perl_groups.pl
+CHECK_INTERPRETER_SKIP+=	go${GOVERSSUFFIX}/src/syscall/*.pl
 
 # uses own linker, which does not support relro on NetBSD
 CHECK_RELRO_SKIP+=		go${GOVERSSUFFIX}/bin/go
@@ -117,7 +117,15 @@ do-install:
 	cd ${WRKSRC} && rm -rf pkg/obj pkg/bootstrap
 	cd ${WRKSRC} && pax -rw . ${DESTDIR}${PREFIX}/go${GOVERSSUFFIX}
 	find ${DESTDIR}${PREFIX}/go${GOVERSSUFFIX} -name \*.orig -exec rm {} \;
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+	cd ${DESTDIR}${PREFIX}/go${GOVERSSUFFIX} && \
+	${RM} -rf pkg/tool/${NATIVE_GO_PLATFORM}
+.endif
 .for cmd in go gofmt
+.  if ${USE_CROSS_COMPILE:tl} == "yes"
+	${MV} ${DESTDIR}${PREFIX}/go${GOVERSSUFFIX}/bin/${GO_PLATFORM}/${cmd} \
+		${DESTDIR}${PREFIX}/go${GOVERSSUFFIX}/bin/${cmd}
+.  endif
 	${LN} -sf ${PREFIX}/go${GOVERSSUFFIX}/bin/${cmd} ${DESTDIR}${PREFIX}/bin/${cmd}${GOVERSSUFFIX}
 .endfor
 


Home | Main Index | Thread Index | Old Index