tech-pkg archive

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

[WIP PATCH] Cross-OS package builds



The attached work-in-progress patch series -- attched alternately as a
git patch series (.patch) and a single giant diff (.diff) --
implements cross-OS package builds, by splitting not just MACHINE_ARCH
but also OPSYS, OS_VERSION, and other variables on native vs cross.

The result is that you can add some variables to mk.conf to describe
the platform that packages should be cross-built for -- currently only
NetBSD is supported, requiring a tooldir from `build.sh tools' and a
destdir from `build.sh distribution' -- and then start cross-building
by setting USE_CROSS_COMPILE=yes.

Review and feedback welcome!


For example:

   # mk.conf
   CROSS_MACHINE_ARCH=	aarch64
   TOOLDIR=		/home/riastradh/netbsd/10/obj.arm64/tooldir
   CROSS_DESTDIR=	/home/riastradh/netbsd/10/obj.arm64/destdir.evbarm
   CROSS_OBJECT_FMT=	ELF
   CROSS_OPSYS=		NetBSD
   CROSS_OS_VERSION=	10.0
   CROSS_OPSYS_VERSION=	100000
   CROSS_LOWER_OPSYS=	netbsd
   CROSS_LOWER_OPSYS_VERSUFFIX=	# empty
   CROSS_LOWER_OS_VARIANT=	# empty
   CROSS_LOWER_VARIANT_VERSION=	# empty
   CROSS_LOWER_VENDOR=		# empty

Then you can cross-build a package by setting USE_CROSS_COMPILE=yes on
the command line:

   $ cd net/dnsmasq
   $ bmake package USE_CROSS_COMPILE=yes

The resulting package will end up under packages.NetBSD-10.0-aarch64.


Some caveats about this work-in-progress:

1. The mechanism for overriding all the variables like MACHINE_ARCH,
   OPSYS, &c., in bsd.prefs.mk, and the native/cross variable
   switcheroo based on USE_CROSS_COMPILE, is a little gnarly and may
   have a bit of a performance impact on native builds.

   This is in patch 03/13 of the series.  Because of this, I probably
   won't commit as is.  But it's delicate, so finding a better
   mechanism is a little tricky.

2. USE_TOOLS+=xyz:run doesn't work for cross-OS builds.

   This is because because we don't have any mechanism to distinguish
   the build-time tool that you can execute during package build from
   the run-time tool that you can bake into the packages you build.

   For now I put in an explicit error to avoid confusion, but it means
   there are a lot of packages that won't build.

3. It is necessary to define all the variables in the example above --
   you can't skip any.

   I didn't duplicate any logic to provide reasonable defaults based
   on CROSS_OPSYS, for instance, but I did add an error check to
   ensure you didn't miss anything, because the results were very
   confusing if you forgot to define one of the variables.  To be
   improved.

   There are other variables which are optional, like CROSS_LOCALBASE,
   CROSS_VARBASE, and CROSS_SYSCONFBASE, which override the defaults
   of /usr/pkg, /var, and /etc, respectively.

4. No integration with pbulk yet.

   Need to teach it about TOOL_DEPENDS split for native vs cross
   dependency resolution.  Should teach it to build only the native
   packages it needs for a full cross build.

5. Perl still isn't reasonably cross-compilable.
>From 2c504240c4ad7d0cbdd48af620448979e782224f Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 04:12:48 +0000
Subject: [PATCH 01/13] bsd.prefs.mk: Set OBJECT_FMT for Darwin before cross
 variables.

This way it can be handled by the cross variable logic when the host
and target have misatched object formats, like building NetBSD
packages (ELF) on macOS (Mach-O).

This whole stanza can be removed when PR pkg/57837
(bootstrap-mk-files bsd.own.mk defines wrong OBJECT_FMT on macOS
(Darwin), https://gnats.NetBSD.org/57837) is fixed.

No functional change intended so far -- this just makes subsequent
patches easier to follow.
---
 mk/bsd.prefs.mk | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index f1161385fcea..87dbb29bd15a 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -341,6 +341,11 @@ MACHINE_PLATFORM?=		${OPSYS}-${OS_VERSION}-${MACHINE_ARCH}
 NATIVE_MACHINE_GNU_PLATFORM?=	${NATIVE_MACHINE_GNU_ARCH}-${LOWER_VENDOR}-${LOWER_OPSYS:C/[0-9]//g}${NATIVE_APPEND_ELF}${LOWER_OPSYS_VERSUFFIX}${NATIVE_APPEND_ABI}
 MACHINE_GNU_PLATFORM?=		${MACHINE_GNU_ARCH}-${LOWER_VENDOR}-${LOWER_OPSYS:C/[0-9]//g}${APPEND_ELF}${LOWER_OPSYS_VERSUFFIX}${APPEND_ABI}
 
+# Set this before <bsd.own.mk> does, since it doesn't know about Darwin
+.if ${OPSYS} == "Darwin"
+OBJECT_FMT?=		Mach-O
+.endif
+
 #
 # cross-libtool is special -- it is built as a native package, but it
 # needs tools set up as if for a cross-compiled package because it
@@ -376,11 +381,6 @@ NEED_OWN_INSTALL_TARGET=no
 USETOOLS=		no
 MAKE_ENV+=		USETOOLS=no
 
-# Set this before <bsd.own.mk> does, since it doesn't know about Darwin
-.if ${OPSYS} == "Darwin"
-OBJECT_FMT?=		Mach-O
-.endif
-
 ACCEPTABLE_LICENSES?=	${DEFAULT_ACCEPTABLE_LICENSES}
 
 # Provide PKGPATH early on so that mk.conf can use it.

>From 5b83e34f23c56839bf8348edc597ceae0af991d1 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 04:20:16 +0000
Subject: [PATCH 02/13] bsd.prefs.mk: Set cross MACHINE_ARCH/destdir right
 after bsd.own.mk.

This puts it before defaults/mk.conf, which has no effect here --
there's no default TARGET_ARCH, MAKEOBJDIR, or CROSS_DESTDIR in
defaults/mk.conf, and defaults/mk.conf is not affected by
MACHINE_ARCH (immediately, anyway), CROSS_DESTDIR, or _CROSS_DESTDIR.

Later we'll add more variables like MACHINE_ARCH here affected by a
TARGET_* variable, including OBJECT_FMT.  This will allow us to
handle OBJECT_FMT via TARGET_OBJECT_FMT before the next stanza which
provides OPSYS-based defaults for OBJECT_FMT.

No change for native builds since this only moves around a block
gated on USE_CROSS_COMPILE = yes.
---
 mk/bsd.prefs.mk | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index 87dbb29bd15a..ad66a61cdec0 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -389,6 +389,28 @@ PKGPATH?=		${.CURDIR:C|.*/([^/]*/[^/]*)$|\1|}
 # Load the settings from MAKECONF, which is /etc/mk.conf by default.
 .include <bsd.own.mk>
 
+# When cross-compilation support is requested, the following options
+# must be specified as well or guessable:
+# - MACHINE_ARCH is set to TARGET_ARCH if set.
+# - CROSS_DESTDIR is guessed from MAKEOBJDIR and MACHINE_ARCH.
+# - PKG_DBDIR is expanded and prefixed with CROSS_DESTDIR
+# - DESTDIR support is required
+#
+# _CROSS_DESTDIR is set for internal use to avoid conditionalising
+# the use.
+
+.if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
+.  if defined(TARGET_ARCH)
+MACHINE_ARCH=	${TARGET_ARCH}
+.  endif
+CROSS_DESTDIR?=	${MAKEOBJDIR}/destdir.${MACHINE_ARCH}
+.  if !exists(${CROSS_DESTDIR}/usr/include/stddef.h)
+PKG_FAIL_REASON+=	"The cross-compiling root ${CROSS_DESTDIR:Q} is incomplete"
+.  else
+_CROSS_DESTDIR=	${CROSS_DESTDIR}
+.  endif
+.endif
+
 .if ${OPSYS} == "OpenBSD"
 .  if defined(ELF_TOOLCHAIN) && ${ELF_TOOLCHAIN} == "yes"
 OBJECT_FMT?=	ELF
@@ -450,28 +472,6 @@ SHAREMODE?=		${DOCMODE}
 	@${FALSE}
 .endif
 
-# When cross-compilation support is requested, the following options
-# must be specified as well or guessable:
-# - MACHINE_ARCH is set to TARGET_ARCH if set.
-# - CROSS_DESTDIR is guessed from MAKEOBJDIR and MACHINE_ARCH.
-# - PKG_DBDIR is expanded and prefixed with CROSS_DESTDIR
-# - DESTDIR support is required
-#
-# _CROSS_DESTDIR is set for internal use to avoid conditionalising
-# the use.
-
-.if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-.  if defined(TARGET_ARCH)
-MACHINE_ARCH=	${TARGET_ARCH}
-.  endif
-CROSS_DESTDIR?=	${MAKEOBJDIR}/destdir.${MACHINE_ARCH}
-.  if !exists(${CROSS_DESTDIR}/usr/include/stddef.h)
-PKG_FAIL_REASON+=	"The cross-compiling root ${CROSS_DESTDIR:Q} is incomplete"
-.  else
-_CROSS_DESTDIR=	${CROSS_DESTDIR}
-.  endif
-.endif
-
 # Load the OS-specific definitions for program variables.  Default to loading
 # the NetBSD ones if an OS-specific file doesn't exist.
 .if exists(${_PKGSRC_TOPDIR}/mk/platform/${OPSYS}.mk)

>From 0a7555235f2a9541ff96edb83bc882a005b847f0 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 04:25:06 +0000
Subject: [PATCH 03/13] mk: New CROSS_* variable scheme for cross-compilation.

This change brings in support for cross-OS-compilation.

Caveat: Existing mk.conf files used for cross-compilation no longer
work; they must be adapted to the new scheme.

Under this new scheme, if an mk.conf variable X can be different for
native and cross builds like OPSYS, MACHINE_ARCH, LOCALBASE, &c., you
just define X in mk.conf to set it for native builds, and CROSS_X in
mk.conf to set it for cross builds.

Example:

    LOCALBASE=		/home/riastradh/pkgsrc/cross/pkg
    CROSS_LOCALBASE=	/opt/pkg
    CROSS_MACHINE_ARCH=	powerpc

For now, _all_ OS-related variables must be defined in cross-builds;
none are filled in automatically.  For NetBSD, this means:

    CROSS_OPSYS=		NetBSD
    CROSS_OS_VERSION=		10.0
    CROSS_OPSYS_VERSION=	100000
    CROSS_LOWER_OPSYS=		netbsd
    CROSS_LOWER_OPSYS_VERSUFFIX=# empty
    CROSS_LOWER_OS_VARIANT=	# empty
    CROSS_LOWER_VARIANT_VERSION=# empty
    CROSS_LOWER_VENDOR=		# empty

XXX This new scheme is likely to substantially raise make(1) costs by
making a lot of variables expand to conditionals rather than fixed
strings.  Need to think of a way to mitigate this.  Unfortunately,
there's a lot of moving parts so it's not trivial to just make it all
conditional on USE_CROSS_COMPILE = yes, because that might not even
be defined by the time we have to use some of the variables.
---
 doc/HOWTO-use-crosscompile |  33 ++--
 mk/bsd.prefs.mk            | 338 +++++++++++++++++++++----------------
 mk/tools/cross.NetBSD.mk   |  25 +++
 mk/tools/defaults.mk       |  13 +-
 mk/tools/tools.NetBSD.mk   |  32 ----
 5 files changed, 247 insertions(+), 194 deletions(-)
 create mode 100644 mk/tools/cross.NetBSD.mk

diff --git a/doc/HOWTO-use-crosscompile b/doc/HOWTO-use-crosscompile
index c2f7fe7c659f..51fe453bc4dd 100644
--- a/doc/HOWTO-use-crosscompile
+++ b/doc/HOWTO-use-crosscompile
@@ -37,29 +37,27 @@ In addition to whatever else you want in your mk.conf for pkgsrc, add:
    # Cross-compile by default.
    #
    # XXX This currently can't be set to `yes' on the command line,
-   # which is a bug.
+   # which is a bug.  But it can be set to `no' to build native
+   # packages.
    USE_CROSS_COMPILE?=  yes
 
    # Point pkgsrc at the NetBSD tooldir and destdir.  These are used
    # only for cross-builds.
-   #
-   # XXX There is no obvious variable that is set to amd64 so that we
-   # could use
-   #
-   #    TOOLDIR=        /usr/obj/tooldir.${OPSYS}-${OS_VERSION}-${NATIVE_xyz}
-   #
-   # MACHINE is amd64 but, since it's not NATIVE_xyz, it's wrong.
-   # NATIVE_MACHINE_ARCH is x86_64, not amd64.
    TOOLDIR=             /usr/obj/tooldir.NetBSD-6.1-amd64
    CROSS_DESTDIR=       /usr/obj/destdir.evbppc
 
    # Specify the machine architecture of target packages.
-   #
-   # XXX This currently can't be set on the command line, which is a
-   # bug.
-   .if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-   MACHINE_ARCH=        powerpc
-   .endif
+   CROSS_MACHINE_ARCH=  powerpc
+
+   # Specify the OS of target packages.
+   CROSS_OPSYS=		NetBSD
+   CROSS_OS_VERSION=	10.0
+   CROSS_OPSYS_VERSION=	100000
+   CROSS_LOWER_OPSYS=   netbsd
+   CROSS_LOWER_OPSYS_VERSUFFIX= # empty
+   CROSS_LOWER_OS_VARIANT=      # empty
+   CROSS_LOWER_VARIANT_VERSION= # empty
+   CROSS_LOWER_VENDOR=          # empty
 
 Optionally, you can set CROSS_LOCALBASE for cross-compiled packages
 separately from LOCALBASE for natively compiled packages.  For example,
@@ -69,6 +67,9 @@ will create packages which install to /opt/pkg:
    LOCALBASE=		/home/user/cross/pkg
    CROSS_LOCALBASE=	/opt/pkg
 
+By default, CROSS_LOCALBASE will be /usr/pkg, meaning packages that are
+being cross-compiled will see LOCALBASE=/usr/pkg.
+
 ** Bootstrapped pkgsrc
 
 You can bootstrap pkgsrc or not; it shouldn't make a difference for
@@ -83,7 +84,7 @@ cross-compilation.  If you do:
    be left empty or undefined for earmv7hf cross-builds.  So you might
    need:
 
-      .if empty(USE_CROSS_COMPILE:M[yY][eE][sS])
+      .if ${USE_CROSS_COMPILE:tl} != "yes"
       ABI=    64 # set for native amd64 build
       .else
       ABI=    # empty for earmv7hf cross-build
diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index ad66a61cdec0..47be8aee8479 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -87,23 +87,23 @@ UNAME=/run/current-system/sw/bin/uname
 UNAME=echo Unknown
 .endif
 
-.if !defined(OPSYS)
-OPSYS:=			${:!${UNAME} -s!:S/-//g:S/\///g:C/^CYGWIN_.*$/Cygwin/}
-MAKEFLAGS+=		OPSYS=${OPSYS:Q}
+.if !defined(NATIVE_OPSYS)
+NATIVE_OPSYS:=		${:!${UNAME} -s!:S/-//g:S/\///g:C/^CYGWIN_.*$/Cygwin/}
+MAKEFLAGS+=		NATIVE_OPSYS=${NATIVE_OPSYS:Q}
 .endif
 
 # OS_VARIANT is used to differentiate operating systems which have a common
 # basis but offer contrasting environments, for example Linux distributions
 # or illumos forks.
-OS_VARIANT?=		# empty
+NATIVE_OS_VARIANT?=	# empty
 
 # The _CMD indirection allows code below to modify these values
 # without executing the commands at all.  Later, recursed make
 # invocations will skip these blocks entirely thanks to MAKEFLAGS.
-.if !defined(OS_VERSION)
-_OS_VERSION_CMD=	${UNAME} -r
-OS_VERSION=		${_OS_VERSION_CMD:sh}
-MAKEFLAGS+=		OS_VERSION=${OS_VERSION:Q}
+.if !defined(NATIVE_OS_VERSION)
+_NATIVE_OS_VERSION_CMD=	${UNAME} -r
+NATIVE_OS_VERSION=	${_NATIVE_OS_VERSION_CMD:sh}
+MAKEFLAGS+=		NATIVE_OS_VERSION=${NATIVE_OS_VERSION:Q}
 .endif
 
 #
@@ -112,11 +112,11 @@ MAKEFLAGS+=		OS_VERSION=${OS_VERSION:Q}
 # default command is likely correct for most OS, those that need to can set
 # it to a custom command in the later OPSYS-specific section.
 #
-.if !defined(OPSYS_VERSION)
-_OPSYS_VERSION_CMD=	${UNAME} -r | \
+.if !defined(NATIVE_OPSYS_VERSION)
+_NATIVE_OPSYS_VERSION_CMD=	${UNAME} -r | \
 			awk -F. '{major=int($$1); minor=int($$2); if (minor>=100) minor=99; patch=int($$3); if (patch>=100) patch=99; printf "%02d%02d%02d", major, minor, patch}'
-OPSYS_VERSION=		${_OPSYS_VERSION_CMD:sh}
-MAKEFLAGS+=		OPSYS_VERSION=${OPSYS_VERSION:Q}
+NATIVE_OPSYS_VERSION=	${_NATIVE_OPSYS_VERSION_CMD:sh}
+MAKEFLAGS+=		NATIVE_OPSYS_VERSION=${NATIVE_OPSYS_VERSION:Q}
 .endif
 
 # Preload these for architectures not in all variations of bsd.own.mk,
@@ -155,194 +155,231 @@ MACHINE_GNU_ARCH?=		${GNU_ARCH.${MACHINE_ARCH}:U${MACHINE_ARCH}}
 
 ## If changes are made to how OS_VERSION is set below please keep
 ## "pkgsrc/pkgtools/osabi/INSTALL" in-sync.
-.if ${OPSYS} == "NetBSD"
-LOWER_OPSYS?=		netbsd
+.if ${NATIVE_OPSYS} == "NetBSD"
+NATIVE_LOWER_OPSYS?=	netbsd
 
-.elif ${OPSYS} == "AIX"
+.elif ${NATIVE_OPSYS} == "AIX"
 .  if exists(/usr/bin/oslevel)
-_OS_VERSION!=		/usr/bin/oslevel
+_NATIVE_OS_VERSION!=	/usr/bin/oslevel
 .  else
-_OS_VERSION!=		echo `${UNAME} -v`.`${UNAME} -r`
+_NATIVE_OS_VERSION!=	echo `${UNAME} -v`.`${UNAME} -r`
 .  endif
-OS_VERSION=		${_OS_VERSION:C/([0-9]*\.[0-9]*).*/\1/}
-LOWER_OPSYS_VERSUFFIX=	${_OS_VERSION}
-LOWER_OPSYS?=		aix
-LOWER_VENDOR?=		ibm
-
-.elif ${OPSYS} == "BSDOS"
-LOWER_OPSYS?=		bsdi
-
-.elif ${OPSYS} == "Cygwin"
-LOWER_OPSYS?=		cygwin
-LOWER_VENDOR?=		pc
-_OS_VERSION!=		${UNAME} -r
-OS_VERSION=		${_OS_VERSION:C/\(.*\)//}
-OS_VARIANT!=		${UNAME} -s
-
-.elif ${OPSYS} == "Darwin"
-LOWER_OPSYS?=		darwin
-LOWER_OPSYS_VERSUFFIX=	${OS_VERSION:C/([0-9]*).*/\1/}
-LOWER_VENDOR?=		apple
-_OPSYS_VERSION_CMD=	sw_vers -productVersion | \
+NATIVE_OS_VERSION=		${_NATIVE_OS_VERSION:C/([0-9]*\.[0-9]*).*/\1/}
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${_NATIVE_OS_VERSION}
+NATIVE_LOWER_OPSYS?=		aix
+NATIVE_LOWER_VENDOR?=		ibm
+
+.elif ${NATIVE_OPSYS} == "BSDOS"
+NATIVE_LOWER_OPSYS?=	bsdi
+
+.elif ${NATIVE_OPSYS} == "Cygwin"
+NATIVE_LOWER_OPSYS?=	cygwin
+NATIVE_LOWER_VENDOR?=	pc
+_NATIVE_OS_VERSION!=	${UNAME} -r
+NATIVE_OS_VERSION=	${_NATIVE_OS_VERSION:C/\(.*\)//}
+NATIVE_OS_VARIANT!=	${UNAME} -s
+
+.elif ${NATIVE_OPSYS} == "Darwin"
+NATIVE_LOWER_OPSYS?=		darwin
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${NATIVE_OS_VERSION:C/([0-9]*).*/\1/}
+NATIVE_LOWER_VENDOR?=		apple
+_NATIVE_OPSYS_VERSION_CMD=	sw_vers -productVersion | \
 			awk -F. '{major=int($$1); minor=int($$2); if (minor>=100) minor=99; patch=int($$3); if (patch>=100) patch=99; printf "%02d%02d%02d", major, minor, patch}'
 
-.elif ${OPSYS} == "DragonFly"
-OS_VERSION:=		${OS_VERSION:C/-.*$//}
-LOWER_OPSYS?=		dragonfly
-LOWER_VENDOR?=		pc
+.elif ${NATIVE_OPSYS} == "DragonFly"
+NATIVE_OS_VERSION:=	${NATIVE_OS_VERSION:C/-.*$//}
+NATIVE_LOWER_OPSYS?=	dragonfly
+NATIVE_LOWER_VENDOR?=	pc
 
-.elif ${OPSYS} == "FreeBSD"
-OS_VERSION:=		${OS_VERSION:C/-.*$//}
-LOWER_OPSYS?=		freebsd
-LOWER_OPSYS_VERSUFFIX=	${OS_VERSION:C/([0-9]*).*/\1/}
+.elif ${NATIVE_OPSYS} == "FreeBSD"
+NATIVE_OS_VERSION:=		${OS_VERSION:C/-.*$//}
+NATIVE_LOWER_OPSYS?=		freebsd
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${OS_VERSION:C/([0-9]*).*/\1/}
 .  if ${MACHINE_ARCH} == "i386"
-LOWER_VENDOR?=		pc
+NATIVE_LOWER_VENDOR?=		pc
 .  endif
-LOWER_VENDOR?=		unknown
+NATIVE_LOWER_VENDOR?=		unknown
 
-.elif ${OPSYS} == "Haiku"
-LOWER_OPSYS?=		haiku
-.  if ${MACHINE_ARCH} == "i386"
-LOWER_VENDOR?=		pc
+.elif ${NATIVE_OPSYS} == "Haiku"
+NATIVE_LOWER_OPSYS?=		haiku
+.  if ${NATIVE_MACHINE_ARCH} == "i386"
+NATIVE_LOWER_VENDOR?=		pc
 .  endif
 
-.elif ${OPSYS} == "Interix"
-LOWER_OPSYS?=		interix
-LOWER_VENDOR?=		pc
+.elif ${NATIVE_OPSYS} == "Interix"
+NATIVE_LOWER_OPSYS?=		interix
+NATIVE_LOWER_VENDOR?=		pc
 .  if exists(/usr/lib/libc.so.5.2) || exists(/usr/lib/x86/libc.so.5.2)
-LOWER_OPSYS_VERSUFFIX=	${OS_VERSION:C/([0-9]*).*/\1/}
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${NATIVE_OS_VERSION:C/([0-9]*).*/\1/}
 .  else
-LOWER_OPSYS_VERSUFFIX?=	3
+NATIVE_LOWER_OPSYS_VERSUFFIX?=	3
 .    if exists(/usr/lib/libc.so.3.5)
-OS_VERSION=		3.5
+NATIVE_OS_VERSION=		3.5
 .    elif exists(/usr/lib/libc.so.3.1)
-OS_VERSION=		3.1
+NATIVE_OS_VERSION=		3.1
 .    else
-OS_VERSION=		3.0
+NATIVE_OS_VERSION=		3.0
 .    endif
 .  endif
 
-.elif ${OPSYS} == "MirBSD"
-LOWER_OPSYS?=		mirbsd
-LOWER_OPSYS_VERSUFFIX=	${OS_VERSION}
-LOWER_VENDOR?=		unknown
+.elif ${NATIVE_OPSYS} == "MirBSD"
+NATIVE_LOWER_OPSYS?=		mirbsd
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${NATIVE_OS_VERSION}
+NATIVE_LOWER_VENDOR?=		unknown
 
-.elif !empty(OPSYS:MIRIX*)
-LOWER_OPSYS?=		irix
-LOWER_OPSYS_VERSUFFIX?=	${OS_VERSION}
-LOWER_VENDOR?=		sgi
+.elif !empty(NATIVE_OPSYS:MIRIX*)
+NATIVE_LOWER_OPSYS?=		irix
+NATIVE_LOWER_OPSYS_VERSUFFIX?=	${NATIVE_OS_VERSION}
+NATIVE_LOWER_VENDOR?=		sgi
 
-.elif ${OPSYS} == "Linux"
-OS_VERSION:=		${OS_VERSION:C/-.*$//}
-LOWER_OPSYS?=		linux
+.elif ${NATIVE_OPSYS} == "Linux"
+NATIVE_OS_VERSION:=		${NATIVE_OS_VERSION:C/-.*$//}
+NATIVE_LOWER_OPSYS?=		linux
 .  if exists(/etc/lsb-release)
 CHROMEOS_RELEASE_NAME!=	awk -F = '$$1 == "CHROMEOS_RELEASE_NAME" { print $$2 }' /etc/lsb-release
 .  endif
 .  if exists(/etc/debian_version)
-LOWER_VENDOR?=		debian
+NATIVE_LOWER_VENDOR?=		debian
 .  elif exists(/etc/mandrake-release)
-LOWER_VENDOR?=		mandrake
+NATIVE_LOWER_VENDOR?=		mandrake
 .  elif exists(/etc/redhat-version) || exists(/etc/redhat-release)
-LOWER_VENDOR?=		redhat
+NATIVE_LOWER_VENDOR?=		redhat
 .  elif exists(/etc/slackware-version)
-LOWER_VENDOR?=		slackware
+NATIVE_LOWER_VENDOR?=		slackware
 .  elif exists(/etc/ssdlinux_version)
-LOWER_VENDOR?=		ssd
+NATIVE_LOWER_VENDOR?=		ssd
 .  elif !empty(CHROMEOS_RELEASE_NAME)
-LOWER_VENDOR?=		chromeos
-.  elif ${MACHINE_ARCH} == "i386"
-LOWER_VENDOR?=          pc
+NATIVE_LOWER_VENDOR?=		chromeos
+.  elif ${NATIVE_MACHINE_ARCH} == "i386"
+NATIVE_LOWER_VENDOR?=          pc
 .  endif
-LOWER_VENDOR?=          unknown
-OS_VARIANT!=		${UNAME} -r
-OS_VARIANT:=		${OS_VARIANT:C/^.*-//}
-.  if ${OS_VARIANT} != "Microsoft"
-OS_VARIANT=		${LOWER_VENDOR}
+NATIVE_LOWER_VENDOR?=          unknown
+NATIVE_OS_VARIANT!=		${UNAME} -r
+NATIVE_OS_VARIANT:=		${NATIVE_OS_VARIANT:C/^.*-//}
+.  if ${NATIVE_OS_VARIANT} != "Microsoft"
+NATIVE_OS_VARIANT=		${NATIVE_LOWER_VENDOR}
 .  endif
+# XXX NATIVE_HOST_MACHINE_ARCH?  ???
 .  if !defined(HOST_MACHINE_ARCH)
 HOST_MACHINE_ARCH!=	${UNAME} -m
 MAKEFLAGS+=		HOST_MACHINE_ARCH=${HOST_MACHINE_ARCH:Q}
 .  endif
 
-.elif ${OPSYS} == "OpenBSD"
-LOWER_OPSYS?= 		openbsd
-
-.elif ${OPSYS} == "OSF1"
-OS_VERSION:=		${OS_VERSION:C/^V//}
-LOWER_OPSYS?=		osf1
-LOWER_OPSYS_VERSUFFIX?=	${OS_VERSION}
-LOWER_VENDOR?=		dec
-
-.elif ${OPSYS} == "HPUX"
-OS_VERSION:=		${OS_VERSION:C/^B.//}
-LOWER_OPSYS?=		hpux
-LOWER_OPSYS_VERSUFFIX?=	${OS_VERSION}
-LOWER_VENDOR?=		hp
-
-.elif ${OPSYS} == "SunOS"
-LOWER_VENDOR?=		sun
-LOWER_OPSYS?=		solaris
-LOWER_OPSYS_VERSUFFIX=	2.${OS_VERSION:C/5.//}
+.elif ${NATIVE_OPSYS} == "OpenBSD"
+NATIVE_LOWER_OPSYS?= 		openbsd
+
+.elif ${NATIVE_OPSYS} == "OSF1"
+NATIVE_OS_VERSION:=		${NATIVE_OS_VERSION:C/^V//}
+NATIVE_LOWER_OPSYS?=		osf1
+NATIVE_LOWER_OPSYS_VERSUFFIX?=	${NATIVE_OS_VERSION}
+NATIVE_LOWER_VENDOR?=		dec
+
+.elif ${NATIVE_OPSYS} == "HPUX"
+NATIVE_OS_VERSION:=		${NATIVE_OS_VERSION:C/^B.//}
+NATIVE_LOWER_OPSYS?=		hpux
+NATIVE_LOWER_OPSYS_VERSUFFIX?=	${NATIVE_OS_VERSION}
+NATIVE_LOWER_VENDOR?=		hp
+
+.elif ${NATIVE_OPSYS} == "SunOS"
+NATIVE_LOWER_VENDOR?=		sun
+NATIVE_LOWER_OPSYS?=		solaris
+NATIVE_LOWER_OPSYS_VERSUFFIX=	2.${NATIVE_OS_VERSION:C/5.//}
 .  if !defined(_UNAME_V)
 _UNAME_V!=		${UNAME} -v
 MAKEFLAGS+=		_UNAME_V=${_UNAME_V:Q}
 .  endif
 .  if !empty(_UNAME_V:Mjoyent_*)
-OS_VARIANT=		SmartOS
-LOWER_VARIANT_VERSION=	${_UNAME_V:C/joyent_//}
+NATIVE_OS_VARIANT=		SmartOS
+NATIVE_LOWER_VARIANT_VERSION=	${_UNAME_V:C/joyent_//}
 .  elif !empty(_UNAME_V:Momnios-*)
-OS_VARIANT=		OmniOS
-LOWER_VARIANT_VERSION!=	/usr/bin/awk '{ print $$3; exit 0; }' /etc/release
+NATIVE_OS_VARIANT=		OmniOS
+NATIVE_LOWER_VARIANT_VERSION!=	/usr/bin/awk '{ print $$3; exit 0; }' /etc/release
 .  elif !empty(_UNAME_V:Mtribblix-*)
-OS_VARIANT=		Tribblix
-LOWER_VARIANT_VERSION!=	/usr/bin/awk '{ print $$2; exit 0; }' /etc/release
+NATIVE_OS_VARIANT=		Tribblix
+NATIVE_LOWER_VARIANT_VERSION!=	/usr/bin/awk '{ print $$2; exit 0; }' /etc/release
 .  else
-OS_VARIANT=		Solaris
-LOWER_VARIANT_VERSION=	${_UNAME_V}
+NATIVE_OS_VARIANT=		Solaris
+NATIVE_LOWER_VARIANT_VERSION=	${_UNAME_V}
 .  endif
 
 .elif ${OPSYS} == "SCO_SV"
-SCO_RELEASE!=		${UNAME} -r
-SCO_VERSION!=		${UNAME} -v
-LOWER_VENDOR?=		pc
-LOWER_OPSYS?=		sco
-LOWER_OPSYS_VERSUFFIX=	${SCO_RELEASE}v${SCO_VERSION}
-_UNAME_V!=		${UNAME} -v
+SCO_RELEASE!=			${UNAME} -r
+SCO_VERSION!=			${UNAME} -v
+NATIVE_LOWER_VENDOR?=		pc
+NATIVE_LOWER_OPSYS?=		sco
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${SCO_RELEASE}v${SCO_VERSION}
+_UNAME_V!=			${UNAME} -v
 .  if !empty(_UNAME_V:M5.0*)
-OS_VARIANT=		SCOOSR5
+NATIVE_OS_VARIANT=		SCOOSR5
 .  elif !empty(_UNAME_V:M6.0*)
-OS_VARIANT=		SCOOSR6
+NATIVE_OS_VARIANT=		SCOOSR6
 .  endif
 
-.elif ${OPSYS} == "UnixWare"
-SCO_RELEASE?=		sysv5${OPSYS}
-SCO_VERSION!=		${UNAME} -v
-LOWER_VENDOR?=		unknown
-LOWER_OPSYS_VERSUFFIX=	${SCO_RELEASE}${SCO_VERSION}
+.elif ${NATIVE_OPSYS} == "UnixWare"
+SCO_RELEASE?=			sysv5${NATIVE_OPSYS}
+SCO_VERSION!=			${UNAME} -v
+NATIVE_LOWER_VENDOR?=		unknown
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${SCO_RELEASE}${SCO_VERSION}
 
-.elif ${OPSYS} == "Minix"
-LOWER_VENDOR?=		unknown
-LOWER_OPSYS:=		${OPSYS:tl}
+.elif ${NATIVE_OPSYS} == "Minix"
+NATIVE_LOWER_VENDOR?=		unknown
+NATIVE_LOWER_OPSYS:=		${NATIVE_OPSYS:tl}
 
-.elif !defined(LOWER_OPSYS)
-LOWER_OPSYS:=		${OPSYS:tl}
+.elif !defined(NATIVE_LOWER_OPSYS)
+NATIVE_LOWER_OPSYS:=		${NATIVE_OPSYS:tl}
 .endif
 
 # Now commit the version values computed above, eliding the :sh
-OS_VERSION:=		${OS_VERSION}
-
-MAKEFLAGS+=		LOWER_OPSYS=${LOWER_OPSYS:Q}
-
-LOWER_VENDOR?=			# empty ("arch--opsys")
-
+NATIVE_OS_VERSION:=	${NATIVE_OS_VERSION}
+
+MAKEFLAGS+=		NATIVE_LOWER_OPSYS=${NATIVE_LOWER_OPSYS:Q}
+
+NATIVE_LOWER_VENDOR?=	# empty ("arch--opsys")
+
+# List of variables that must be set to determine a cross-compilation
+# target.
+CROSSVARS?=	# empty
+
+# Cross-compilation target settings.
+CROSSVARS+=	OPSYS
+OPSYS=			\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OPSYS}:${NATIVE_OPSYS}}
+CROSSVARS+=	OS_VERSION
+OS_VERSION=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OS_VERSION}:${NATIVE_OS_VERSION}}
+CROSSVARS+=	OPSYS_VERSION
+OPSYS_VERSION=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OPSYS_VERSION}:${NATIVE_OPSYS_VERSION}}
+CROSSVARS+=	LOWER_OPSYS
+LOWER_OPSYS=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_LOWER_OPSYS}:${NATIVE_LOWER_OPSYS}}
+CROSSVARS+=	LOWER_OPSYS_VERSUFFIX
+LOWER_OPSYS_VERSUFFIX=	\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_LOWER_OPSYS_VERSUFFIX}:${NATIVE_LOWER_OPSYS_VERSUFFIX}}
+CROSSVARS+=	LOWER_VARIANT_VERSION
+LOWER_VARIANT_VERSION=	\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_LOWER_VARIANT_VERSION}:${NATIVE_LOWER_VARIANT_VERSION}}
+CROSSVARS+=	LOWER_VENDOR
+LOWER_VENDOR=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_LOWER_VENDOR}:${NATIVE_LOWER_VENDOR}}
+CROSSVARS+=	LOWER_OS_VARIANT
+OS_VARIANT=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OS_VARIANT}:${NATIVE_OS_VARIANT}}
+
+# Remember the MACHINE_ARCH that make was built with before we override
+# it with CROSS_MACHINE_ARCH if USE_CROSS_COMPILE is enabled.
+CROSSVARS+=	MACHINE_ARCH
 NATIVE_MACHINE_ARCH:=		${MACHINE_ARCH}
+
 NATIVE_MACHINE_PLATFORM?=	${OPSYS}-${OS_VERSION}-${NATIVE_MACHINE_ARCH}
 MACHINE_PLATFORM?=		${OPSYS}-${OS_VERSION}-${MACHINE_ARCH}
-NATIVE_MACHINE_GNU_PLATFORM?=	${NATIVE_MACHINE_GNU_ARCH}-${LOWER_VENDOR}-${LOWER_OPSYS:C/[0-9]//g}${NATIVE_APPEND_ELF}${LOWER_OPSYS_VERSUFFIX}${NATIVE_APPEND_ABI}
+NATIVE_MACHINE_GNU_PLATFORM?=	${NATIVE_MACHINE_GNU_ARCH}-${NATIVE_LOWER_VENDOR}-${NATIVE_LOWER_OPSYS:C/[0-9]//g}${NATIVE_APPEND_ELF}${NATIVE_LOWER_OPSYS_VERSUFFIX}${NATIVE_APPEND_ABI}
 MACHINE_GNU_PLATFORM?=		${MACHINE_GNU_ARCH}-${LOWER_VENDOR}-${LOWER_OPSYS:C/[0-9]//g}${APPEND_ELF}${LOWER_OPSYS_VERSUFFIX}${APPEND_ABI}
 
 # Set this before <bsd.own.mk> does, since it doesn't know about Darwin
-.if ${OPSYS} == "Darwin"
+# We will later set OBJECT_FMT to be conditional on USE_CROSS_COMPILE.
+.if ${NATIVE_OPSYS} == "Darwin"
+NATIVE_OBJECT_FMT?=	Mach-O
 OBJECT_FMT?=		Mach-O
 .endif
 
@@ -368,6 +405,9 @@ PKG_FAIL_REASON+=	"Must set TARGET_ARCH for cross-libtool."
 MACHINE_ARCH:=			${TARGET_ARCH}
 _BUILD_DEFS.MACHINE_ARCH=	${NATIVE_MACHINE_ARCH}
 _BUILD_DEFS.MACHINE_GNU_ARCH=	${NATIVE_MACHINE_GNU_ARCH}
+_BUILD_DEFS.OBJECT_FMT=		${NATIVE_OBJECT_FMT}
+_BUILD_DEFS.OPSYS=		${NATIVE_OPSYS}
+_BUILD_DEFS.OS_VERSION=		${NATIVE_OS_VERSION}
 TOOLS_USE_CROSS_COMPILE=	yes
 .else
 TOOLS_USE_CROSS_COMPILE=	${USE_CROSS_COMPILE:Uno}
@@ -389,9 +429,17 @@ PKGPATH?=		${.CURDIR:C|.*/([^/]*/[^/]*)$|\1|}
 # Load the settings from MAKECONF, which is /etc/mk.conf by default.
 .include <bsd.own.mk>
 
+# Save the OBJECT_FMT determined by bsd.own.mk, and turn OBJECT_FMT
+# into a cross-compilation variable so it can be overridden by
+# CROSS_OBJECT_FMT.
+NATIVE_OBJECT_FMT:=	${OBJECT_FMT}
+CROSSVARS+=		OBJECT_FMT
+OBJECT_FMT=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OBJECT_FMT}:${NATIVE_OBJECT_FMT}}
+
 # When cross-compilation support is requested, the following options
 # must be specified as well or guessable:
-# - MACHINE_ARCH is set to TARGET_ARCH if set.
+# - Variables like MACHINE_ARCH are set to CROSS_MACHINE_ARCH.
 # - CROSS_DESTDIR is guessed from MAKEOBJDIR and MACHINE_ARCH.
 # - PKG_DBDIR is expanded and prefixed with CROSS_DESTDIR
 # - DESTDIR support is required
@@ -399,9 +447,16 @@ PKGPATH?=		${.CURDIR:C|.*/([^/]*/[^/]*)$|\1|}
 # _CROSS_DESTDIR is set for internal use to avoid conditionalising
 # the use.
 
-.if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-.  if defined(TARGET_ARCH)
-MACHINE_ARCH=	${TARGET_ARCH}
+.if ${USE_CROSS_COMPILE:U:tl} == "yes" # defaults/mk.conf not yet loaded, so :U
+.  for _v_ in ${CROSSVARS}
+.    ifndef CROSS_${_v_}
+MISSING_CROSSVARS=	yes
+.      warning Missing CROSS_${_v_} setting
+.    endif
+${_v_}:=	${CROSS_${_v_}}
+.  endfor
+.  ifdef MISSING_CROSSVARS
+.    error USE_CROSS_COMPILE=yes but missing cross variable settings
 .  endif
 CROSS_DESTDIR?=	${MAKEOBJDIR}/destdir.${MACHINE_ARCH}
 .  if !exists(${CROSS_DESTDIR}/usr/include/stddef.h)
@@ -562,9 +617,6 @@ TOOLS_CROSS_DESTDIR=		# empty
 
 # Depends on MACHINE_ARCH override above
 .if ${OPSYS} == "NetBSD"
-# XXX NATIVE_OBJECT_FMT is a cop-out -- but seriously, who is going to
-# do cross-builds on a NetBSD host that still uses a.out?
-NATIVE_OBJECT_FMT?=	${OBJECT_FMT}
 .  if ${NATIVE_OBJECT_FMT} == "ELF" && \
    (!empty(NATIVE_MACHINE_ARCH:Mearm*) || \
     ${NATIVE_MACHINE_GNU_ARCH} == "arm" || \
diff --git a/mk/tools/cross.NetBSD.mk b/mk/tools/cross.NetBSD.mk
new file mode 100644
index 000000000000..df739ba84035
--- /dev/null
+++ b/mk/tools/cross.NetBSD.mk
@@ -0,0 +1,25 @@
+# $NetBSD$
+#
+# Cross-compiler toolchain for the NetBSD operating system.  Requires
+# TOOLDIR to match build.sh for a NetBSD build.
+
+TOOLS_PLATFORM.install?=	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-install
+TOOLS_PLATFORM.readelf?=	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-readelf
+TOOLS_PLATFORM.strip?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-strip
+
+.for _t_ in ar as ld nm objcopy objdump ranlib readelf strip
+TOOLS_PATH.${MACHINE_GNU_PLATFORM}-${_t_}?=	\
+	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-${_t_}
+TOOLS_CREATE+=	${MACHINE_GNU_PLATFORM}-${_t_}
+.endfor
+
+TOOLS_PATH.ar?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ar
+TOOLS_CREATE+=			ar
+TOOLS_PATH.ranlib?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ranlib
+TOOLS_CREATE+=			ranlib
+TOOLS_PATH.readelf?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-readelf
+TOOLS_CREATE+=			readelf
+
+CC=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-gcc
+CXX=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-g++
+LD=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ld
diff --git a/mk/tools/defaults.mk b/mk/tools/defaults.mk
index 5b49c4224d72..51d956f1ae81 100644
--- a/mk/tools/defaults.mk
+++ b/mk/tools/defaults.mk
@@ -34,10 +34,17 @@ TOOLS_DEFAULTS_MK=	defined
 # These are the platform-specific lists of system-supplied tools.
 #
 # XXX These should eventually just migrate over to the appropriate
-# XXX pkgsrc/mk/platform/${OPSYS}.mk file.
+# XXX pkgsrc/mk/platform/${NATIVE_OPSYS}.mk file.
 #
-.if exists(${_PKGSRC_TOPDIR}/mk/tools/tools.${OPSYS}.mk)
-.  include "${_PKGSRC_TOPDIR}/mk/tools/tools.${OPSYS}.mk"
+# XXX Use ${OPSYS} for :run tools, but ${NATIVE_OPSYS} for :build and
+# XXX :bootstrap tools.
+#
+.if ${TOOLS_USE_CROSS_COMPILE:tl} == "yes" && \
+    exists(${_PKGSRC_TOPDIR}/mk/tools/cross.${OPSYS}.mk)
+.  include "${_PKGSRC_TOPDIR}/mk/tools/cross.${OPSYS}.mk"
+.endif
+.if exists(${_PKGSRC_TOPDIR}/mk/tools/tools.${NATIVE_OPSYS}.mk)
+.  include "${_PKGSRC_TOPDIR}/mk/tools/tools.${NATIVE_OPSYS}.mk"
 .endif
 
 ######################################################################
diff --git a/mk/tools/tools.NetBSD.mk b/mk/tools/tools.NetBSD.mk
index 2d4de5afe264..387367f36531 100644
--- a/mk/tools/tools.NetBSD.mk
+++ b/mk/tools/tools.NetBSD.mk
@@ -58,11 +58,7 @@ TOOLS_PLATFORM.head?=		/usr/bin/head
 TOOLS_PLATFORM.hostname?=	/bin/hostname
 TOOLS_PLATFORM.id?=		/usr/bin/id
 TOOLS_PLATFORM.ident?=		/usr/bin/ident
-.if ${TOOLS_USE_CROSS_COMPILE:tl} != yes
 TOOLS_PLATFORM.install?=	/usr/bin/install
-.else
-TOOLS_PLATFORM.install?=	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-install
-.endif
 .if exists(/usr/bin/install-info)
 TOOLS_PLATFORM.install-info?=	/usr/bin/install-info
 .endif
@@ -102,11 +98,7 @@ TOOLS_PLATFORM.paxctl?=		/usr/sbin/paxctl
 .endif
 TOOLS_PLATFORM.printf?=		/usr/bin/printf
 TOOLS_PLATFORM.pwd?=		/bin/pwd
-.if ${TOOLS_USE_CROSS_COMPILE:U:tl} != yes
 TOOLS_PLATFORM.readelf?=	/usr/bin/readelf
-.else
-TOOLS_PLATFORM.readelf?=	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-readelf
-.endif
 TOOLS_PLATFORM.readlink?=	/usr/bin/readlink
 .if exists(/usr/bin/realpath)
 TOOLS_PLATFORM.realpath?=	/usr/bin/realpath
@@ -120,11 +112,7 @@ TOOLS_PLATFORM.shlock?=		/usr/bin/shlock
 TOOLS_PLATFORM.sleep?=		/bin/sleep
 TOOLS_PLATFORM.soelim?=		/usr/bin/soelim
 TOOLS_PLATFORM.sort?=		/usr/bin/sort
-.if ${TOOLS_USE_CROSS_COMPILE:U:tl} != yes
 TOOLS_PLATFORM.strip?=		/usr/bin/strip
-.else
-TOOLS_PLATFORM.strip?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-strip
-.endif
 
 TOOLS_PLATFORM.tail?=		/usr/bin/tail
 .if exists(/bin/tar)
@@ -157,29 +145,9 @@ TOOLS_PLATFORM.xzcat?=		/usr/bin/xzcat
 TOOLS_PLATFORM.yacc?=		/usr/bin/yacc
 
 .if ${TOOLS_USE_CROSS_COMPILE:U:tl} == yes
-.  for _t_ in ar as ld nm objcopy objdump ranlib readelf strip
-TOOLS_PATH.${MACHINE_GNU_PLATFORM}-${_t_}?=	\
-	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-${_t_}
-TOOLS_CREATE+=	${MACHINE_GNU_PLATFORM}-${_t_}
-.  endfor
-
-TOOLS_PATH.ar?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ar
-TOOLS_CREATE+=			ar
-TOOLS_PATH.ranlib?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ranlib
-TOOLS_CREATE+=			ranlib
-TOOLS_PATH.readelf?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-readelf
-TOOLS_CREATE+=			readelf
-
 NATIVE_CC:=	/usr/bin/cc -B /usr/libexec -B /usr/bin
-CC=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-gcc
-
 NATIVE_CXX:=	/usr/bin/c++ -B /usr/libexec -B /usr/bin
-CXX=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-g++
-
 NATIVE_LD:=	/usr/bin/ld
-LD=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ld
-
 NATIVE_AR:=	/usr/bin/ar
 NATIVE_RANLIB:=	/usr/bin/ranlib
-
 .endif

>From 674fa99e6f8c13b603a61b9ad37da62c2adca546 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Wed, 28 Jun 2023 23:53:26 +0000
Subject: [PATCH 04/13] mk: Pass through all CROSSVARS as TARGET_* for tool
 depends.

Use this for cross-libtool-base.

Name it cross-libtool-base-${MACHINE_PLATFORM} instead of
cross-libtool-base-${MACHINE_ARCH}.  MACHINE_GNU_PLATFORM isn't quite
enough, because it doesn't reflect OS versions (e.g., aarch64--netbsd
covers both NetBSD 9 and NetBSD 10).

No functional change intended in native builds -- everything here is
conditional on cross builds.  The _DEPENDS_INSTALL_CMD shell fragment
is changed in native builds, but only to move around some of the
shell-based cross-build fragments (which could maybe be factored out
to save a bit of shell execution in native builds, but that's for
another day).

XXX MACHINE_PLATFORM doesn't cover all the other little exotic OS
knobs like LOWER_OPSYS_VERSUFFIX.  Do we care?
---
 cross/cross-libtool-base/Makefile |  13 ++--
 cross/cross-libtool-base/PLIST    | 108 +++++++++++++++---------------
 doc/HOWTO-dev-crosscompile        |  46 +++++++------
 mk/bsd.pkg.use.mk                 |   6 +-
 mk/bsd.prefs.mk                   |  42 ++++++++++--
 mk/pkgformat/pkg/depends.mk       |  18 +++--
 6 files changed, 138 insertions(+), 95 deletions(-)

diff --git a/cross/cross-libtool-base/Makefile b/cross/cross-libtool-base/Makefile
index c2b4abedd693..4fbeb7a2c165 100644
--- a/cross/cross-libtool-base/Makefile
+++ b/cross/cross-libtool-base/Makefile
@@ -37,7 +37,7 @@ LIBTOOL_CROSS_COMPILE=	yes
 
 # XXX Tweaked for cross-compilation.
 #PKGNAME=	${DISTNAME:S/-/-base-/}
-PKGNAME=	${DISTNAME:S/^libtool-/cross-libtool-base-${MACHINE_ARCH}-/}
+PKGNAME=	${DISTNAME:S/^libtool-/cross-libtool-base-${MACHINE_PLATFORM}-/}
 PKGREVISION=	8
 
 COMMENT=	Generic shared library support script (the script itself)
@@ -64,10 +64,11 @@ CFLAGS.SunOS+=	${_COMPILER_ABI_FLAG.${ABI}}
 # and Fortran compilers.
 #
 USE_LANGUAGES=		c c++
-# XXX Added for cross-compilation.  XXX Should be ${TARGET_ARCH}, but
-# currently we have to fake-cross-compile libtool because it's broken
-# upstream.
-GNU_CONFIGURE_PREFIX=	${PREFIX}/cross-${MACHINE_ARCH}
+# XXX Added for cross-compilation.  XXX Should be
+# ${TARGET_MACHINE_PLATFORM}, but currently we have to
+# fake-cross-compile libtool because it's broken upstream.
+GNU_CONFIGURE_PREFIX=	${PREFIX}/cross-${MACHINE_PLATFORM}
+PLIST_SUBST+=		MACHINE_PLATFORM=${MACHINE_PLATFORM:Q}
 CONFIGURE_ARGS+=	--disable-ltdl-install
 CONFIGURE_ARGS+=	F77=no FC=no
 
@@ -96,7 +97,7 @@ post-build:
 		${FILESDIR}/shlibtool.in > ${WRKSRC}/shlibtool
 
 post-install:
-	${INSTALL_SCRIPT} ${WRKSRC}/shlibtool ${DESTDIR}${PREFIX}/cross-${MACHINE_ARCH}/bin/shlibtool
+	${INSTALL_SCRIPT} ${WRKSRC}/shlibtool ${DESTDIR}${PREFIX}/cross-${MACHINE_PLATFORM}/bin/shlibtool
 
 BUILDLINK_DEPMETHOD.dlcompat=	build
 
diff --git a/cross/cross-libtool-base/PLIST b/cross/cross-libtool-base/PLIST
index a1db9768dde3..c78dfac0fcb5 100644
--- a/cross/cross-libtool-base/PLIST
+++ b/cross/cross-libtool-base/PLIST
@@ -1,55 +1,55 @@
 @comment $NetBSD: PLIST,v 1.3 2019/07/09 15:45:25 riastradh Exp $
-cross-${MACHINE_ARCH}/bin/libtool
-cross-${MACHINE_ARCH}/bin/libtoolize
-cross-${MACHINE_ARCH}/bin/shlibtool
-cross-${MACHINE_ARCH}/man/man1/libtool.1
-cross-${MACHINE_ARCH}/man/man1/libtoolize.1
-cross-${MACHINE_ARCH}/share/aclocal/libtool.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltargz.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltdl.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltoptions.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltsugar.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltversion.m4
-cross-${MACHINE_ARCH}/share/aclocal/lt~obsolete.m4
-cross-${MACHINE_ARCH}/share/libtool/COPYING.LIB
-cross-${MACHINE_ARCH}/share/libtool/Makefile.am
-cross-${MACHINE_ARCH}/share/libtool/Makefile.in
-cross-${MACHINE_ARCH}/share/libtool/README
-cross-${MACHINE_ARCH}/share/libtool/aclocal.m4
-cross-${MACHINE_ARCH}/share/libtool/build-aux/compile
-cross-${MACHINE_ARCH}/share/libtool/build-aux/config.guess
-cross-${MACHINE_ARCH}/share/libtool/build-aux/config.sub
-cross-${MACHINE_ARCH}/share/libtool/build-aux/depcomp
-cross-${MACHINE_ARCH}/share/libtool/build-aux/install-sh
-cross-${MACHINE_ARCH}/share/libtool/build-aux/ltmain.sh
-cross-${MACHINE_ARCH}/share/libtool/build-aux/missing
-cross-${MACHINE_ARCH}/share/libtool/config-h.in
-cross-${MACHINE_ARCH}/share/libtool/configure
-cross-${MACHINE_ARCH}/share/libtool/configure.ac
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__alloc.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__argz_.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__dirent.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__glibc.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__private.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__strl.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt_dlloader.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt_error.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt_system.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/slist.h
-cross-${MACHINE_ARCH}/share/libtool/loaders/dld_link.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/dlopen.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/dyld.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/load_add_on.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/loadlibrary.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/preopen.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/shl_load.c
-cross-${MACHINE_ARCH}/share/libtool/lt__alloc.c
-cross-${MACHINE_ARCH}/share/libtool/lt__argz.c
-cross-${MACHINE_ARCH}/share/libtool/lt__dirent.c
-cross-${MACHINE_ARCH}/share/libtool/lt__strl.c
-cross-${MACHINE_ARCH}/share/libtool/lt_dlloader.c
-cross-${MACHINE_ARCH}/share/libtool/lt_error.c
-cross-${MACHINE_ARCH}/share/libtool/ltdl.c
-cross-${MACHINE_ARCH}/share/libtool/ltdl.h
-cross-${MACHINE_ARCH}/share/libtool/ltdl.mk
-cross-${MACHINE_ARCH}/share/libtool/slist.c
+cross-${MACHINE_PLATFORM}/bin/libtool
+cross-${MACHINE_PLATFORM}/bin/libtoolize
+cross-${MACHINE_PLATFORM}/bin/shlibtool
+cross-${MACHINE_PLATFORM}/man/man1/libtool.1
+cross-${MACHINE_PLATFORM}/man/man1/libtoolize.1
+cross-${MACHINE_PLATFORM}/share/aclocal/libtool.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltargz.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltdl.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltoptions.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltsugar.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltversion.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/lt~obsolete.m4
+cross-${MACHINE_PLATFORM}/share/libtool/COPYING.LIB
+cross-${MACHINE_PLATFORM}/share/libtool/Makefile.am
+cross-${MACHINE_PLATFORM}/share/libtool/Makefile.in
+cross-${MACHINE_PLATFORM}/share/libtool/README
+cross-${MACHINE_PLATFORM}/share/libtool/aclocal.m4
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/compile
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/config.guess
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/config.sub
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/depcomp
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/install-sh
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/ltmain.sh
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/missing
+cross-${MACHINE_PLATFORM}/share/libtool/config-h.in
+cross-${MACHINE_PLATFORM}/share/libtool/configure
+cross-${MACHINE_PLATFORM}/share/libtool/configure.ac
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__alloc.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__argz_.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__dirent.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__glibc.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__private.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__strl.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt_dlloader.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt_error.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt_system.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/slist.h
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/dld_link.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/dlopen.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/dyld.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/load_add_on.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/loadlibrary.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/preopen.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/shl_load.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt__alloc.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt__argz.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt__dirent.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt__strl.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt_dlloader.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt_error.c
+cross-${MACHINE_PLATFORM}/share/libtool/ltdl.c
+cross-${MACHINE_PLATFORM}/share/libtool/ltdl.h
+cross-${MACHINE_PLATFORM}/share/libtool/ltdl.mk
+cross-${MACHINE_PLATFORM}/share/libtool/slist.c
diff --git a/doc/HOWTO-dev-crosscompile b/doc/HOWTO-dev-crosscompile
index e1cbd3c57f69..1de740a04eee 100644
--- a/doc/HOWTO-dev-crosscompile
+++ b/doc/HOWTO-dev-crosscompile
@@ -11,34 +11,42 @@ have ever thought of cross-compilation.
 
 * Native and target platform
 
-When building a package, MACHINE_ARCH, MACHINE_GNU_PLATFORM, &c.,
-describe the platform for which the package is being built.  If
+When building a package, MACHINE_ARCH, OPSYS, &c., describe the
+platform for which the package is being built.  If
 USE_CROSS_COMPILE=no, this is the native platform; otherwise, if
-USE_CROSS_COMPILE=yes, it is the target platform, and the additional
-variables NATIVE_MACHINE_ARCH, NATIVE_MACHINE_GNU_PLATFORM, &c.,
-describe the native platform.
+USE_CROSS_COMPILE=yes, it is the target platform.  The additional
+variables NATIVE_MACHINE_ARCH, NATIVE_OPSYS, &c., always describe the
+native platform.
 
 When building a native package for cross-compilation, such as a
-compiler for the target, the variable TARGET_ARCH describes the target
-platform like MACHINE_ARCH.  If the build product varies with the
-choice of target, then TARGET_ARCH should be embedded into the PKGNAME
+compiler for the target, the variables TARGET_MACHINE_ARCH,
+TARGET_OPSYS, &c., describe the target platform.  If the build product
+varies with the choice of target, then TARGET_MACHINE_ARCH or
+TARGET_OPSYS or whatever affects it should be embedded into the PKGNAME
 somewhere so that the different build products are distinguished by
 having different package names.
 
-XXX This pattern is incompletely realized.  We should probably replace
-TARGET_ARCH by TARGET_MACHINE_ARCH, TARGET_MACHINE_GNU_PLATFORM, &c.,
-and perhaps decide which of those is the main switch that you set when
-you want to select cross-compilation.  Ideally, this switch should
-also support cross-compilation to other operating systems.
+XXX Missing:
+XXX - TARGET_MACHINE_GNU_PLATFORM
+XXX - TARGET_MACHINE_GNU_ARCH
+XXX - probably other variables defined in terms of the CROSSVARS
 
 * Specifying the toolchain
 
-Software built following GNU conventions can set GNU_CONFIGURE=yes so
-that pkgsrc will automatically specify the right --build, --host, and
---target options for cross-compilation and point everything at the
-right toolchain.
+The following build systems should automagically handle
+cross-compilation by passing through the architecture and OS
+information:
 
-XXX And software not built following GNU conventions...?
+- GNU_CONFIGURE=yes
+- .include "../../devel/meson/build.mk" (sets
+- .include "../../devel/cmake/build.mk" (and legacy USE_CMAKE=yes)
+
+Additional tweaks are sometimes needed (but not always), conditional on
+${USE_CROSS_COMPILE:tl} == "yes" (after including bsd.prefs.mk):
+
+- (pkg-config) ALL_ENV+= PKG_CONFIG_SYSROOT_DIR=${CROSS_DESTDIR:Q}
+- (pkg-config) ALL_ENV+= PKG_CONFIG_FDO_SYSROOT_RULES=1
+- (cmake) CMAKE_ARGS+= -DCMAKE_SYSROOT:STRING=${CROSS_DESTDIR:Q}
 
 * Tool dependencies
 
@@ -107,7 +115,7 @@ pre-answer the tests for autoconf:
 
 .include "../../bsd.prefs.mk"
 
-.if ${USE_CROSS_COMPILE:U:tl} == "yes"
+.if ${USE_CROSS_COMPILE:tl} == "yes"
 # Configure wants to check for /dev/random but can't.  We know NetBSD
 # always has a /dev/random, so inform autoconf of the fact.
 CONFIGURE_ENV.NetBSD+=	ac_cv_file__dev_random=yes
diff --git a/mk/bsd.pkg.use.mk b/mk/bsd.pkg.use.mk
index 03ee7cbf1323..30728ebc4bf7 100644
--- a/mk/bsd.pkg.use.mk
+++ b/mk/bsd.pkg.use.mk
@@ -91,8 +91,8 @@ TOOL_DEPENDS+=		libtool-fortran>=${_OPSYS_LIBTOOL_REQD:U${LIBTOOL_REQD}}:../../d
 .  endif
 .else
 .  if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-PKG_LIBTOOL?=		${TOOLBASE}/cross-${TARGET_ARCH:U${MACHINE_ARCH}}/bin/libtool
-PKG_SHLIBTOOL?=		${TOOLBASE}/cross-${TARGET_ARCH:U${MACHINE_ARCH}}/bin/shlibtool
+PKG_LIBTOOL?=		${TOOLBASE}/cross-${TARGET_MACHINE_PLATFORM:U${MACHINE_PLATFORM}}/bin/libtool
+PKG_SHLIBTOOL?=		${TOOLBASE}/cross-${TARGET_MACHINE_PLATFORM:U${MACHINE_PLATFORM}}/bin/shlibtool
 .  else
 PKG_LIBTOOL?=		${TOOLBASE}/bin/libtool
 PKG_SHLIBTOOL?=		${TOOLBASE}/bin/shlibtool
@@ -103,7 +103,7 @@ SHLIBTOOL?=		${WRAPPER_BINDIR}/shlibtool
 .if defined(USE_LIBTOOL)
 LIBTOOL_REQD?=		2.4.2nb9
 .if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-TOOL_DEPENDS+=		cross-libtool-base-${MACHINE_ARCH}>=${_OPSYS_LIBTOOL_REQD:U${LIBTOOL_REQD}}:../../cross/cross-libtool-base
+TOOL_DEPENDS+=		cross-libtool-base-${MACHINE_PLATFORM}>=${_OPSYS_LIBTOOL_REQD:U${LIBTOOL_REQD}}:../../cross/cross-libtool-base
 .else
 TOOL_DEPENDS+=		libtool-base>=${_OPSYS_LIBTOOL_REQD:U${LIBTOOL_REQD}}:../../devel/libtool-base
 .endif
diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index 47be8aee8479..a1372eef505d 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -376,6 +376,12 @@ MACHINE_PLATFORM?=		${OPSYS}-${OS_VERSION}-${MACHINE_ARCH}
 NATIVE_MACHINE_GNU_PLATFORM?=	${NATIVE_MACHINE_GNU_ARCH}-${NATIVE_LOWER_VENDOR}-${NATIVE_LOWER_OPSYS:C/[0-9]//g}${NATIVE_APPEND_ELF}${NATIVE_LOWER_OPSYS_VERSUFFIX}${NATIVE_APPEND_ABI}
 MACHINE_GNU_PLATFORM?=		${MACHINE_GNU_ARCH}-${LOWER_VENDOR}-${LOWER_OPSYS:C/[0-9]//g}${APPEND_ELF}${LOWER_OPSYS_VERSUFFIX}${APPEND_ABI}
 
+.ifdef TARGET_MACHINE_ARCH
+TARGET_MACHINE_GNU_ARCH=	${GNU_ARCH.${TARGET_MACHINE_ARCH}:U${TARGET_MACHINE_ARCH}}
+TARGET_MACHINE_GNU_PLATFORM=	${TARGET_MACHINE_GNU_ARCH}-${TARGET_LOWER_VENDOR}-${TARGET_LOWER_OPSYS:C/[0-9]//g}${TARGET_APPEND_ELF}${TARGET_LOWER_OPSYS_VERSUFFIX}${TARGET_APPEND_ABI}
+TARGET_MACHINE_PLATFORM=	${TARGET_OPSYS}-${TARGET_OS_VERSION}-${TARGET_MACHINE_ARCH}
+.endif
+
 # Set this before <bsd.own.mk> does, since it doesn't know about Darwin
 # We will later set OBJECT_FMT to be conditional on USE_CROSS_COMPILE.
 .if ${NATIVE_OPSYS} == "Darwin"
@@ -394,15 +400,18 @@ OBJECT_FMT?=		Mach-O
 # the rest of the native package build with USE_CROSS_COMPILE=no.
 #
 # This can't live inside the cross-libtool makefile because the
-# TARGET_ARCH / MACHINE_ARCH / NATIVE_MACHINE_ARCH switcheroo has to
-# happen in the middle of this file -- after NATIVE_MACHINE_ARCH is
-# determined, before MACHINE_ARCH is used for anything else.
+# TARGET_MACHINE_ARCH / MACHINE_ARCH / NATIVE_MACHINE_ARCH switcheroo
+# has to happen in the middle of this file -- after NATIVE_MACHINE_ARCH
+# is determined, before MACHINE_ARCH is used for anything else.
 #
-.if !empty(LIBTOOL_CROSS_COMPILE:M[yY][eE][sS])
-.  if !defined(TARGET_ARCH)
-PKG_FAIL_REASON+=	"Must set TARGET_ARCH for cross-libtool."
+.if ${LIBTOOL_CROSS_COMPILE:U:tl} == "yes"
+.  if !defined(TARGET_MACHINE_ARCH)
+PKG_FAIL_REASON+=	"Must set TARGET_MACHINE_ARCH for cross-libtool."
 .  endif
-MACHINE_ARCH:=			${TARGET_ARCH}
+.  for _v_ in ${CROSSVARS}
+${_v_}=				${TARGET_${_v_}}
+.  endfor
+# XXX Other CROSSVARS for _BUILD_DEFS?
 _BUILD_DEFS.MACHINE_ARCH=	${NATIVE_MACHINE_ARCH}
 _BUILD_DEFS.MACHINE_GNU_ARCH=	${NATIVE_MACHINE_GNU_ARCH}
 _BUILD_DEFS.OBJECT_FMT=		${NATIVE_OBJECT_FMT}
@@ -617,6 +626,9 @@ TOOLS_CROSS_DESTDIR=		# empty
 
 # Depends on MACHINE_ARCH override above
 .if ${OPSYS} == "NetBSD"
+.  ifdef TARGET_MACHINE_ARCH
+TARGET_OBJECT_FMT?=	${OBJECT_FMT} # XXX
+.  endif
 .  if ${NATIVE_OBJECT_FMT} == "ELF" && \
    (!empty(NATIVE_MACHINE_ARCH:Mearm*) || \
     ${NATIVE_MACHINE_GNU_ARCH} == "arm" || \
@@ -641,12 +653,28 @@ NATIVE_APPEND_ELF=	elf
     ${MACHINE_ARCH} == "vax")
 APPEND_ELF=		elf
 .  endif
+.  if defined(TARGET_MACHINE_ARCH) && \
+   ${TARGET_OBJECT_FMT} == "ELF" && \
+   (!empty(TARGET_MACHINE_ARCH:Mearm*) || \
+    ${TARGET_MACHINE_GNU_ARCH} == "arm" || \
+    ${TARGET_MACHINE_ARCH} == "i386" || \
+    ${TARGET_MACHINE_ARCH} == "m68k" || \
+    ${TARGET_MACHINE_ARCH} == "m68000" || \
+    ${TARGET_MACHINE_GNU_ARCH} == "sh" || \
+    ${TARGET_MACHINE_GNU_ARCH} == "shle" || \
+    ${TARGET_MACHINE_ARCH} == "sparc" || \
+    ${TARGET_MACHINE_ARCH} == "vax")
+TARGET_APPEND_ELF=	elf
+.  endif
 .  if !empty(NATIVE_MACHINE_ARCH:Mearm*)
 NATIVE_APPEND_ABI=	-${NATIVE_MACHINE_ARCH:C/eb//:C/v[4-7]//:S/earm/eabi/}
 .  endif
 .  if !empty(MACHINE_ARCH:Mearm*)
 APPEND_ABI=		-${MACHINE_ARCH:C/eb//:C/v[4-7]//:S/earm/eabi/}
 .  endif
+.  if !empty(TARGET_MACHINE_ARCH:Mearm*)
+TARGET_APPEND_ABI=	-${TARGET_MACHINE_ARCH:C/eb//:C/v[4-7]//:S/earm/eabi/}
+.  endif
 .endif
 
 # if the system is IPv6-ready, compile with IPv6 support turned on.
diff --git a/mk/pkgformat/pkg/depends.mk b/mk/pkgformat/pkg/depends.mk
index ed4674e63279..57b873186116 100644
--- a/mk/pkgformat/pkg/depends.mk
+++ b/mk/pkgformat/pkg/depends.mk
@@ -90,6 +90,8 @@ _RESOLVE_DEPENDS_CMD=	\
 			" "${BUILD_DEPENDS:Q} \
 			" "${DEPENDS:Q}
 
+CROSSTARGETSETTINGS=	${CROSSVARS:@_v_@TARGET_${_v_}=${${_v_}}@}
+
 # _DEPENDS_INSTALL_CMD checks whether the package $pattern is installed,
 #	and installs it if necessary.
 #
@@ -110,17 +112,20 @@ _DEPENDS_INSTALL_CMD=							\
 	case $$type in							\
 	bootstrap|tool)							\
 		case "${USE_CROSS_COMPILE:Uno:tl}" in			\
-		yes) extradep="" ;;					\
-		*) extradep=" ${PKGNAME}" ;;				\
+		yes)	extradep="";					\
+			crosstargetsettings=${CROSSTARGETSETTINGS:Q};	\
+			;;						\
+		*)	extradep=" ${PKGNAME}";				\
+			crosstargetsettings=;				\
+			;;						\
 		esac;							\
 		cross=no;						\
-		archopt=TARGET_ARCH=${MACHINE_ARCH};			\
 		pkg=`${_HOST_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`;	\
 		;;							\
-	build|test|full)							\
+	build|test|full)						\
 		extradep=" ${PKGNAME}";					\
+		crosstargetsettings=;					\
 		cross=${USE_CROSS_COMPILE:Uno};				\
-		archopt=;						\
 		pkg=`${_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`;	\
 		;;							\
 	esac;								\
@@ -133,11 +138,12 @@ _DEPENDS_INSTALL_CMD=							\
 		cd $$dir;						\
 		unset _PKGSRC_BARRIER;					\
 		unset MAKEFLAGS;					\
+		unset ${CROSSVARS:@_v_@TARGET_${_v_}@};			\
 		${PKGSRC_SETENV} ${PKGSRC_MAKE_ENV} PATH=${_PATH_ORIG:Q}\
 			_PKGSRC_DEPS="$$extradep${_PKGSRC_DEPS}"	\
 			PKGNAME_REQD="$$pattern"			\
 			USE_CROSS_COMPILE=$$cross			\
-			$$archopt					\
+			$$crosstargetsettings				\
 		    ${MAKE} ${MAKEFLAGS} _AUTOMATIC=yes $$target;	\
 		case $$type in						\
 		bootstrap|tool)						\

>From 9651fa710a8e525c196beab9b1e1eacb5ccecf6e Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Thu, 29 Jun 2023 00:38:40 +0000
Subject: [PATCH 05/13] mk/configure/gnu-configure.mk: Set --target too if
 requested.

No change to existing builds because nothing sets
USE_GNU_CONFIGURE_TARGET yet.
---
 mk/configure/gnu-configure.mk | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/mk/configure/gnu-configure.mk b/mk/configure/gnu-configure.mk
index 4a1ab41ba888..d13d3461ff0b 100644
--- a/mk/configure/gnu-configure.mk
+++ b/mk/configure/gnu-configure.mk
@@ -40,7 +40,7 @@ _PKG_VARS.gnu-configure=	\
 	GNU_CONFIGURE_LIBDIR GNU_CONFIGURE_INFODIR GNU_CONFIGURE_MANDIR \
 	CONFIGURE_HAS_LIBDIR CONFIGURE_HAS_MANDIR CONFIGURE_HAS_INFODIR \
 	OVERRIDE_DIRDEPTH.configure \
-	USE_GNU_CONFIGURE_HOST
+	USE_GNU_CONFIGURE_HOST USE_GNU_CONFIGURE_TARGET
 
 HAS_CONFIGURE=			defined
 OVERRIDE_GNU_CONFIG_SCRIPTS=	defined
@@ -85,6 +85,7 @@ CONFIGURE_ARGS+=	--libdir=${GNU_CONFIGURE_LIBDIR}
 .endif
 
 USE_GNU_CONFIGURE_HOST?=	yes
+USE_GNU_CONFIGURE_TARGET?=	no # enable for toolchain packages
 .if !empty(USE_GNU_CONFIGURE_HOST:M[yY][eE][sS])
 .  if !empty(TOOLS_USE_CROSS_COMPILE:M[yY][eE][sS])
 CONFIGURE_ARGS+=	--build=${NATIVE_MACHINE_GNU_PLATFORM:Q}
@@ -92,6 +93,9 @@ CONFIGURE_ARGS+=	--build=${NATIVE_MACHINE_GNU_PLATFORM:Q}
 CONFIGURE_ARGS+=	--build=${MACHINE_GNU_PLATFORM:Q}
 .  endif
 CONFIGURE_ARGS+=	--host=${MACHINE_GNU_PLATFORM:Q}
+.  if ${USE_GNU_CONFIGURE_TARGET:tl} == "yes"
+CONFIGURE_ARGS+=	--target=${TARGET_MACHINE_GNU_PLATFORM:Q}
+.  endif
 .endif
 
 # PKGINFODIR is the subdirectory of ${PREFIX} into which the info

>From febf4bdc0a91670bee8ae62e849da97f52f63c61 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Thu, 29 Jun 2023 01:24:05 +0000
Subject: [PATCH 06/13] mk: Use MACHINE_PLATFORM, not MACHINE_ARCH, for
 work/packages.

Fix bogus default PACKAGES setting -- this was shadowed by the one in
mk/defaults/mk.conf, so it never took effect.

No change to native builds because this logic is conditional on
USE_CROSS_COMPILE = yes.
---
 mk/bsd.prefs.mk     | 6 ++----
 mk/defaults/mk.conf | 5 +++--
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index a1372eef505d..2bf979820a4e 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -811,12 +811,10 @@ MAKEFLAGS+=		_PKGSRCDIR=${_PKGSRCDIR:Q}
 .endif
 PKGSRCDIR=		${_PKGSRCDIR}
 
-.if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-_CROSSDIR_SUFFIX=	.${MACHINE_ARCH}
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+_CROSSDIR_SUFFIX=	.${MACHINE_PLATFORM}
 .endif
 
-DISTDIR?=		${PKGSRCDIR}/distfiles
-PACKAGES?=		${PKGSRCDIR}/packages${_CROSSDIR_SUFFIX}
 TEMPLATES?=		${PKGSRCDIR}/templates
 
 PATCHDIR?=		${.CURDIR}/patches
diff --git a/mk/defaults/mk.conf b/mk/defaults/mk.conf
index ff620ee298b5..88207049159b 100644
--- a/mk/defaults/mk.conf
+++ b/mk/defaults/mk.conf
@@ -524,10 +524,11 @@ RCD_SCRIPTS_DIR?= ${SYSCONFBASE}/rc.d
 # Possible: any path you like
 # Default: ${SYSCONFBASE}/rc.d
 
-PACKAGES?=	${PKGSRCDIR}/packages
+PACKAGES?=	${PKGSRCDIR}/packages${${USE_CROSS_COMPILE:tl} == "yes":?.${MACHINE_PLATFORM}:}
 # Stores generated packages
 # Possible: any path you like
-# Default: ${PKGSRCDIR}/packages
+# Default: ${PKGSRCDIR}/packages, or ${PKGSRCDIR}/packages.${MACHINE_PLATFORM}
+# if cross-compiling.
 
 #PASSIVE_FETCH=
 # Use ftp(1) in passive mode, for use behind filtering firewalls.

>From 6874231d24432bd570d5f97bd113a03181cfb559 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 00:24:31 +0000
Subject: [PATCH 07/13] mk/pkgformat/pkg: Handle OBJECT_FMT mismatch in cross
 builds.

No change to native builds because OBJECT_FMT = NATIVE_OBJECT_FMT in
native builds.
---
 mk/pkgformat/pkg/depends.mk | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/mk/pkgformat/pkg/depends.mk b/mk/pkgformat/pkg/depends.mk
index 57b873186116..fe5b0f74914d 100644
--- a/mk/pkgformat/pkg/depends.mk
+++ b/mk/pkgformat/pkg/depends.mk
@@ -162,16 +162,18 @@ _DEPENDS_INSTALL_CMD=							\
 	*)								\
 		case $$type in						\
 		bootstrap|tool)						\
-			objfmt=`${HOST_PKG_INFO} -Q OBJECT_FMT "$$pkg"`;; \
+			objfmt=`${HOST_PKG_INFO} -Q OBJECT_FMT "$$pkg"`; \
+			needobjfmt=${NATIVE_OBJECT_FMT:Q};;		\
 		build|test|full)					\
-			objfmt=`${PKG_INFO} -Q OBJECT_FMT "$$pkg"`;;	\
+			objfmt=`${PKG_INFO} -Q OBJECT_FMT "$$pkg"`;	\
+			needobjfmt=${OBJECT_FMT:Q};;			\
 		esac;							\
 		case "$$objfmt" in					\
 		"")	${WARNING_MSG} "[depends.mk] Unknown object format for installed package $$pkg" ;; \
-		${OBJECT_FMT})	;;					\
+		$$needobjfmt)	;;					\
 		*)	${ERROR_MSG} "[depends.mk] Installed package $$pkg has an"; \
-			${ERROR_MSG} "    object format \`\`$$objfmt'' which differs from \`\`${OBJECT_FMT}''.  Please"; \
-			${ERROR_MSG} "    update the $$pkg package to ${OBJECT_FMT}."; \
+			${ERROR_MSG} "    object format \`\`$$objfmt'' which differs from \`\`$$needobjfmt''.  Please"; \
+			${ERROR_MSG} "    update the $$pkg package to $$needobjfmt."; \
 			exit 1;						\
 			;;						\
 		esac;							\

>From 7cb0226de1b66cad0cc4aa2c4b8c9ba603d72a8e Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 00:24:47 +0000
Subject: [PATCH 08/13] mk/tools: Prohibit USE_TOOLS+=foo:run in cross-built
 packages.

This just doesn't work yet, sorry!  Makes the problem easier to
identify up front.  Eventually, these cases need to be converted to
use TOOL_DEPENDS, but we also need to be able to split native and
cross `tools' here.

No change to native builds because the new failure is conditional on
USE_CROSS_COMPILE = yes (and OPSYS != NATIVE_OPSYS).

XXX Should also check for OS_VERSION != NATIVE_OS_VERSION, &c.
---
 mk/tools/replace.mk | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mk/tools/replace.mk b/mk/tools/replace.mk
index 133ad8ed54f4..25c1591f8450 100644
--- a/mk/tools/replace.mk
+++ b/mk/tools/replace.mk
@@ -133,6 +133,9 @@ _TOOLS_DEPMETHOD.${_t_:C/:.*//}=	BOOTSTRAP_DEPENDS
 _TOOLS_DEPMETHOD.${_t_:C/:.*//}=	TOOL_DEPENDS
 .endfor
 .for _t_ in ${USE_TOOLS:M*\:run}
+.  if ${USE_CROSS_COMPILE:tl} == "yes" && ${OPSYS} != ${NATIVE_OPSYS}
+PKG_FAIL_REASON+=	"USE_TOOLS+=${_t_} not supported in cross-compilation"
+.  endif
 _TOOLS_DEPMETHOD.${_t_:C/:.*//}=	DEPENDS
 .endfor
 .for _t_ in ${USE_TOOLS:M*\:test}

>From 1434ebebb87d77bc9baabb7f5cfef5a048e595d5 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 00:45:11 +0000
Subject: [PATCH 09/13] bsd.prefs.mk: New CROSS_VARBASE and CROSS_SYSCONFBASE.

These default to /var and /etc, respectively.

When cross-building packages, VARBASE and SYSCONFBASE are set to
these instead of whatever they were set to in mk.conf.

No change to native builds because use of these variables is
conditional on USE_CROSS_COMPILE = yes.
---
 doc/HOWTO-use-crosscompile | 17 +++++++++++++----
 mk/bsd.prefs.mk            |  2 ++
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/doc/HOWTO-use-crosscompile b/doc/HOWTO-use-crosscompile
index 51fe453bc4dd..e2ba471eb357 100644
--- a/doc/HOWTO-use-crosscompile
+++ b/doc/HOWTO-use-crosscompile
@@ -59,16 +59,25 @@ In addition to whatever else you want in your mk.conf for pkgsrc, add:
    CROSS_LOWER_VARIANT_VERSION= # empty
    CROSS_LOWER_VENDOR=          # empty
 
-Optionally, you can set CROSS_LOCALBASE for cross-compiled packages
-separately from LOCALBASE for natively compiled packages.  For example,
+Optionally, you can set CROSS_LOCALBASE, CROSS_SYSCONFBASE, and
+CROSS_VARBASE for cross-compiled packages separately from LOCALBASE,
+SYSCONFBASE, and VARBASE for natively compiled packages.  For example,
 you can use an unprivileged pkgsrc build into /home/user/cross/pkg that
 will create packages which install to /opt/pkg:
 
    LOCALBASE=		/home/user/cross/pkg
    CROSS_LOCALBASE=	/opt/pkg
 
-By default, CROSS_LOCALBASE will be /usr/pkg, meaning packages that are
-being cross-compiled will see LOCALBASE=/usr/pkg.
+By default, pkgsrc will assume:
+
+   CROSS_LOCALBASE=	/usr/pkg
+   CROSS_SYSCONFBASE=	/etc
+   CROSS_VARBASE=	/var
+
+That is, no matter what you set LOCALBASE, SYSCONFBASE, and VARBASE to
+in mk.conf for native packages, like directores under /home/user, by
+default cross-compiled packages will see LOCALBASE=/usr/pkg,
+SYSCONFBASE=/etc, and VARBASE=/var.
 
 ** Bootstrapped pkgsrc
 
diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index 2bf979820a4e..e722b7f06b70 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -688,6 +688,8 @@ LOCALBASE?=		/usr/pkg
 TOOLBASE:=		${LOCALBASE}
 .if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
 LOCALBASE=		${CROSS_LOCALBASE:U/usr/pkg}
+VARBASE=		${CROSS_VARBASE:U/var}
+SYSCONFBASE=		${CROSS_SYSCONFBASE:U/etc}
 .endif
 X11_TYPE?=		modular
 .if !empty(X11_TYPE:Mnative)

>From 386268bcb62aa9d5585d5911ae707fce93b5b0a3 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 12:15:21 +0000
Subject: [PATCH 10/13] mk/pkgformat/pkg: Make default cross-built PKG_DBDIR
 nicer.

`bootstrap --prefix /home/user/pkg' will create an mk.conf with
PKG_DBDIR=/home/user/pkg/pkgdb, but if you are using that installation
to cross-build packages, you likely want the default cross-built
PKG_DBDIR to be /usr/pkg/pkgdb just like the default cross-built
LOCALBASE is /usr/pkg.  This change implements that.

You can still override the cross-built PKG_DBDIR by setting
CROSS_PKG_DBDIr in mk.conf.

No change to native builds because the new logic is conditional on
USE_CROSS_COMPILE = yes.
---
 mk/pkgformat/pkg/pkgformat-vars.mk | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/mk/pkgformat/pkg/pkgformat-vars.mk b/mk/pkgformat/pkg/pkgformat-vars.mk
index 226c13e4e25d..e222c57f6adb 100644
--- a/mk/pkgformat/pkg/pkgformat-vars.mk
+++ b/mk/pkgformat/pkg/pkgformat-vars.mk
@@ -16,7 +16,21 @@ USE_TOOLS+=	date
 .endif
 
 # This is the package database directory for the default view.
+.if ${USE_CROSS_COMPILE:tl} != "yes"
 PKG_DBDIR?=		${LOCALBASE}/pkgdb
+.else
+.  ifndef HOST_PKG_DBDIR
+# XXX This isn't quite right: if PKG_DBDIR is defined in terms of
+# LOCALBASE, we really want to resolve it (`HOST_PKG_DBDIR:=') in
+# bsd.prefs.mk before we switch LOCALBASE to CROSS_LOCALBASE.  But
+# there's no place there to put pkgformat-vars business.  Fortunately,
+# bootstrap just writes out the full path so this is only an issue if
+# you explicitly write out `PKG_DBDIR= ...${LOCALBASE}...' in your
+# mk.conf.
+HOST_PKG_DBDIR:=	${PKG_DBDIR:U${TOOLBASE}/pkgdb}
+.  endif
+PKG_DBDIR=		${CROSS_PKG_DBDIR:U${LOCALBASE}/pkgdb}
+.endif
 
 # _PKG_DBDIR is the actual packages database directory where we register
 # packages.

>From a18df5e80b8561fd0abbd1ad8e3f2ce5a0e5e5e0 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 12:19:01 +0000
Subject: [PATCH 11/13] mk/platform/NetBSD.mk: Make default cross-built
 PKG_TOOLS_BIN nicer.

`bootstrap --prefix /home/user/pkg' will create an mk.conf with
PKG_TOOLS_BIN=/home/user/pkg/sbin, but if you are using that
installation to cross-build packages, you likely want the default
cross-built PKG_TOOLS_BIN to be /usr/pkg/sbin just like the default
cross-built LOCALBASE is /usr/pkg.  This change implements that.

You can still override the cross-built PKG_TOOLS_BIN by setting
CROSS_PKG_TOOLS_BIN in mk.conf.

No change to native builds because the changed part is conditional on
USE_CROSS_COMPILE = yes.
---
 mk/platform/NetBSD.mk | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/mk/platform/NetBSD.mk b/mk/platform/NetBSD.mk
index a5e8e48fb6e8..ba9c954a4f66 100644
--- a/mk/platform/NetBSD.mk
+++ b/mk/platform/NetBSD.mk
@@ -35,7 +35,11 @@ NOLOGIN?=		/sbin/nologin
 # This must be lazy and using :? evaluation doesn't work due to a make bugs.
 NATIVE_PKG_TOOLS_BIN_cmd=	if [ -x ${TOOLBASE}/sbin/pkg_info ]; then echo ${TOOLBASE}/sbin; else echo /usr/sbin; fi
 NATIVE_PKG_TOOLS_BIN?=		${NATIVE_PKG_TOOLS_BIN_cmd:sh}
-PKG_TOOLS_BIN?=			${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_PKG_TOOLS_BIN:U/usr/sbin}:${NATIVE_PKG_TOOLS_BIN}}
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+PKG_TOOLS_BIN=			${CROSS_PKG_TOOLS_BIN:U/usr/sbin}
+.else
+PKG_TOOLS_BIN?=			${NATIVE_PKG_TOOLS_BIN}
+.endif
 ROOT_CMD?=		${SU} - root -c
 ROOT_USER?=		root
 ROOT_GROUP?=	wheel

>From 053d95ab9ca181b9516a88d3e97d7c0f95c59d10 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 12:37:13 +0000
Subject: [PATCH 12/13] doc/HOWTO-use-crosscompile: `make
 USE_CROSS_COMPILE=yes' works now.

At least, it seems to!  Not sure what symptom I saw ages ago when I
warned users against it.
---
 doc/HOWTO-use-crosscompile | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/doc/HOWTO-use-crosscompile b/doc/HOWTO-use-crosscompile
index e2ba471eb357..d9800c7255b6 100644
--- a/doc/HOWTO-use-crosscompile
+++ b/doc/HOWTO-use-crosscompile
@@ -34,15 +34,15 @@ running NetBSD 6.1 on amd64.
 
 In addition to whatever else you want in your mk.conf for pkgsrc, add:
 
-   # Cross-compile by default.
+   # Cross-compile by default.  (Alternatively, you can cross-build
+   # packages with `make package USE_CROSS_COMPILE=no'.)
    #
-   # XXX This currently can't be set to `yes' on the command line,
-   # which is a bug.  But it can be set to `no' to build native
-   # packages.
+   # Note: This must use `?=' so it doesn't override pkgsrc's internal
+   # USE_CROSS_COMPILE=no when recursively building toolchain packages
+   # that have to run on the host.
    USE_CROSS_COMPILE?=  yes
 
-   # Point pkgsrc at the NetBSD tooldir and destdir.  These are used
-   # only for cross-builds.
+   # Point pkgsrc at the NetBSD tooldir and destdir for cross builds.
    TOOLDIR=             /usr/obj/tooldir.NetBSD-6.1-amd64
    CROSS_DESTDIR=       /usr/obj/destdir.evbppc
 
@@ -115,10 +115,6 @@ build a native package, you can run
 
    $ cd /usr/pkgsrc/net/isc-dhcpd4 && make package USE_CROSS_COMPILE=no
 
-XXX Note that currently you cannot omit USE_CROSS_COMPILE?=yes from
-your mk.conf and pass USE_CROSS_COMPILE=yes on the make command line.
-This is a bug.
-
 * Unprivileged notes
 
 I do all this stuff unprivileged in directories under my home

>From 7782ea3a79a44be71a9c7355f0538e3413c7e444 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Fri, 12 Jan 2024 22:21:10 +0000
Subject: [PATCH 13/13] bsd.prefs.mk: Use CROSS_ABI or nothing as ABI when
 cross-building.

This way, when you use the mk.conf generated by bootstrap on amd64 to
cross-build for other architectures, the ABI=64 setting that
bootstrap put in mk.conf doesn't break it.

No change to native builds because this is conditional on
USE_CROSS_COMPILE = yes.
---
 mk/bsd.prefs.mk | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index e722b7f06b70..bd17a2e3e8f6 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -690,6 +690,11 @@ TOOLBASE:=		${LOCALBASE}
 LOCALBASE=		${CROSS_LOCALBASE:U/usr/pkg}
 VARBASE=		${CROSS_VARBASE:U/var}
 SYSCONFBASE=		${CROSS_SYSCONFBASE:U/etc}
+.  if defined(CROSS_ABI)
+ABI=			${CROSS_ABI}
+.  else
+.    undef ABI
+.  endif
 .endif
 X11_TYPE?=		modular
 .if !empty(X11_TYPE:Mnative)
diff --git a/cross/cross-libtool-base/Makefile b/cross/cross-libtool-base/Makefile
index c2b4abedd693..4fbeb7a2c165 100644
--- a/cross/cross-libtool-base/Makefile
+++ b/cross/cross-libtool-base/Makefile
@@ -37,7 +37,7 @@ LIBTOOL_CROSS_COMPILE=	yes
 
 # XXX Tweaked for cross-compilation.
 #PKGNAME=	${DISTNAME:S/-/-base-/}
-PKGNAME=	${DISTNAME:S/^libtool-/cross-libtool-base-${MACHINE_ARCH}-/}
+PKGNAME=	${DISTNAME:S/^libtool-/cross-libtool-base-${MACHINE_PLATFORM}-/}
 PKGREVISION=	8
 
 COMMENT=	Generic shared library support script (the script itself)
@@ -64,10 +64,11 @@ CFLAGS.SunOS+=	${_COMPILER_ABI_FLAG.${ABI}}
 # and Fortran compilers.
 #
 USE_LANGUAGES=		c c++
-# XXX Added for cross-compilation.  XXX Should be ${TARGET_ARCH}, but
-# currently we have to fake-cross-compile libtool because it's broken
-# upstream.
-GNU_CONFIGURE_PREFIX=	${PREFIX}/cross-${MACHINE_ARCH}
+# XXX Added for cross-compilation.  XXX Should be
+# ${TARGET_MACHINE_PLATFORM}, but currently we have to
+# fake-cross-compile libtool because it's broken upstream.
+GNU_CONFIGURE_PREFIX=	${PREFIX}/cross-${MACHINE_PLATFORM}
+PLIST_SUBST+=		MACHINE_PLATFORM=${MACHINE_PLATFORM:Q}
 CONFIGURE_ARGS+=	--disable-ltdl-install
 CONFIGURE_ARGS+=	F77=no FC=no
 
@@ -96,7 +97,7 @@ post-build:
 		${FILESDIR}/shlibtool.in > ${WRKSRC}/shlibtool
 
 post-install:
-	${INSTALL_SCRIPT} ${WRKSRC}/shlibtool ${DESTDIR}${PREFIX}/cross-${MACHINE_ARCH}/bin/shlibtool
+	${INSTALL_SCRIPT} ${WRKSRC}/shlibtool ${DESTDIR}${PREFIX}/cross-${MACHINE_PLATFORM}/bin/shlibtool
 
 BUILDLINK_DEPMETHOD.dlcompat=	build
 
diff --git a/cross/cross-libtool-base/PLIST b/cross/cross-libtool-base/PLIST
index a1db9768dde3..c78dfac0fcb5 100644
--- a/cross/cross-libtool-base/PLIST
+++ b/cross/cross-libtool-base/PLIST
@@ -1,55 +1,55 @@
 @comment $NetBSD: PLIST,v 1.3 2019/07/09 15:45:25 riastradh Exp $
-cross-${MACHINE_ARCH}/bin/libtool
-cross-${MACHINE_ARCH}/bin/libtoolize
-cross-${MACHINE_ARCH}/bin/shlibtool
-cross-${MACHINE_ARCH}/man/man1/libtool.1
-cross-${MACHINE_ARCH}/man/man1/libtoolize.1
-cross-${MACHINE_ARCH}/share/aclocal/libtool.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltargz.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltdl.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltoptions.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltsugar.m4
-cross-${MACHINE_ARCH}/share/aclocal/ltversion.m4
-cross-${MACHINE_ARCH}/share/aclocal/lt~obsolete.m4
-cross-${MACHINE_ARCH}/share/libtool/COPYING.LIB
-cross-${MACHINE_ARCH}/share/libtool/Makefile.am
-cross-${MACHINE_ARCH}/share/libtool/Makefile.in
-cross-${MACHINE_ARCH}/share/libtool/README
-cross-${MACHINE_ARCH}/share/libtool/aclocal.m4
-cross-${MACHINE_ARCH}/share/libtool/build-aux/compile
-cross-${MACHINE_ARCH}/share/libtool/build-aux/config.guess
-cross-${MACHINE_ARCH}/share/libtool/build-aux/config.sub
-cross-${MACHINE_ARCH}/share/libtool/build-aux/depcomp
-cross-${MACHINE_ARCH}/share/libtool/build-aux/install-sh
-cross-${MACHINE_ARCH}/share/libtool/build-aux/ltmain.sh
-cross-${MACHINE_ARCH}/share/libtool/build-aux/missing
-cross-${MACHINE_ARCH}/share/libtool/config-h.in
-cross-${MACHINE_ARCH}/share/libtool/configure
-cross-${MACHINE_ARCH}/share/libtool/configure.ac
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__alloc.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__argz_.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__dirent.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__glibc.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__private.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt__strl.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt_dlloader.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt_error.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/lt_system.h
-cross-${MACHINE_ARCH}/share/libtool/libltdl/slist.h
-cross-${MACHINE_ARCH}/share/libtool/loaders/dld_link.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/dlopen.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/dyld.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/load_add_on.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/loadlibrary.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/preopen.c
-cross-${MACHINE_ARCH}/share/libtool/loaders/shl_load.c
-cross-${MACHINE_ARCH}/share/libtool/lt__alloc.c
-cross-${MACHINE_ARCH}/share/libtool/lt__argz.c
-cross-${MACHINE_ARCH}/share/libtool/lt__dirent.c
-cross-${MACHINE_ARCH}/share/libtool/lt__strl.c
-cross-${MACHINE_ARCH}/share/libtool/lt_dlloader.c
-cross-${MACHINE_ARCH}/share/libtool/lt_error.c
-cross-${MACHINE_ARCH}/share/libtool/ltdl.c
-cross-${MACHINE_ARCH}/share/libtool/ltdl.h
-cross-${MACHINE_ARCH}/share/libtool/ltdl.mk
-cross-${MACHINE_ARCH}/share/libtool/slist.c
+cross-${MACHINE_PLATFORM}/bin/libtool
+cross-${MACHINE_PLATFORM}/bin/libtoolize
+cross-${MACHINE_PLATFORM}/bin/shlibtool
+cross-${MACHINE_PLATFORM}/man/man1/libtool.1
+cross-${MACHINE_PLATFORM}/man/man1/libtoolize.1
+cross-${MACHINE_PLATFORM}/share/aclocal/libtool.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltargz.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltdl.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltoptions.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltsugar.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/ltversion.m4
+cross-${MACHINE_PLATFORM}/share/aclocal/lt~obsolete.m4
+cross-${MACHINE_PLATFORM}/share/libtool/COPYING.LIB
+cross-${MACHINE_PLATFORM}/share/libtool/Makefile.am
+cross-${MACHINE_PLATFORM}/share/libtool/Makefile.in
+cross-${MACHINE_PLATFORM}/share/libtool/README
+cross-${MACHINE_PLATFORM}/share/libtool/aclocal.m4
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/compile
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/config.guess
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/config.sub
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/depcomp
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/install-sh
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/ltmain.sh
+cross-${MACHINE_PLATFORM}/share/libtool/build-aux/missing
+cross-${MACHINE_PLATFORM}/share/libtool/config-h.in
+cross-${MACHINE_PLATFORM}/share/libtool/configure
+cross-${MACHINE_PLATFORM}/share/libtool/configure.ac
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__alloc.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__argz_.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__dirent.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__glibc.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__private.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt__strl.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt_dlloader.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt_error.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/lt_system.h
+cross-${MACHINE_PLATFORM}/share/libtool/libltdl/slist.h
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/dld_link.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/dlopen.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/dyld.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/load_add_on.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/loadlibrary.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/preopen.c
+cross-${MACHINE_PLATFORM}/share/libtool/loaders/shl_load.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt__alloc.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt__argz.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt__dirent.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt__strl.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt_dlloader.c
+cross-${MACHINE_PLATFORM}/share/libtool/lt_error.c
+cross-${MACHINE_PLATFORM}/share/libtool/ltdl.c
+cross-${MACHINE_PLATFORM}/share/libtool/ltdl.h
+cross-${MACHINE_PLATFORM}/share/libtool/ltdl.mk
+cross-${MACHINE_PLATFORM}/share/libtool/slist.c
diff --git a/doc/HOWTO-dev-crosscompile b/doc/HOWTO-dev-crosscompile
index e1cbd3c57f69..1de740a04eee 100644
--- a/doc/HOWTO-dev-crosscompile
+++ b/doc/HOWTO-dev-crosscompile
@@ -11,34 +11,42 @@ have ever thought of cross-compilation.
 
 * Native and target platform
 
-When building a package, MACHINE_ARCH, MACHINE_GNU_PLATFORM, &c.,
-describe the platform for which the package is being built.  If
+When building a package, MACHINE_ARCH, OPSYS, &c., describe the
+platform for which the package is being built.  If
 USE_CROSS_COMPILE=no, this is the native platform; otherwise, if
-USE_CROSS_COMPILE=yes, it is the target platform, and the additional
-variables NATIVE_MACHINE_ARCH, NATIVE_MACHINE_GNU_PLATFORM, &c.,
-describe the native platform.
+USE_CROSS_COMPILE=yes, it is the target platform.  The additional
+variables NATIVE_MACHINE_ARCH, NATIVE_OPSYS, &c., always describe the
+native platform.
 
 When building a native package for cross-compilation, such as a
-compiler for the target, the variable TARGET_ARCH describes the target
-platform like MACHINE_ARCH.  If the build product varies with the
-choice of target, then TARGET_ARCH should be embedded into the PKGNAME
+compiler for the target, the variables TARGET_MACHINE_ARCH,
+TARGET_OPSYS, &c., describe the target platform.  If the build product
+varies with the choice of target, then TARGET_MACHINE_ARCH or
+TARGET_OPSYS or whatever affects it should be embedded into the PKGNAME
 somewhere so that the different build products are distinguished by
 having different package names.
 
-XXX This pattern is incompletely realized.  We should probably replace
-TARGET_ARCH by TARGET_MACHINE_ARCH, TARGET_MACHINE_GNU_PLATFORM, &c.,
-and perhaps decide which of those is the main switch that you set when
-you want to select cross-compilation.  Ideally, this switch should
-also support cross-compilation to other operating systems.
+XXX Missing:
+XXX - TARGET_MACHINE_GNU_PLATFORM
+XXX - TARGET_MACHINE_GNU_ARCH
+XXX - probably other variables defined in terms of the CROSSVARS
 
 * Specifying the toolchain
 
-Software built following GNU conventions can set GNU_CONFIGURE=yes so
-that pkgsrc will automatically specify the right --build, --host, and
---target options for cross-compilation and point everything at the
-right toolchain.
+The following build systems should automagically handle
+cross-compilation by passing through the architecture and OS
+information:
 
-XXX And software not built following GNU conventions...?
+- GNU_CONFIGURE=yes
+- .include "../../devel/meson/build.mk" (sets
+- .include "../../devel/cmake/build.mk" (and legacy USE_CMAKE=yes)
+
+Additional tweaks are sometimes needed (but not always), conditional on
+${USE_CROSS_COMPILE:tl} == "yes" (after including bsd.prefs.mk):
+
+- (pkg-config) ALL_ENV+= PKG_CONFIG_SYSROOT_DIR=${CROSS_DESTDIR:Q}
+- (pkg-config) ALL_ENV+= PKG_CONFIG_FDO_SYSROOT_RULES=1
+- (cmake) CMAKE_ARGS+= -DCMAKE_SYSROOT:STRING=${CROSS_DESTDIR:Q}
 
 * Tool dependencies
 
@@ -107,7 +115,7 @@ pre-answer the tests for autoconf:
 
 .include "../../bsd.prefs.mk"
 
-.if ${USE_CROSS_COMPILE:U:tl} == "yes"
+.if ${USE_CROSS_COMPILE:tl} == "yes"
 # Configure wants to check for /dev/random but can't.  We know NetBSD
 # always has a /dev/random, so inform autoconf of the fact.
 CONFIGURE_ENV.NetBSD+=	ac_cv_file__dev_random=yes
diff --git a/doc/HOWTO-use-crosscompile b/doc/HOWTO-use-crosscompile
index c2f7fe7c659f..d9800c7255b6 100644
--- a/doc/HOWTO-use-crosscompile
+++ b/doc/HOWTO-use-crosscompile
@@ -34,41 +34,51 @@ running NetBSD 6.1 on amd64.
 
 In addition to whatever else you want in your mk.conf for pkgsrc, add:
 
-   # Cross-compile by default.
+   # Cross-compile by default.  (Alternatively, you can cross-build
+   # packages with `make package USE_CROSS_COMPILE=no'.)
    #
-   # XXX This currently can't be set to `yes' on the command line,
-   # which is a bug.
+   # Note: This must use `?=' so it doesn't override pkgsrc's internal
+   # USE_CROSS_COMPILE=no when recursively building toolchain packages
+   # that have to run on the host.
    USE_CROSS_COMPILE?=  yes
 
-   # Point pkgsrc at the NetBSD tooldir and destdir.  These are used
-   # only for cross-builds.
-   #
-   # XXX There is no obvious variable that is set to amd64 so that we
-   # could use
-   #
-   #    TOOLDIR=        /usr/obj/tooldir.${OPSYS}-${OS_VERSION}-${NATIVE_xyz}
-   #
-   # MACHINE is amd64 but, since it's not NATIVE_xyz, it's wrong.
-   # NATIVE_MACHINE_ARCH is x86_64, not amd64.
+   # Point pkgsrc at the NetBSD tooldir and destdir for cross builds.
    TOOLDIR=             /usr/obj/tooldir.NetBSD-6.1-amd64
    CROSS_DESTDIR=       /usr/obj/destdir.evbppc
 
    # Specify the machine architecture of target packages.
-   #
-   # XXX This currently can't be set on the command line, which is a
-   # bug.
-   .if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-   MACHINE_ARCH=        powerpc
-   .endif
-
-Optionally, you can set CROSS_LOCALBASE for cross-compiled packages
-separately from LOCALBASE for natively compiled packages.  For example,
+   CROSS_MACHINE_ARCH=  powerpc
+
+   # Specify the OS of target packages.
+   CROSS_OPSYS=		NetBSD
+   CROSS_OS_VERSION=	10.0
+   CROSS_OPSYS_VERSION=	100000
+   CROSS_LOWER_OPSYS=   netbsd
+   CROSS_LOWER_OPSYS_VERSUFFIX= # empty
+   CROSS_LOWER_OS_VARIANT=      # empty
+   CROSS_LOWER_VARIANT_VERSION= # empty
+   CROSS_LOWER_VENDOR=          # empty
+
+Optionally, you can set CROSS_LOCALBASE, CROSS_SYSCONFBASE, and
+CROSS_VARBASE for cross-compiled packages separately from LOCALBASE,
+SYSCONFBASE, and VARBASE for natively compiled packages.  For example,
 you can use an unprivileged pkgsrc build into /home/user/cross/pkg that
 will create packages which install to /opt/pkg:
 
    LOCALBASE=		/home/user/cross/pkg
    CROSS_LOCALBASE=	/opt/pkg
 
+By default, pkgsrc will assume:
+
+   CROSS_LOCALBASE=	/usr/pkg
+   CROSS_SYSCONFBASE=	/etc
+   CROSS_VARBASE=	/var
+
+That is, no matter what you set LOCALBASE, SYSCONFBASE, and VARBASE to
+in mk.conf for native packages, like directores under /home/user, by
+default cross-compiled packages will see LOCALBASE=/usr/pkg,
+SYSCONFBASE=/etc, and VARBASE=/var.
+
 ** Bootstrapped pkgsrc
 
 You can bootstrap pkgsrc or not; it shouldn't make a difference for
@@ -83,7 +93,7 @@ cross-compilation.  If you do:
    be left empty or undefined for earmv7hf cross-builds.  So you might
    need:
 
-      .if empty(USE_CROSS_COMPILE:M[yY][eE][sS])
+      .if ${USE_CROSS_COMPILE:tl} != "yes"
       ABI=    64 # set for native amd64 build
       .else
       ABI=    # empty for earmv7hf cross-build
@@ -105,10 +115,6 @@ build a native package, you can run
 
    $ cd /usr/pkgsrc/net/isc-dhcpd4 && make package USE_CROSS_COMPILE=no
 
-XXX Note that currently you cannot omit USE_CROSS_COMPILE?=yes from
-your mk.conf and pass USE_CROSS_COMPILE=yes on the make command line.
-This is a bug.
-
 * Unprivileged notes
 
 I do all this stuff unprivileged in directories under my home
diff --git a/mk/bsd.pkg.use.mk b/mk/bsd.pkg.use.mk
index 03ee7cbf1323..30728ebc4bf7 100644
--- a/mk/bsd.pkg.use.mk
+++ b/mk/bsd.pkg.use.mk
@@ -91,8 +91,8 @@ TOOL_DEPENDS+=		libtool-fortran>=${_OPSYS_LIBTOOL_REQD:U${LIBTOOL_REQD}}:../../d
 .  endif
 .else
 .  if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-PKG_LIBTOOL?=		${TOOLBASE}/cross-${TARGET_ARCH:U${MACHINE_ARCH}}/bin/libtool
-PKG_SHLIBTOOL?=		${TOOLBASE}/cross-${TARGET_ARCH:U${MACHINE_ARCH}}/bin/shlibtool
+PKG_LIBTOOL?=		${TOOLBASE}/cross-${TARGET_MACHINE_PLATFORM:U${MACHINE_PLATFORM}}/bin/libtool
+PKG_SHLIBTOOL?=		${TOOLBASE}/cross-${TARGET_MACHINE_PLATFORM:U${MACHINE_PLATFORM}}/bin/shlibtool
 .  else
 PKG_LIBTOOL?=		${TOOLBASE}/bin/libtool
 PKG_SHLIBTOOL?=		${TOOLBASE}/bin/shlibtool
@@ -103,7 +103,7 @@ SHLIBTOOL?=		${WRAPPER_BINDIR}/shlibtool
 .if defined(USE_LIBTOOL)
 LIBTOOL_REQD?=		2.4.2nb9
 .if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-TOOL_DEPENDS+=		cross-libtool-base-${MACHINE_ARCH}>=${_OPSYS_LIBTOOL_REQD:U${LIBTOOL_REQD}}:../../cross/cross-libtool-base
+TOOL_DEPENDS+=		cross-libtool-base-${MACHINE_PLATFORM}>=${_OPSYS_LIBTOOL_REQD:U${LIBTOOL_REQD}}:../../cross/cross-libtool-base
 .else
 TOOL_DEPENDS+=		libtool-base>=${_OPSYS_LIBTOOL_REQD:U${LIBTOOL_REQD}}:../../devel/libtool-base
 .endif
diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index f1161385fcea..bd17a2e3e8f6 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -87,23 +87,23 @@ UNAME=/run/current-system/sw/bin/uname
 UNAME=echo Unknown
 .endif
 
-.if !defined(OPSYS)
-OPSYS:=			${:!${UNAME} -s!:S/-//g:S/\///g:C/^CYGWIN_.*$/Cygwin/}
-MAKEFLAGS+=		OPSYS=${OPSYS:Q}
+.if !defined(NATIVE_OPSYS)
+NATIVE_OPSYS:=		${:!${UNAME} -s!:S/-//g:S/\///g:C/^CYGWIN_.*$/Cygwin/}
+MAKEFLAGS+=		NATIVE_OPSYS=${NATIVE_OPSYS:Q}
 .endif
 
 # OS_VARIANT is used to differentiate operating systems which have a common
 # basis but offer contrasting environments, for example Linux distributions
 # or illumos forks.
-OS_VARIANT?=		# empty
+NATIVE_OS_VARIANT?=	# empty
 
 # The _CMD indirection allows code below to modify these values
 # without executing the commands at all.  Later, recursed make
 # invocations will skip these blocks entirely thanks to MAKEFLAGS.
-.if !defined(OS_VERSION)
-_OS_VERSION_CMD=	${UNAME} -r
-OS_VERSION=		${_OS_VERSION_CMD:sh}
-MAKEFLAGS+=		OS_VERSION=${OS_VERSION:Q}
+.if !defined(NATIVE_OS_VERSION)
+_NATIVE_OS_VERSION_CMD=	${UNAME} -r
+NATIVE_OS_VERSION=	${_NATIVE_OS_VERSION_CMD:sh}
+MAKEFLAGS+=		NATIVE_OS_VERSION=${NATIVE_OS_VERSION:Q}
 .endif
 
 #
@@ -112,11 +112,11 @@ MAKEFLAGS+=		OS_VERSION=${OS_VERSION:Q}
 # default command is likely correct for most OS, those that need to can set
 # it to a custom command in the later OPSYS-specific section.
 #
-.if !defined(OPSYS_VERSION)
-_OPSYS_VERSION_CMD=	${UNAME} -r | \
+.if !defined(NATIVE_OPSYS_VERSION)
+_NATIVE_OPSYS_VERSION_CMD=	${UNAME} -r | \
 			awk -F. '{major=int($$1); minor=int($$2); if (minor>=100) minor=99; patch=int($$3); if (patch>=100) patch=99; printf "%02d%02d%02d", major, minor, patch}'
-OPSYS_VERSION=		${_OPSYS_VERSION_CMD:sh}
-MAKEFLAGS+=		OPSYS_VERSION=${OPSYS_VERSION:Q}
+NATIVE_OPSYS_VERSION=	${_NATIVE_OPSYS_VERSION_CMD:sh}
+MAKEFLAGS+=		NATIVE_OPSYS_VERSION=${NATIVE_OPSYS_VERSION:Q}
 .endif
 
 # Preload these for architectures not in all variations of bsd.own.mk,
@@ -155,192 +155,240 @@ MACHINE_GNU_ARCH?=		${GNU_ARCH.${MACHINE_ARCH}:U${MACHINE_ARCH}}
 
 ## If changes are made to how OS_VERSION is set below please keep
 ## "pkgsrc/pkgtools/osabi/INSTALL" in-sync.
-.if ${OPSYS} == "NetBSD"
-LOWER_OPSYS?=		netbsd
+.if ${NATIVE_OPSYS} == "NetBSD"
+NATIVE_LOWER_OPSYS?=	netbsd
 
-.elif ${OPSYS} == "AIX"
+.elif ${NATIVE_OPSYS} == "AIX"
 .  if exists(/usr/bin/oslevel)
-_OS_VERSION!=		/usr/bin/oslevel
+_NATIVE_OS_VERSION!=	/usr/bin/oslevel
 .  else
-_OS_VERSION!=		echo `${UNAME} -v`.`${UNAME} -r`
+_NATIVE_OS_VERSION!=	echo `${UNAME} -v`.`${UNAME} -r`
 .  endif
-OS_VERSION=		${_OS_VERSION:C/([0-9]*\.[0-9]*).*/\1/}
-LOWER_OPSYS_VERSUFFIX=	${_OS_VERSION}
-LOWER_OPSYS?=		aix
-LOWER_VENDOR?=		ibm
-
-.elif ${OPSYS} == "BSDOS"
-LOWER_OPSYS?=		bsdi
-
-.elif ${OPSYS} == "Cygwin"
-LOWER_OPSYS?=		cygwin
-LOWER_VENDOR?=		pc
-_OS_VERSION!=		${UNAME} -r
-OS_VERSION=		${_OS_VERSION:C/\(.*\)//}
-OS_VARIANT!=		${UNAME} -s
-
-.elif ${OPSYS} == "Darwin"
-LOWER_OPSYS?=		darwin
-LOWER_OPSYS_VERSUFFIX=	${OS_VERSION:C/([0-9]*).*/\1/}
-LOWER_VENDOR?=		apple
-_OPSYS_VERSION_CMD=	sw_vers -productVersion | \
+NATIVE_OS_VERSION=		${_NATIVE_OS_VERSION:C/([0-9]*\.[0-9]*).*/\1/}
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${_NATIVE_OS_VERSION}
+NATIVE_LOWER_OPSYS?=		aix
+NATIVE_LOWER_VENDOR?=		ibm
+
+.elif ${NATIVE_OPSYS} == "BSDOS"
+NATIVE_LOWER_OPSYS?=	bsdi
+
+.elif ${NATIVE_OPSYS} == "Cygwin"
+NATIVE_LOWER_OPSYS?=	cygwin
+NATIVE_LOWER_VENDOR?=	pc
+_NATIVE_OS_VERSION!=	${UNAME} -r
+NATIVE_OS_VERSION=	${_NATIVE_OS_VERSION:C/\(.*\)//}
+NATIVE_OS_VARIANT!=	${UNAME} -s
+
+.elif ${NATIVE_OPSYS} == "Darwin"
+NATIVE_LOWER_OPSYS?=		darwin
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${NATIVE_OS_VERSION:C/([0-9]*).*/\1/}
+NATIVE_LOWER_VENDOR?=		apple
+_NATIVE_OPSYS_VERSION_CMD=	sw_vers -productVersion | \
 			awk -F. '{major=int($$1); minor=int($$2); if (minor>=100) minor=99; patch=int($$3); if (patch>=100) patch=99; printf "%02d%02d%02d", major, minor, patch}'
 
-.elif ${OPSYS} == "DragonFly"
-OS_VERSION:=		${OS_VERSION:C/-.*$//}
-LOWER_OPSYS?=		dragonfly
-LOWER_VENDOR?=		pc
+.elif ${NATIVE_OPSYS} == "DragonFly"
+NATIVE_OS_VERSION:=	${NATIVE_OS_VERSION:C/-.*$//}
+NATIVE_LOWER_OPSYS?=	dragonfly
+NATIVE_LOWER_VENDOR?=	pc
 
-.elif ${OPSYS} == "FreeBSD"
-OS_VERSION:=		${OS_VERSION:C/-.*$//}
-LOWER_OPSYS?=		freebsd
-LOWER_OPSYS_VERSUFFIX=	${OS_VERSION:C/([0-9]*).*/\1/}
+.elif ${NATIVE_OPSYS} == "FreeBSD"
+NATIVE_OS_VERSION:=		${OS_VERSION:C/-.*$//}
+NATIVE_LOWER_OPSYS?=		freebsd
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${OS_VERSION:C/([0-9]*).*/\1/}
 .  if ${MACHINE_ARCH} == "i386"
-LOWER_VENDOR?=		pc
+NATIVE_LOWER_VENDOR?=		pc
 .  endif
-LOWER_VENDOR?=		unknown
+NATIVE_LOWER_VENDOR?=		unknown
 
-.elif ${OPSYS} == "Haiku"
-LOWER_OPSYS?=		haiku
-.  if ${MACHINE_ARCH} == "i386"
-LOWER_VENDOR?=		pc
+.elif ${NATIVE_OPSYS} == "Haiku"
+NATIVE_LOWER_OPSYS?=		haiku
+.  if ${NATIVE_MACHINE_ARCH} == "i386"
+NATIVE_LOWER_VENDOR?=		pc
 .  endif
 
-.elif ${OPSYS} == "Interix"
-LOWER_OPSYS?=		interix
-LOWER_VENDOR?=		pc
+.elif ${NATIVE_OPSYS} == "Interix"
+NATIVE_LOWER_OPSYS?=		interix
+NATIVE_LOWER_VENDOR?=		pc
 .  if exists(/usr/lib/libc.so.5.2) || exists(/usr/lib/x86/libc.so.5.2)
-LOWER_OPSYS_VERSUFFIX=	${OS_VERSION:C/([0-9]*).*/\1/}
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${NATIVE_OS_VERSION:C/([0-9]*).*/\1/}
 .  else
-LOWER_OPSYS_VERSUFFIX?=	3
+NATIVE_LOWER_OPSYS_VERSUFFIX?=	3
 .    if exists(/usr/lib/libc.so.3.5)
-OS_VERSION=		3.5
+NATIVE_OS_VERSION=		3.5
 .    elif exists(/usr/lib/libc.so.3.1)
-OS_VERSION=		3.1
+NATIVE_OS_VERSION=		3.1
 .    else
-OS_VERSION=		3.0
+NATIVE_OS_VERSION=		3.0
 .    endif
 .  endif
 
-.elif ${OPSYS} == "MirBSD"
-LOWER_OPSYS?=		mirbsd
-LOWER_OPSYS_VERSUFFIX=	${OS_VERSION}
-LOWER_VENDOR?=		unknown
+.elif ${NATIVE_OPSYS} == "MirBSD"
+NATIVE_LOWER_OPSYS?=		mirbsd
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${NATIVE_OS_VERSION}
+NATIVE_LOWER_VENDOR?=		unknown
 
-.elif !empty(OPSYS:MIRIX*)
-LOWER_OPSYS?=		irix
-LOWER_OPSYS_VERSUFFIX?=	${OS_VERSION}
-LOWER_VENDOR?=		sgi
+.elif !empty(NATIVE_OPSYS:MIRIX*)
+NATIVE_LOWER_OPSYS?=		irix
+NATIVE_LOWER_OPSYS_VERSUFFIX?=	${NATIVE_OS_VERSION}
+NATIVE_LOWER_VENDOR?=		sgi
 
-.elif ${OPSYS} == "Linux"
-OS_VERSION:=		${OS_VERSION:C/-.*$//}
-LOWER_OPSYS?=		linux
+.elif ${NATIVE_OPSYS} == "Linux"
+NATIVE_OS_VERSION:=		${NATIVE_OS_VERSION:C/-.*$//}
+NATIVE_LOWER_OPSYS?=		linux
 .  if exists(/etc/lsb-release)
 CHROMEOS_RELEASE_NAME!=	awk -F = '$$1 == "CHROMEOS_RELEASE_NAME" { print $$2 }' /etc/lsb-release
 .  endif
 .  if exists(/etc/debian_version)
-LOWER_VENDOR?=		debian
+NATIVE_LOWER_VENDOR?=		debian
 .  elif exists(/etc/mandrake-release)
-LOWER_VENDOR?=		mandrake
+NATIVE_LOWER_VENDOR?=		mandrake
 .  elif exists(/etc/redhat-version) || exists(/etc/redhat-release)
-LOWER_VENDOR?=		redhat
+NATIVE_LOWER_VENDOR?=		redhat
 .  elif exists(/etc/slackware-version)
-LOWER_VENDOR?=		slackware
+NATIVE_LOWER_VENDOR?=		slackware
 .  elif exists(/etc/ssdlinux_version)
-LOWER_VENDOR?=		ssd
+NATIVE_LOWER_VENDOR?=		ssd
 .  elif !empty(CHROMEOS_RELEASE_NAME)
-LOWER_VENDOR?=		chromeos
-.  elif ${MACHINE_ARCH} == "i386"
-LOWER_VENDOR?=          pc
+NATIVE_LOWER_VENDOR?=		chromeos
+.  elif ${NATIVE_MACHINE_ARCH} == "i386"
+NATIVE_LOWER_VENDOR?=          pc
 .  endif
-LOWER_VENDOR?=          unknown
-OS_VARIANT!=		${UNAME} -r
-OS_VARIANT:=		${OS_VARIANT:C/^.*-//}
-.  if ${OS_VARIANT} != "Microsoft"
-OS_VARIANT=		${LOWER_VENDOR}
+NATIVE_LOWER_VENDOR?=          unknown
+NATIVE_OS_VARIANT!=		${UNAME} -r
+NATIVE_OS_VARIANT:=		${NATIVE_OS_VARIANT:C/^.*-//}
+.  if ${NATIVE_OS_VARIANT} != "Microsoft"
+NATIVE_OS_VARIANT=		${NATIVE_LOWER_VENDOR}
 .  endif
+# XXX NATIVE_HOST_MACHINE_ARCH?  ???
 .  if !defined(HOST_MACHINE_ARCH)
 HOST_MACHINE_ARCH!=	${UNAME} -m
 MAKEFLAGS+=		HOST_MACHINE_ARCH=${HOST_MACHINE_ARCH:Q}
 .  endif
 
-.elif ${OPSYS} == "OpenBSD"
-LOWER_OPSYS?= 		openbsd
-
-.elif ${OPSYS} == "OSF1"
-OS_VERSION:=		${OS_VERSION:C/^V//}
-LOWER_OPSYS?=		osf1
-LOWER_OPSYS_VERSUFFIX?=	${OS_VERSION}
-LOWER_VENDOR?=		dec
-
-.elif ${OPSYS} == "HPUX"
-OS_VERSION:=		${OS_VERSION:C/^B.//}
-LOWER_OPSYS?=		hpux
-LOWER_OPSYS_VERSUFFIX?=	${OS_VERSION}
-LOWER_VENDOR?=		hp
-
-.elif ${OPSYS} == "SunOS"
-LOWER_VENDOR?=		sun
-LOWER_OPSYS?=		solaris
-LOWER_OPSYS_VERSUFFIX=	2.${OS_VERSION:C/5.//}
+.elif ${NATIVE_OPSYS} == "OpenBSD"
+NATIVE_LOWER_OPSYS?= 		openbsd
+
+.elif ${NATIVE_OPSYS} == "OSF1"
+NATIVE_OS_VERSION:=		${NATIVE_OS_VERSION:C/^V//}
+NATIVE_LOWER_OPSYS?=		osf1
+NATIVE_LOWER_OPSYS_VERSUFFIX?=	${NATIVE_OS_VERSION}
+NATIVE_LOWER_VENDOR?=		dec
+
+.elif ${NATIVE_OPSYS} == "HPUX"
+NATIVE_OS_VERSION:=		${NATIVE_OS_VERSION:C/^B.//}
+NATIVE_LOWER_OPSYS?=		hpux
+NATIVE_LOWER_OPSYS_VERSUFFIX?=	${NATIVE_OS_VERSION}
+NATIVE_LOWER_VENDOR?=		hp
+
+.elif ${NATIVE_OPSYS} == "SunOS"
+NATIVE_LOWER_VENDOR?=		sun
+NATIVE_LOWER_OPSYS?=		solaris
+NATIVE_LOWER_OPSYS_VERSUFFIX=	2.${NATIVE_OS_VERSION:C/5.//}
 .  if !defined(_UNAME_V)
 _UNAME_V!=		${UNAME} -v
 MAKEFLAGS+=		_UNAME_V=${_UNAME_V:Q}
 .  endif
 .  if !empty(_UNAME_V:Mjoyent_*)
-OS_VARIANT=		SmartOS
-LOWER_VARIANT_VERSION=	${_UNAME_V:C/joyent_//}
+NATIVE_OS_VARIANT=		SmartOS
+NATIVE_LOWER_VARIANT_VERSION=	${_UNAME_V:C/joyent_//}
 .  elif !empty(_UNAME_V:Momnios-*)
-OS_VARIANT=		OmniOS
-LOWER_VARIANT_VERSION!=	/usr/bin/awk '{ print $$3; exit 0; }' /etc/release
+NATIVE_OS_VARIANT=		OmniOS
+NATIVE_LOWER_VARIANT_VERSION!=	/usr/bin/awk '{ print $$3; exit 0; }' /etc/release
 .  elif !empty(_UNAME_V:Mtribblix-*)
-OS_VARIANT=		Tribblix
-LOWER_VARIANT_VERSION!=	/usr/bin/awk '{ print $$2; exit 0; }' /etc/release
+NATIVE_OS_VARIANT=		Tribblix
+NATIVE_LOWER_VARIANT_VERSION!=	/usr/bin/awk '{ print $$2; exit 0; }' /etc/release
 .  else
-OS_VARIANT=		Solaris
-LOWER_VARIANT_VERSION=	${_UNAME_V}
+NATIVE_OS_VARIANT=		Solaris
+NATIVE_LOWER_VARIANT_VERSION=	${_UNAME_V}
 .  endif
 
 .elif ${OPSYS} == "SCO_SV"
-SCO_RELEASE!=		${UNAME} -r
-SCO_VERSION!=		${UNAME} -v
-LOWER_VENDOR?=		pc
-LOWER_OPSYS?=		sco
-LOWER_OPSYS_VERSUFFIX=	${SCO_RELEASE}v${SCO_VERSION}
-_UNAME_V!=		${UNAME} -v
+SCO_RELEASE!=			${UNAME} -r
+SCO_VERSION!=			${UNAME} -v
+NATIVE_LOWER_VENDOR?=		pc
+NATIVE_LOWER_OPSYS?=		sco
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${SCO_RELEASE}v${SCO_VERSION}
+_UNAME_V!=			${UNAME} -v
 .  if !empty(_UNAME_V:M5.0*)
-OS_VARIANT=		SCOOSR5
+NATIVE_OS_VARIANT=		SCOOSR5
 .  elif !empty(_UNAME_V:M6.0*)
-OS_VARIANT=		SCOOSR6
+NATIVE_OS_VARIANT=		SCOOSR6
 .  endif
 
-.elif ${OPSYS} == "UnixWare"
-SCO_RELEASE?=		sysv5${OPSYS}
-SCO_VERSION!=		${UNAME} -v
-LOWER_VENDOR?=		unknown
-LOWER_OPSYS_VERSUFFIX=	${SCO_RELEASE}${SCO_VERSION}
+.elif ${NATIVE_OPSYS} == "UnixWare"
+SCO_RELEASE?=			sysv5${NATIVE_OPSYS}
+SCO_VERSION!=			${UNAME} -v
+NATIVE_LOWER_VENDOR?=		unknown
+NATIVE_LOWER_OPSYS_VERSUFFIX=	${SCO_RELEASE}${SCO_VERSION}
 
-.elif ${OPSYS} == "Minix"
-LOWER_VENDOR?=		unknown
-LOWER_OPSYS:=		${OPSYS:tl}
+.elif ${NATIVE_OPSYS} == "Minix"
+NATIVE_LOWER_VENDOR?=		unknown
+NATIVE_LOWER_OPSYS:=		${NATIVE_OPSYS:tl}
 
-.elif !defined(LOWER_OPSYS)
-LOWER_OPSYS:=		${OPSYS:tl}
+.elif !defined(NATIVE_LOWER_OPSYS)
+NATIVE_LOWER_OPSYS:=		${NATIVE_OPSYS:tl}
 .endif
 
 # Now commit the version values computed above, eliding the :sh
-OS_VERSION:=		${OS_VERSION}
-
-MAKEFLAGS+=		LOWER_OPSYS=${LOWER_OPSYS:Q}
-
-LOWER_VENDOR?=			# empty ("arch--opsys")
-
+NATIVE_OS_VERSION:=	${NATIVE_OS_VERSION}
+
+MAKEFLAGS+=		NATIVE_LOWER_OPSYS=${NATIVE_LOWER_OPSYS:Q}
+
+NATIVE_LOWER_VENDOR?=	# empty ("arch--opsys")
+
+# List of variables that must be set to determine a cross-compilation
+# target.
+CROSSVARS?=	# empty
+
+# Cross-compilation target settings.
+CROSSVARS+=	OPSYS
+OPSYS=			\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OPSYS}:${NATIVE_OPSYS}}
+CROSSVARS+=	OS_VERSION
+OS_VERSION=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OS_VERSION}:${NATIVE_OS_VERSION}}
+CROSSVARS+=	OPSYS_VERSION
+OPSYS_VERSION=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OPSYS_VERSION}:${NATIVE_OPSYS_VERSION}}
+CROSSVARS+=	LOWER_OPSYS
+LOWER_OPSYS=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_LOWER_OPSYS}:${NATIVE_LOWER_OPSYS}}
+CROSSVARS+=	LOWER_OPSYS_VERSUFFIX
+LOWER_OPSYS_VERSUFFIX=	\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_LOWER_OPSYS_VERSUFFIX}:${NATIVE_LOWER_OPSYS_VERSUFFIX}}
+CROSSVARS+=	LOWER_VARIANT_VERSION
+LOWER_VARIANT_VERSION=	\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_LOWER_VARIANT_VERSION}:${NATIVE_LOWER_VARIANT_VERSION}}
+CROSSVARS+=	LOWER_VENDOR
+LOWER_VENDOR=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_LOWER_VENDOR}:${NATIVE_LOWER_VENDOR}}
+CROSSVARS+=	LOWER_OS_VARIANT
+OS_VARIANT=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OS_VARIANT}:${NATIVE_OS_VARIANT}}
+
+# Remember the MACHINE_ARCH that make was built with before we override
+# it with CROSS_MACHINE_ARCH if USE_CROSS_COMPILE is enabled.
+CROSSVARS+=	MACHINE_ARCH
 NATIVE_MACHINE_ARCH:=		${MACHINE_ARCH}
+
 NATIVE_MACHINE_PLATFORM?=	${OPSYS}-${OS_VERSION}-${NATIVE_MACHINE_ARCH}
 MACHINE_PLATFORM?=		${OPSYS}-${OS_VERSION}-${MACHINE_ARCH}
-NATIVE_MACHINE_GNU_PLATFORM?=	${NATIVE_MACHINE_GNU_ARCH}-${LOWER_VENDOR}-${LOWER_OPSYS:C/[0-9]//g}${NATIVE_APPEND_ELF}${LOWER_OPSYS_VERSUFFIX}${NATIVE_APPEND_ABI}
+NATIVE_MACHINE_GNU_PLATFORM?=	${NATIVE_MACHINE_GNU_ARCH}-${NATIVE_LOWER_VENDOR}-${NATIVE_LOWER_OPSYS:C/[0-9]//g}${NATIVE_APPEND_ELF}${NATIVE_LOWER_OPSYS_VERSUFFIX}${NATIVE_APPEND_ABI}
 MACHINE_GNU_PLATFORM?=		${MACHINE_GNU_ARCH}-${LOWER_VENDOR}-${LOWER_OPSYS:C/[0-9]//g}${APPEND_ELF}${LOWER_OPSYS_VERSUFFIX}${APPEND_ABI}
 
+.ifdef TARGET_MACHINE_ARCH
+TARGET_MACHINE_GNU_ARCH=	${GNU_ARCH.${TARGET_MACHINE_ARCH}:U${TARGET_MACHINE_ARCH}}
+TARGET_MACHINE_GNU_PLATFORM=	${TARGET_MACHINE_GNU_ARCH}-${TARGET_LOWER_VENDOR}-${TARGET_LOWER_OPSYS:C/[0-9]//g}${TARGET_APPEND_ELF}${TARGET_LOWER_OPSYS_VERSUFFIX}${TARGET_APPEND_ABI}
+TARGET_MACHINE_PLATFORM=	${TARGET_OPSYS}-${TARGET_OS_VERSION}-${TARGET_MACHINE_ARCH}
+.endif
+
+# Set this before <bsd.own.mk> does, since it doesn't know about Darwin
+# We will later set OBJECT_FMT to be conditional on USE_CROSS_COMPILE.
+.if ${NATIVE_OPSYS} == "Darwin"
+NATIVE_OBJECT_FMT?=	Mach-O
+OBJECT_FMT?=		Mach-O
+.endif
+
 #
 # cross-libtool is special -- it is built as a native package, but it
 # needs tools set up as if for a cross-compiled package because it
@@ -352,17 +400,23 @@ MACHINE_GNU_PLATFORM?=		${MACHINE_GNU_ARCH}-${LOWER_VENDOR}-${LOWER_OPSYS:C/[0-9
 # the rest of the native package build with USE_CROSS_COMPILE=no.
 #
 # This can't live inside the cross-libtool makefile because the
-# TARGET_ARCH / MACHINE_ARCH / NATIVE_MACHINE_ARCH switcheroo has to
-# happen in the middle of this file -- after NATIVE_MACHINE_ARCH is
-# determined, before MACHINE_ARCH is used for anything else.
+# TARGET_MACHINE_ARCH / MACHINE_ARCH / NATIVE_MACHINE_ARCH switcheroo
+# has to happen in the middle of this file -- after NATIVE_MACHINE_ARCH
+# is determined, before MACHINE_ARCH is used for anything else.
 #
-.if !empty(LIBTOOL_CROSS_COMPILE:M[yY][eE][sS])
-.  if !defined(TARGET_ARCH)
-PKG_FAIL_REASON+=	"Must set TARGET_ARCH for cross-libtool."
+.if ${LIBTOOL_CROSS_COMPILE:U:tl} == "yes"
+.  if !defined(TARGET_MACHINE_ARCH)
+PKG_FAIL_REASON+=	"Must set TARGET_MACHINE_ARCH for cross-libtool."
 .  endif
-MACHINE_ARCH:=			${TARGET_ARCH}
+.  for _v_ in ${CROSSVARS}
+${_v_}=				${TARGET_${_v_}}
+.  endfor
+# XXX Other CROSSVARS for _BUILD_DEFS?
 _BUILD_DEFS.MACHINE_ARCH=	${NATIVE_MACHINE_ARCH}
 _BUILD_DEFS.MACHINE_GNU_ARCH=	${NATIVE_MACHINE_GNU_ARCH}
+_BUILD_DEFS.OBJECT_FMT=		${NATIVE_OBJECT_FMT}
+_BUILD_DEFS.OPSYS=		${NATIVE_OPSYS}
+_BUILD_DEFS.OS_VERSION=		${NATIVE_OS_VERSION}
 TOOLS_USE_CROSS_COMPILE=	yes
 .else
 TOOLS_USE_CROSS_COMPILE=	${USE_CROSS_COMPILE:Uno}
@@ -376,11 +430,6 @@ NEED_OWN_INSTALL_TARGET=no
 USETOOLS=		no
 MAKE_ENV+=		USETOOLS=no
 
-# Set this before <bsd.own.mk> does, since it doesn't know about Darwin
-.if ${OPSYS} == "Darwin"
-OBJECT_FMT?=		Mach-O
-.endif
-
 ACCEPTABLE_LICENSES?=	${DEFAULT_ACCEPTABLE_LICENSES}
 
 # Provide PKGPATH early on so that mk.conf can use it.
@@ -389,6 +438,43 @@ PKGPATH?=		${.CURDIR:C|.*/([^/]*/[^/]*)$|\1|}
 # Load the settings from MAKECONF, which is /etc/mk.conf by default.
 .include <bsd.own.mk>
 
+# Save the OBJECT_FMT determined by bsd.own.mk, and turn OBJECT_FMT
+# into a cross-compilation variable so it can be overridden by
+# CROSS_OBJECT_FMT.
+NATIVE_OBJECT_FMT:=	${OBJECT_FMT}
+CROSSVARS+=		OBJECT_FMT
+OBJECT_FMT=		\
+	${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_OBJECT_FMT}:${NATIVE_OBJECT_FMT}}
+
+# When cross-compilation support is requested, the following options
+# must be specified as well or guessable:
+# - Variables like MACHINE_ARCH are set to CROSS_MACHINE_ARCH.
+# - CROSS_DESTDIR is guessed from MAKEOBJDIR and MACHINE_ARCH.
+# - PKG_DBDIR is expanded and prefixed with CROSS_DESTDIR
+# - DESTDIR support is required
+#
+# _CROSS_DESTDIR is set for internal use to avoid conditionalising
+# the use.
+
+.if ${USE_CROSS_COMPILE:U:tl} == "yes" # defaults/mk.conf not yet loaded, so :U
+.  for _v_ in ${CROSSVARS}
+.    ifndef CROSS_${_v_}
+MISSING_CROSSVARS=	yes
+.      warning Missing CROSS_${_v_} setting
+.    endif
+${_v_}:=	${CROSS_${_v_}}
+.  endfor
+.  ifdef MISSING_CROSSVARS
+.    error USE_CROSS_COMPILE=yes but missing cross variable settings
+.  endif
+CROSS_DESTDIR?=	${MAKEOBJDIR}/destdir.${MACHINE_ARCH}
+.  if !exists(${CROSS_DESTDIR}/usr/include/stddef.h)
+PKG_FAIL_REASON+=	"The cross-compiling root ${CROSS_DESTDIR:Q} is incomplete"
+.  else
+_CROSS_DESTDIR=	${CROSS_DESTDIR}
+.  endif
+.endif
+
 .if ${OPSYS} == "OpenBSD"
 .  if defined(ELF_TOOLCHAIN) && ${ELF_TOOLCHAIN} == "yes"
 OBJECT_FMT?=	ELF
@@ -450,28 +536,6 @@ SHAREMODE?=		${DOCMODE}
 	@${FALSE}
 .endif
 
-# When cross-compilation support is requested, the following options
-# must be specified as well or guessable:
-# - MACHINE_ARCH is set to TARGET_ARCH if set.
-# - CROSS_DESTDIR is guessed from MAKEOBJDIR and MACHINE_ARCH.
-# - PKG_DBDIR is expanded and prefixed with CROSS_DESTDIR
-# - DESTDIR support is required
-#
-# _CROSS_DESTDIR is set for internal use to avoid conditionalising
-# the use.
-
-.if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-.  if defined(TARGET_ARCH)
-MACHINE_ARCH=	${TARGET_ARCH}
-.  endif
-CROSS_DESTDIR?=	${MAKEOBJDIR}/destdir.${MACHINE_ARCH}
-.  if !exists(${CROSS_DESTDIR}/usr/include/stddef.h)
-PKG_FAIL_REASON+=	"The cross-compiling root ${CROSS_DESTDIR:Q} is incomplete"
-.  else
-_CROSS_DESTDIR=	${CROSS_DESTDIR}
-.  endif
-.endif
-
 # Load the OS-specific definitions for program variables.  Default to loading
 # the NetBSD ones if an OS-specific file doesn't exist.
 .if exists(${_PKGSRC_TOPDIR}/mk/platform/${OPSYS}.mk)
@@ -562,9 +626,9 @@ TOOLS_CROSS_DESTDIR=		# empty
 
 # Depends on MACHINE_ARCH override above
 .if ${OPSYS} == "NetBSD"
-# XXX NATIVE_OBJECT_FMT is a cop-out -- but seriously, who is going to
-# do cross-builds on a NetBSD host that still uses a.out?
-NATIVE_OBJECT_FMT?=	${OBJECT_FMT}
+.  ifdef TARGET_MACHINE_ARCH
+TARGET_OBJECT_FMT?=	${OBJECT_FMT} # XXX
+.  endif
 .  if ${NATIVE_OBJECT_FMT} == "ELF" && \
    (!empty(NATIVE_MACHINE_ARCH:Mearm*) || \
     ${NATIVE_MACHINE_GNU_ARCH} == "arm" || \
@@ -589,12 +653,28 @@ NATIVE_APPEND_ELF=	elf
     ${MACHINE_ARCH} == "vax")
 APPEND_ELF=		elf
 .  endif
+.  if defined(TARGET_MACHINE_ARCH) && \
+   ${TARGET_OBJECT_FMT} == "ELF" && \
+   (!empty(TARGET_MACHINE_ARCH:Mearm*) || \
+    ${TARGET_MACHINE_GNU_ARCH} == "arm" || \
+    ${TARGET_MACHINE_ARCH} == "i386" || \
+    ${TARGET_MACHINE_ARCH} == "m68k" || \
+    ${TARGET_MACHINE_ARCH} == "m68000" || \
+    ${TARGET_MACHINE_GNU_ARCH} == "sh" || \
+    ${TARGET_MACHINE_GNU_ARCH} == "shle" || \
+    ${TARGET_MACHINE_ARCH} == "sparc" || \
+    ${TARGET_MACHINE_ARCH} == "vax")
+TARGET_APPEND_ELF=	elf
+.  endif
 .  if !empty(NATIVE_MACHINE_ARCH:Mearm*)
 NATIVE_APPEND_ABI=	-${NATIVE_MACHINE_ARCH:C/eb//:C/v[4-7]//:S/earm/eabi/}
 .  endif
 .  if !empty(MACHINE_ARCH:Mearm*)
 APPEND_ABI=		-${MACHINE_ARCH:C/eb//:C/v[4-7]//:S/earm/eabi/}
 .  endif
+.  if !empty(TARGET_MACHINE_ARCH:Mearm*)
+TARGET_APPEND_ABI=	-${TARGET_MACHINE_ARCH:C/eb//:C/v[4-7]//:S/earm/eabi/}
+.  endif
 .endif
 
 # if the system is IPv6-ready, compile with IPv6 support turned on.
@@ -608,6 +688,13 @@ LOCALBASE?=		/usr/pkg
 TOOLBASE:=		${LOCALBASE}
 .if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
 LOCALBASE=		${CROSS_LOCALBASE:U/usr/pkg}
+VARBASE=		${CROSS_VARBASE:U/var}
+SYSCONFBASE=		${CROSS_SYSCONFBASE:U/etc}
+.  if defined(CROSS_ABI)
+ABI=			${CROSS_ABI}
+.  else
+.    undef ABI
+.  endif
 .endif
 X11_TYPE?=		modular
 .if !empty(X11_TYPE:Mnative)
@@ -731,12 +818,10 @@ MAKEFLAGS+=		_PKGSRCDIR=${_PKGSRCDIR:Q}
 .endif
 PKGSRCDIR=		${_PKGSRCDIR}
 
-.if !empty(USE_CROSS_COMPILE:M[yY][eE][sS])
-_CROSSDIR_SUFFIX=	.${MACHINE_ARCH}
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+_CROSSDIR_SUFFIX=	.${MACHINE_PLATFORM}
 .endif
 
-DISTDIR?=		${PKGSRCDIR}/distfiles
-PACKAGES?=		${PKGSRCDIR}/packages${_CROSSDIR_SUFFIX}
 TEMPLATES?=		${PKGSRCDIR}/templates
 
 PATCHDIR?=		${.CURDIR}/patches
diff --git a/mk/configure/gnu-configure.mk b/mk/configure/gnu-configure.mk
index 4a1ab41ba888..d13d3461ff0b 100644
--- a/mk/configure/gnu-configure.mk
+++ b/mk/configure/gnu-configure.mk
@@ -40,7 +40,7 @@ _PKG_VARS.gnu-configure=	\
 	GNU_CONFIGURE_LIBDIR GNU_CONFIGURE_INFODIR GNU_CONFIGURE_MANDIR \
 	CONFIGURE_HAS_LIBDIR CONFIGURE_HAS_MANDIR CONFIGURE_HAS_INFODIR \
 	OVERRIDE_DIRDEPTH.configure \
-	USE_GNU_CONFIGURE_HOST
+	USE_GNU_CONFIGURE_HOST USE_GNU_CONFIGURE_TARGET
 
 HAS_CONFIGURE=			defined
 OVERRIDE_GNU_CONFIG_SCRIPTS=	defined
@@ -85,6 +85,7 @@ CONFIGURE_ARGS+=	--libdir=${GNU_CONFIGURE_LIBDIR}
 .endif
 
 USE_GNU_CONFIGURE_HOST?=	yes
+USE_GNU_CONFIGURE_TARGET?=	no # enable for toolchain packages
 .if !empty(USE_GNU_CONFIGURE_HOST:M[yY][eE][sS])
 .  if !empty(TOOLS_USE_CROSS_COMPILE:M[yY][eE][sS])
 CONFIGURE_ARGS+=	--build=${NATIVE_MACHINE_GNU_PLATFORM:Q}
@@ -92,6 +93,9 @@ CONFIGURE_ARGS+=	--build=${NATIVE_MACHINE_GNU_PLATFORM:Q}
 CONFIGURE_ARGS+=	--build=${MACHINE_GNU_PLATFORM:Q}
 .  endif
 CONFIGURE_ARGS+=	--host=${MACHINE_GNU_PLATFORM:Q}
+.  if ${USE_GNU_CONFIGURE_TARGET:tl} == "yes"
+CONFIGURE_ARGS+=	--target=${TARGET_MACHINE_GNU_PLATFORM:Q}
+.  endif
 .endif
 
 # PKGINFODIR is the subdirectory of ${PREFIX} into which the info
diff --git a/mk/defaults/mk.conf b/mk/defaults/mk.conf
index ff620ee298b5..88207049159b 100644
--- a/mk/defaults/mk.conf
+++ b/mk/defaults/mk.conf
@@ -524,10 +524,11 @@ RCD_SCRIPTS_DIR?= ${SYSCONFBASE}/rc.d
 # Possible: any path you like
 # Default: ${SYSCONFBASE}/rc.d
 
-PACKAGES?=	${PKGSRCDIR}/packages
+PACKAGES?=	${PKGSRCDIR}/packages${${USE_CROSS_COMPILE:tl} == "yes":?.${MACHINE_PLATFORM}:}
 # Stores generated packages
 # Possible: any path you like
-# Default: ${PKGSRCDIR}/packages
+# Default: ${PKGSRCDIR}/packages, or ${PKGSRCDIR}/packages.${MACHINE_PLATFORM}
+# if cross-compiling.
 
 #PASSIVE_FETCH=
 # Use ftp(1) in passive mode, for use behind filtering firewalls.
diff --git a/mk/pkgformat/pkg/depends.mk b/mk/pkgformat/pkg/depends.mk
index ed4674e63279..fe5b0f74914d 100644
--- a/mk/pkgformat/pkg/depends.mk
+++ b/mk/pkgformat/pkg/depends.mk
@@ -90,6 +90,8 @@ _RESOLVE_DEPENDS_CMD=	\
 			" "${BUILD_DEPENDS:Q} \
 			" "${DEPENDS:Q}
 
+CROSSTARGETSETTINGS=	${CROSSVARS:@_v_@TARGET_${_v_}=${${_v_}}@}
+
 # _DEPENDS_INSTALL_CMD checks whether the package $pattern is installed,
 #	and installs it if necessary.
 #
@@ -110,17 +112,20 @@ _DEPENDS_INSTALL_CMD=							\
 	case $$type in							\
 	bootstrap|tool)							\
 		case "${USE_CROSS_COMPILE:Uno:tl}" in			\
-		yes) extradep="" ;;					\
-		*) extradep=" ${PKGNAME}" ;;				\
+		yes)	extradep="";					\
+			crosstargetsettings=${CROSSTARGETSETTINGS:Q};	\
+			;;						\
+		*)	extradep=" ${PKGNAME}";				\
+			crosstargetsettings=;				\
+			;;						\
 		esac;							\
 		cross=no;						\
-		archopt=TARGET_ARCH=${MACHINE_ARCH};			\
 		pkg=`${_HOST_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`;	\
 		;;							\
-	build|test|full)							\
+	build|test|full)						\
 		extradep=" ${PKGNAME}";					\
+		crosstargetsettings=;					\
 		cross=${USE_CROSS_COMPILE:Uno};				\
-		archopt=;						\
 		pkg=`${_PKG_BEST_EXISTS} "$$pattern" || ${TRUE}`;	\
 		;;							\
 	esac;								\
@@ -133,11 +138,12 @@ _DEPENDS_INSTALL_CMD=							\
 		cd $$dir;						\
 		unset _PKGSRC_BARRIER;					\
 		unset MAKEFLAGS;					\
+		unset ${CROSSVARS:@_v_@TARGET_${_v_}@};			\
 		${PKGSRC_SETENV} ${PKGSRC_MAKE_ENV} PATH=${_PATH_ORIG:Q}\
 			_PKGSRC_DEPS="$$extradep${_PKGSRC_DEPS}"	\
 			PKGNAME_REQD="$$pattern"			\
 			USE_CROSS_COMPILE=$$cross			\
-			$$archopt					\
+			$$crosstargetsettings				\
 		    ${MAKE} ${MAKEFLAGS} _AUTOMATIC=yes $$target;	\
 		case $$type in						\
 		bootstrap|tool)						\
@@ -156,16 +162,18 @@ _DEPENDS_INSTALL_CMD=							\
 	*)								\
 		case $$type in						\
 		bootstrap|tool)						\
-			objfmt=`${HOST_PKG_INFO} -Q OBJECT_FMT "$$pkg"`;; \
+			objfmt=`${HOST_PKG_INFO} -Q OBJECT_FMT "$$pkg"`; \
+			needobjfmt=${NATIVE_OBJECT_FMT:Q};;		\
 		build|test|full)					\
-			objfmt=`${PKG_INFO} -Q OBJECT_FMT "$$pkg"`;;	\
+			objfmt=`${PKG_INFO} -Q OBJECT_FMT "$$pkg"`;	\
+			needobjfmt=${OBJECT_FMT:Q};;			\
 		esac;							\
 		case "$$objfmt" in					\
 		"")	${WARNING_MSG} "[depends.mk] Unknown object format for installed package $$pkg" ;; \
-		${OBJECT_FMT})	;;					\
+		$$needobjfmt)	;;					\
 		*)	${ERROR_MSG} "[depends.mk] Installed package $$pkg has an"; \
-			${ERROR_MSG} "    object format \`\`$$objfmt'' which differs from \`\`${OBJECT_FMT}''.  Please"; \
-			${ERROR_MSG} "    update the $$pkg package to ${OBJECT_FMT}."; \
+			${ERROR_MSG} "    object format \`\`$$objfmt'' which differs from \`\`$$needobjfmt''.  Please"; \
+			${ERROR_MSG} "    update the $$pkg package to $$needobjfmt."; \
 			exit 1;						\
 			;;						\
 		esac;							\
diff --git a/mk/pkgformat/pkg/pkgformat-vars.mk b/mk/pkgformat/pkg/pkgformat-vars.mk
index 226c13e4e25d..e222c57f6adb 100644
--- a/mk/pkgformat/pkg/pkgformat-vars.mk
+++ b/mk/pkgformat/pkg/pkgformat-vars.mk
@@ -16,7 +16,21 @@ USE_TOOLS+=	date
 .endif
 
 # This is the package database directory for the default view.
+.if ${USE_CROSS_COMPILE:tl} != "yes"
 PKG_DBDIR?=		${LOCALBASE}/pkgdb
+.else
+.  ifndef HOST_PKG_DBDIR
+# XXX This isn't quite right: if PKG_DBDIR is defined in terms of
+# LOCALBASE, we really want to resolve it (`HOST_PKG_DBDIR:=') in
+# bsd.prefs.mk before we switch LOCALBASE to CROSS_LOCALBASE.  But
+# there's no place there to put pkgformat-vars business.  Fortunately,
+# bootstrap just writes out the full path so this is only an issue if
+# you explicitly write out `PKG_DBDIR= ...${LOCALBASE}...' in your
+# mk.conf.
+HOST_PKG_DBDIR:=	${PKG_DBDIR:U${TOOLBASE}/pkgdb}
+.  endif
+PKG_DBDIR=		${CROSS_PKG_DBDIR:U${LOCALBASE}/pkgdb}
+.endif
 
 # _PKG_DBDIR is the actual packages database directory where we register
 # packages.
diff --git a/mk/platform/NetBSD.mk b/mk/platform/NetBSD.mk
index a5e8e48fb6e8..ba9c954a4f66 100644
--- a/mk/platform/NetBSD.mk
+++ b/mk/platform/NetBSD.mk
@@ -35,7 +35,11 @@ NOLOGIN?=		/sbin/nologin
 # This must be lazy and using :? evaluation doesn't work due to a make bugs.
 NATIVE_PKG_TOOLS_BIN_cmd=	if [ -x ${TOOLBASE}/sbin/pkg_info ]; then echo ${TOOLBASE}/sbin; else echo /usr/sbin; fi
 NATIVE_PKG_TOOLS_BIN?=		${NATIVE_PKG_TOOLS_BIN_cmd:sh}
-PKG_TOOLS_BIN?=			${"${USE_CROSS_COMPILE:U:tl}" == "yes":?${CROSS_PKG_TOOLS_BIN:U/usr/sbin}:${NATIVE_PKG_TOOLS_BIN}}
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+PKG_TOOLS_BIN=			${CROSS_PKG_TOOLS_BIN:U/usr/sbin}
+.else
+PKG_TOOLS_BIN?=			${NATIVE_PKG_TOOLS_BIN}
+.endif
 ROOT_CMD?=		${SU} - root -c
 ROOT_USER?=		root
 ROOT_GROUP?=	wheel
diff --git a/mk/tools/cross.NetBSD.mk b/mk/tools/cross.NetBSD.mk
new file mode 100644
index 000000000000..df739ba84035
--- /dev/null
+++ b/mk/tools/cross.NetBSD.mk
@@ -0,0 +1,25 @@
+# $NetBSD$
+#
+# Cross-compiler toolchain for the NetBSD operating system.  Requires
+# TOOLDIR to match build.sh for a NetBSD build.
+
+TOOLS_PLATFORM.install?=	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-install
+TOOLS_PLATFORM.readelf?=	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-readelf
+TOOLS_PLATFORM.strip?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-strip
+
+.for _t_ in ar as ld nm objcopy objdump ranlib readelf strip
+TOOLS_PATH.${MACHINE_GNU_PLATFORM}-${_t_}?=	\
+	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-${_t_}
+TOOLS_CREATE+=	${MACHINE_GNU_PLATFORM}-${_t_}
+.endfor
+
+TOOLS_PATH.ar?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ar
+TOOLS_CREATE+=			ar
+TOOLS_PATH.ranlib?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ranlib
+TOOLS_CREATE+=			ranlib
+TOOLS_PATH.readelf?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-readelf
+TOOLS_CREATE+=			readelf
+
+CC=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-gcc
+CXX=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-g++
+LD=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ld
diff --git a/mk/tools/defaults.mk b/mk/tools/defaults.mk
index 5b49c4224d72..51d956f1ae81 100644
--- a/mk/tools/defaults.mk
+++ b/mk/tools/defaults.mk
@@ -34,10 +34,17 @@ TOOLS_DEFAULTS_MK=	defined
 # These are the platform-specific lists of system-supplied tools.
 #
 # XXX These should eventually just migrate over to the appropriate
-# XXX pkgsrc/mk/platform/${OPSYS}.mk file.
+# XXX pkgsrc/mk/platform/${NATIVE_OPSYS}.mk file.
 #
-.if exists(${_PKGSRC_TOPDIR}/mk/tools/tools.${OPSYS}.mk)
-.  include "${_PKGSRC_TOPDIR}/mk/tools/tools.${OPSYS}.mk"
+# XXX Use ${OPSYS} for :run tools, but ${NATIVE_OPSYS} for :build and
+# XXX :bootstrap tools.
+#
+.if ${TOOLS_USE_CROSS_COMPILE:tl} == "yes" && \
+    exists(${_PKGSRC_TOPDIR}/mk/tools/cross.${OPSYS}.mk)
+.  include "${_PKGSRC_TOPDIR}/mk/tools/cross.${OPSYS}.mk"
+.endif
+.if exists(${_PKGSRC_TOPDIR}/mk/tools/tools.${NATIVE_OPSYS}.mk)
+.  include "${_PKGSRC_TOPDIR}/mk/tools/tools.${NATIVE_OPSYS}.mk"
 .endif
 
 ######################################################################
diff --git a/mk/tools/replace.mk b/mk/tools/replace.mk
index 133ad8ed54f4..25c1591f8450 100644
--- a/mk/tools/replace.mk
+++ b/mk/tools/replace.mk
@@ -133,6 +133,9 @@ _TOOLS_DEPMETHOD.${_t_:C/:.*//}=	BOOTSTRAP_DEPENDS
 _TOOLS_DEPMETHOD.${_t_:C/:.*//}=	TOOL_DEPENDS
 .endfor
 .for _t_ in ${USE_TOOLS:M*\:run}
+.  if ${USE_CROSS_COMPILE:tl} == "yes" && ${OPSYS} != ${NATIVE_OPSYS}
+PKG_FAIL_REASON+=	"USE_TOOLS+=${_t_} not supported in cross-compilation"
+.  endif
 _TOOLS_DEPMETHOD.${_t_:C/:.*//}=	DEPENDS
 .endfor
 .for _t_ in ${USE_TOOLS:M*\:test}
diff --git a/mk/tools/tools.NetBSD.mk b/mk/tools/tools.NetBSD.mk
index 2d4de5afe264..387367f36531 100644
--- a/mk/tools/tools.NetBSD.mk
+++ b/mk/tools/tools.NetBSD.mk
@@ -58,11 +58,7 @@ TOOLS_PLATFORM.head?=		/usr/bin/head
 TOOLS_PLATFORM.hostname?=	/bin/hostname
 TOOLS_PLATFORM.id?=		/usr/bin/id
 TOOLS_PLATFORM.ident?=		/usr/bin/ident
-.if ${TOOLS_USE_CROSS_COMPILE:tl} != yes
 TOOLS_PLATFORM.install?=	/usr/bin/install
-.else
-TOOLS_PLATFORM.install?=	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-install
-.endif
 .if exists(/usr/bin/install-info)
 TOOLS_PLATFORM.install-info?=	/usr/bin/install-info
 .endif
@@ -102,11 +98,7 @@ TOOLS_PLATFORM.paxctl?=		/usr/sbin/paxctl
 .endif
 TOOLS_PLATFORM.printf?=		/usr/bin/printf
 TOOLS_PLATFORM.pwd?=		/bin/pwd
-.if ${TOOLS_USE_CROSS_COMPILE:U:tl} != yes
 TOOLS_PLATFORM.readelf?=	/usr/bin/readelf
-.else
-TOOLS_PLATFORM.readelf?=	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-readelf
-.endif
 TOOLS_PLATFORM.readlink?=	/usr/bin/readlink
 .if exists(/usr/bin/realpath)
 TOOLS_PLATFORM.realpath?=	/usr/bin/realpath
@@ -120,11 +112,7 @@ TOOLS_PLATFORM.shlock?=		/usr/bin/shlock
 TOOLS_PLATFORM.sleep?=		/bin/sleep
 TOOLS_PLATFORM.soelim?=		/usr/bin/soelim
 TOOLS_PLATFORM.sort?=		/usr/bin/sort
-.if ${TOOLS_USE_CROSS_COMPILE:U:tl} != yes
 TOOLS_PLATFORM.strip?=		/usr/bin/strip
-.else
-TOOLS_PLATFORM.strip?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-strip
-.endif
 
 TOOLS_PLATFORM.tail?=		/usr/bin/tail
 .if exists(/bin/tar)
@@ -157,29 +145,9 @@ TOOLS_PLATFORM.xzcat?=		/usr/bin/xzcat
 TOOLS_PLATFORM.yacc?=		/usr/bin/yacc
 
 .if ${TOOLS_USE_CROSS_COMPILE:U:tl} == yes
-.  for _t_ in ar as ld nm objcopy objdump ranlib readelf strip
-TOOLS_PATH.${MACHINE_GNU_PLATFORM}-${_t_}?=	\
-	${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-${_t_}
-TOOLS_CREATE+=	${MACHINE_GNU_PLATFORM}-${_t_}
-.  endfor
-
-TOOLS_PATH.ar?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ar
-TOOLS_CREATE+=			ar
-TOOLS_PATH.ranlib?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ranlib
-TOOLS_CREATE+=			ranlib
-TOOLS_PATH.readelf?=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-readelf
-TOOLS_CREATE+=			readelf
-
 NATIVE_CC:=	/usr/bin/cc -B /usr/libexec -B /usr/bin
-CC=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-gcc
-
 NATIVE_CXX:=	/usr/bin/c++ -B /usr/libexec -B /usr/bin
-CXX=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-g++
-
 NATIVE_LD:=	/usr/bin/ld
-LD=		${TOOLDIR}/bin/${MACHINE_GNU_PLATFORM}-ld
-
 NATIVE_AR:=	/usr/bin/ar
 NATIVE_RANLIB:=	/usr/bin/ranlib
-
 .endif


Home | Main Index | Thread Index | Old Index