tech-pkg archive

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

Re: Cross-building rusty packages



> Date: Sun, 12 Jan 2025 12:20:06 +0000
> From: Jonathan Perkin <jperkin%pkgsrc.org@localhost>
> 
> * On 2025-01-12 at 09:27 GMT, Taylor R Campbell wrote:
> 
> >+TARGET_RUST_ARCH=	${empty(TARGET_MACHINE_PLATFORM):?:${RUST_MACHINE_ARCH.${TARGET_MACHINE_ARCH}:U${TARGET_MACHINE_ARCH}}-${empty(TARGET_LOWER_VENDOR):?unknown:${TARGET_LOWER_VENDOR}}-${RUST_LOWER_OPSYS.${TARGET_LOWER_OPSYS}:U${TARGET_LOWER_OPSYS}}${TARGET_APPEND_ABI}}
> 
> This is basically unreadable.  Can we prioritise readability over 
> clever use of ternary operators please.

Better?

Had to reorganize a bit to avoid ordering dependencies of assignments
and conditionals, and added a bunch of new temporary intermediate
variables without much thought toward their names.
diff --git a/lang/rust/Makefile b/lang/rust/Makefile
index 001da1136e21..3b02ecda739e 100644
--- a/lang/rust/Makefile
+++ b/lang/rust/Makefile
@@ -1,7 +1,11 @@
 # $NetBSD: Makefile,v 1.321 2024/11/24 16:13:42 he Exp $
 
+.if !empty(TARGET_MACHINE_PLATFORM)
+PKGNAME_TARGET_SUFFIX=	-${TARGET_MACHINE_PLATFORM}
+.endif
+
 DISTNAME=	rustc-1.81.0-src
-PKGNAME=	${DISTNAME:S/rustc/rust/:S/-src//}
+PKGNAME=	${DISTNAME:S/rustc/rust${PKGNAME_TARGET_SUFFIX}/:S/-src//}
 CATEGORIES=	lang
 MASTER_SITES=	https://static.rust-lang.org/dist/
 
@@ -32,13 +36,13 @@ USE_TOOLS+=		bash grep gmake perl:build pkg-config
 BROKEN_ON_PLATFORM+=	NetBSD-[1-8].*-*
 
 HAS_CONFIGURE=		yes
-PYTHON_FOR_BUILD_ONLY=	yes
-CONFIG_SHELL=		${PYTHONBIN}
+PYTHON_FOR_BUILD_ONLY=	tool
+CONFIG_SHELL=		${TOOL_PYTHONBIN}
 CONFIGURE_SCRIPT=	src/bootstrap/configure.py
-CONFIGURE_ARGS+=	--prefix=${PREFIX}
-CONFIGURE_ARGS+=	--mandir=${PREFIX}/${PKGMANDIR}
-CONFIGURE_ARGS+=	--sysconfdir=${PKG_SYSCONFDIR}
-CONFIGURE_ARGS+=	--python=${PYTHONBIN}
+CONFIGURE_ARGS+=	--prefix=${RUST_PREFIX}
+CONFIGURE_ARGS+=	--mandir=${RUST_PREFIX}/${PKGMANDIR}
+CONFIGURE_ARGS+=	--sysconfdir=${PKG_SYSCONFDIR} # XXX RUST_PREFIX?
+CONFIGURE_ARGS+=	--python=${TOOL_PYTHONBIN}
 CONFIGURE_ARGS+=	--release-channel=stable
 CONFIGURE_ARGS+=	--local-rust-root=${RUST_BOOTSTRAP_PATH}
 CONFIGURE_ARGS+=	--enable-extended	# Build and install cargo too.
@@ -103,7 +107,7 @@ MAKE_JOBS_SAFE=		yes
 BUILD_TARGET=	${rust.BUILD_TARGET}
 .endif
 
-.if !empty(TARGET)
+.if !empty(TARGET) || !empty(TARGET_MACHINE_PLATFORM)
 # Use "dist" build target for cross compile of bootstrap
 BUILD_TARGET?=		dist
 .else
@@ -145,9 +149,9 @@ CONFIGURE_ARGS+=	--set llvm.targets="Mips"
 CONFIGURE_ARGS+=	--set llvm.targets="Mips;X86"
 .endif
 
-CHECK_INTERPRETER_SKIP+=	lib/rustlib/src/rust/library/backtrace/ci/*.sh
-CHECK_INTERPRETER_SKIP+=	lib/rustlib/src/rust/library/core/src/unicode/printable.py
-CHECK_INTERPRETER_SKIP+=	lib/rustlib/src/rust/library/stdarch/ci/*.sh
+CHECK_INTERPRETER_SKIP+=	${RUST_PREFIX_SUBDIR}lib/rustlib/src/rust/library/backtrace/ci/*.sh
+CHECK_INTERPRETER_SKIP+=	${RUST_PREFIX_SUBDIR}lib/rustlib/src/rust/library/core/src/unicode/printable.py
+CHECK_INTERPRETER_SKIP+=	${RUST_PREFIX_SUBDIR}lib/rustlib/src/rust/library/stdarch/ci/*.sh
 CHECK_PORTABILITY_SKIP+=	tests/run-make/dump-ice-to-disk/check.sh
 CHECK_PORTABILITY_SKIP+=	vendor/libdbus-sys-0.2.5/vendor/dbus/tools/cmake-format
 
@@ -201,12 +205,147 @@ BUILDLINK_TRANSFORM.NetBSD+=	rm:-Wl,--enable-new-dtags
 BUILDLINK_TRANSFORM+=	opt:x86_64:arm64
 .endif
 
+# XXX Copypasta of arch.mk -- remove me and use arch.mk once we verify
+# that it produces the same RUST_ARCH on all platforms.
+RUST_MACHINE_ARCH.i386=		i586		# not really
+RUST_MACHINE_ARCH.aarch64eb=	aarch64_be
+RUST_MACHINE_ARCH.riscv64=	riscv64gc
+
+RUST_LOWER_OPSYS.solaris=	illumos
+
+.if empty(TARGET_MACHINE_PLATFORM)
+
+RUST_PREFIX=		${PREFIX}
+RUST_PREFIX_SUBDIR=	# empty
+
+.else				# !empty(TARGET_MACHINE_PLATFORM)
+
+# Put Rust cross-toolchain packages in a prefix that doesn't conflict
+# with the native Rust toolchain package, or with each other.
+#
+# XXX Consider using ${TARGET_MACHINE_PLATFORM} so this has the OS
+# version embedded too; otherwise, e.g., 9.0 and 10.0 packages will
+# collide -- alternatively, package should be named with
+# ${TARGET_RUST_ARCH} instead of ${TARGET_MACHINE_PLATFORM}.
+#
+# XXX Make a PLIST substitution for RUST_PREFIX_SUBDIR.
+RUST_PREFIX=		${PREFIX}/rust-${TARGET_RUST_ARCH}
+RUST_PREFIX_SUBDIR=	rust-${TARGET_RUST_ARCH}/
+
+# Avoid conflicts when you want native-rust-native-compiler vs
+# native-rust-cross-compiler (vs native-rust-cross-compiler targeting
+# another architecture).
+#
+# XXX Find a better way to do this -- shouldn't stomp on user's
+# WRKDIR_BASENAME or ignore OBJHOSTNAME.
+WRKDIR_BASENAME=	work-${TARGET_MACHINE_PLATFORM}${_CROSSDIR_SUFFIX}
+
+# XXX Copypasta of arch.mk -- remove me and use arch.mk once we verify
+# that it produces the same RUST_ARCH on all platforms.
+TARGET_RUST_MACHINE_ARCH=	\
+	${RUST_MACHINE_ARCH.${TARGET_MACHINE_ARCH}:U${TARGET_MACHINE_ARCH}}
+.  if empty(TARGET_LOWER_VENDOR)
+TARGET_RUST_LOWER_VENDOR=	unknown
+.  else
+TARGET_RUST_LOWER_VENDOR=	${TARGET_LOWER_VENDOR}
+.  endif
+TARGET_RUST_LOWER_OPSYS=	\
+	${RUST_LOWER_OPSYS.${TARGET_LOWER_OPSYS}:U${TARGET_LOWER_OPSYS}}
+TARGET_RUST_ARCH=		\
+	${TARGET_RUST_MACHINE_ARCH}-${TARGET_RUST_LOWER_VENDOR}-${TARGET_RUST_LOWER_OPSYS}${TARGET_APPEND_ABI}
+
+# Include both the target and the native architectures.  This is
+# necessary, e.g., to natively compile build.rs scripts while
+# cross-building.
+CONFIGURE_ARGS+=	--target=${TARGET_RUST_ARCH:Q},${RUST_ARCH:Q}
+
+LDFLAGS+=			${COMPILER_RPATH_FLAG}${RUST_PREFIX}/lib
+BUILDLINK_PASSTHRU_RPATHDIRS+=	${RUST_PREFIX}/lib
+
+MAKE_ENV+=		GNU_CROSS_TARGET=${TARGET_MACHINE_GNU_PLATFORM:Q}
+
+# XXX Maybe this should use TOOLS_USE_CROSS_COMPILE like cross-libtool
+# instead of hard-coding the NetBSD layout of tooldir.
+CROSS_ROOT=	${WRKDIR}/root
+MAKE_ENV+=	CROSS_ROOT=${CROSS_ROOT:Q}
+pre-configure: pre-configure-setup-root
+pre-configure-setup-root: .PHONY
+	${RUN}${MKDIR} ${CROSS_ROOT:Q}
+	${RUN}${LN} -sf ${CROSS_DESTDIR:Q} ${CROSS_ROOT:Q}/dest
+	${RUN}${LN} -sf ${TOOLDIR:Q} ${CROSS_ROOT:Q}/tools
+
+# Note that these tools -- target-cc, target-cxx -- do not go through
+# the wrappers framework, because we're building the cross-compiler
+# right now rather than using it -- the wrappers apply to the native
+# cc/cxx/linker.  So we have to set sysroot ourselves.  But fortunately
+# the C cross-compiler is only used for a small part of this, to
+# cross-compile compiler-rt, so the risk of bypassing pkgsrc wrappers
+# is minimal -- in fact, since this cross-compiler doesn't even know
+# about pkgsrc's cross-localbase, it is even less likely to
+# accidentally pick anything up it shouldn't anyway.
+TOOLS_CREATE+=		target-cc
+TOOLS_PATH.target-cc=	${TOOLDIR}/bin/${TARGET_MACHINE_GNU_PLATFORM}-gcc # XXX shouldn't hard-code gcc
+TOOLS_ARGS.target-cc=	--sysroot=${CROSS_DESTDIR:Q}
+TOOLS_CREATE+=		target-cxx
+TOOLS_PATH.target-cxx=	${TOOLDIR}/bin/${TARGET_MACHINE_GNU_PLATFORM}-c++
+TOOLS_ARGS.target-cxx=	--sysroot=${CROSS_DESTDIR:Q}
+
+CONFIGURE_ARGS+=	\
+	--set=target.${TARGET_RUST_ARCH:Q}.cc=${TOOLS_CMD.target-cc:Q}
+CONFIGURE_ARGS+=	\
+	--set=target.${TARGET_RUST_ARCH:Q}.cxx=${TOOLS_CMD.target-cxx:Q}
+CONFIGURE_ARGS+=	\
+	--set=target.${TARGET_RUST_ARCH:Q}.linker=${TOOLS_CMD.target-cc:Q}
+CONFIGURE_ARGS+=	\
+	--set=target.${TARGET_RUST_ARCH:Q}.ar=${TOOLDIR:Q}/bin/${TARGET_MACHINE_GNU_PLATFORM:Q}-ar
+
+.endif				# empty(TARGET_MACHINE_PLATFORM)
+
 #
 # Rust unfortunately requires itself to build.  On platforms which aren't
 # supported by upstream (where they offer binary bootstraps), or where we do
 # not trust random binaries from the Internet, we need to build and provide our
 # own bootstrap.  See the stage0-bootstrap below for more details.
 #
+.if ${USE_CROSS_COMPILE:tl} == "yes"	# {
+
+# XXX Copypasta of arch.mk -- remove me and use arch.mk once we verify
+# that it produces the same RUST_ARCH on all platforms.
+RUST_MACHINE_ARCH=	${RUST_MACHINE_ARCH.${MACHINE_ARCH}:U${MACHINE_ARCH}}
+.  if empty(LOWER_VENDOR)
+RUST_LOWER_VENDOR=	unknown
+.  else
+RUST_LOWER_VENDOR=	${LOWER_VENDOR}
+.  endif
+RUST_LOWER_OPSYS=	${RUST_LOWER_OPSYS.${LOWER_OPSYS}:U${LOWER_OPSYS}}
+RUST_ARCH=		\
+	${RUST_MACHINE_ARCH}-${RUST_LOWER_VENDOR}-${RUST_LOWER_OPSYS}${APPEND_ABI}
+
+NATIVE_RUST_MACHINE_ARCH=	\
+	${RUST_MACHINE_ARCH.${NATIVE_MACHINE_ARCH}:U${NATIVE_MACHINE_ARCH}}
+.  if empty(NATIVE_LOWER_VENDOR)
+NATIVE_RUST_LOWER_VENDOR=	unknown
+.  else
+NATIVE_RUST_LOWER_VENDOR=	${NATIVE_LOWER_VENDOR}
+.  endif
+NATIVE_RUST_LOWER_OPSYS=	\
+	${RUST_LOWER_OPSYS.${NATIVE_LOWER_OPSYS}:U${NATIVE_LOWER_OPSYS}}
+NATIVE_RUST_ARCH=		\
+	${NATIVE_RUST_MACHINE_ARCH}-${NATIVE_RUST_LOWER_VENDOR}-${NATIVE_RUST_LOWER_OPSYS}${NATIVE_APPEND_ABI}
+
+# XXX Doesn't actually require the latest version!  In principle we
+# should be able to bootstrap this all the way back to OCaml via some
+# series of older versions.
+TOOL_DEPENDS+=		rust-${MACHINE_PLATFORM}>=${PKGVERSION}:../../${PKGPATH}
+RUST_BOOTSTRAP_PATH=	${TOOLBASE}/rust-${RUST_ARCH}
+
+CONFIGURE_ARGS+=	--host=${RUST_ARCH:Q}
+
+# XXX Maybe omit this if rust-internal-llvm option is enabled?
+CONFIGURE_ARGS+=	--set=target.${NATIVE_RUST_ARCH:Q}.llvm-config=${TOOLBASE:Q}/bin/llvm-config
+
+.else					# } {
+
 DISTFILES:=		${DEFAULT_DISTFILES}
 
 .if ${MACHINE_PLATFORM:MDarwin-*-aarch64} || make(distinfo) || make (makesum) || make(mdi)
@@ -386,6 +525,8 @@ SITES.${RUST_STAGE0}=		${MASTER_SITE_LOCAL:=rust/}
 SITES.${RUST_STD_STAGE0}=	${MASTER_SITE_LOCAL:=rust/}
 .endif
 
+.endif					# }
+
 # You may override RUST_BOOTSTRAP_PATH and RUST_ARCH in mk.conf
 # if you have a local bootstrap compiler.
 .if !defined(RUST_ARCH) && !defined(RUST_BOOTSTRAP_PATH)
@@ -398,8 +539,8 @@ RUST_BOOTSTRAP_PATH?=	${WRKDIR}/rust-bootstrap
 TOOL_DEPENDS+=		coreutils>=0:../../sysutils/coreutils
 TOOL_DEPENDS+=		gzip>=0:../../archivers/gzip
 TOOLS_CREATE+=		md5sum
-TOOLS_PATH.md5sum=	${PREFIX}/bin/gmd5sum
-TOOLS_PLATFORM.gzcat=	${PREFIX}/bin/gzip -cd
+TOOLS_PATH.md5sum=	${TOOLBASE}/bin/gmd5sum
+TOOLS_PLATFORM.gzcat=	${TOOLBASE}/bin/gzip -cd
 .endif
 
 SUBST_CLASSES+=		prefix
@@ -409,7 +550,7 @@ SUBST_FILES.prefix+=	compiler/rustc_target/src/spec/base/netbsd.rs
 SUBST_FILES.prefix+=	src/bootstrap/src/core/build_steps/compile.rs
 SUBST_FILES.prefix+=	src/bootstrap/src/core/builder.rs
 SUBST_FILES.prefix+=	src/bootstrap/bootstrap.py
-SUBST_VARS.prefix=	PREFIX
+SUBST_VARS.prefix=	PREFIX RUST_PREFIX
 
 #
 # Generate list of subst entries for various .cargo-checksum.json files.  These
@@ -561,12 +702,12 @@ do-build:
 	${SETENV} ${MAKE_ENV}						\
 	sh -c "if [ \"${BUILD_TARGET}\" = \"dist\" ]; then		\
 		unset DESTDIR;						\
-		${PYTHONBIN} ./x.py -v					\
+		${TOOL_PYTHONBIN} ./x.py -v				\
 		    ${BUILD_TARGET} -j ${_MAKE_JOBS_N};			\
 	else								\
-		${PYTHONBIN} ./x.py -v					\
+		${TOOL_PYTHONBIN} ./x.py -v				\
 		    ${BUILD_TARGET} --stage 2 -j ${_MAKE_JOBS_N} &&	\
-		${PYTHONBIN} ./x.py -v					\
+		${TOOL_PYTHONBIN} ./x.py -v				\
 		    doc --stage 2 -j ${_MAKE_JOBS_N};			\
 	fi"
 
@@ -574,18 +715,27 @@ do-test:
 	${RUN}${_ULIMIT_CMD}						\
 	cd ${WRKSRC} &&							\
 	${SETENV} ${MAKE_ENV}						\
-		${PYTHONBIN} ./x.py -v test -j ${_MAKE_JOBS_N}
+		${TOOL_PYTHONBIN} ./x.py -v test -j ${_MAKE_JOBS_N}
 
 do-install:
 	${RUN}${_ULIMIT_CMD}						\
 	cd ${WRKSRC} &&							\
 	${SETENV} ${MAKE_ENV} ${INSTALL_ENV} 				\
-		${PYTHONBIN} ./x.py -v install -j ${_MAKE_JOBS_N}
+		${TOOL_PYTHONBIN} ./x.py -v install -j ${_MAKE_JOBS_N}
+.if !empty(TARGET_MACHINE_PLATFORM)
+	${RUN}								\
+	${GTAR} -C ${WRKDIR:Q}						\
+		-xzf ${WRKSRC:Q}/build/dist/rust-std-${PKGVERSION_NOREV:Q}-${TARGET_RUST_ARCH:Q}.tar.xz
+	${RUN}								\
+	cd ${WRKDIR:Q}/rust-std-${PKGVERSION_NOREV:Q}-${TARGET_RUST_ARCH:Q} && \
+	${SETENV} ${MAKE_ENV} ${INSTALL_ENV}				\
+		./install.sh --prefix=${RUST_PREFIX:Q} --destdir=${DESTDIR:Q}
+.endif
 
 SUBST_CLASSES+=		destdir
 SUBST_STAGE.destdir=	post-install
-SUBST_FILES.destdir=	${DESTDIR}${PREFIX}/lib/rustlib/manifest-*
-SUBST_SED.destdir=	-e 's|file:${DESTDIR}${PREFIX}|file:${PREFIX}|'
+SUBST_FILES.destdir=	${DESTDIR}${RUST_PREFIX}/lib/rustlib/manifest-*
+SUBST_SED.destdir=	-e 's|file:${DESTDIR}${RUST_PREFIX}|file:${RUST_PREFIX}|'
 
 GENERATE_PLIST+=	${FIND} ${DESTDIR}${PREFIX} \( -type f -o -type l \) -print | \
 			${SED} -e 's,${DESTDIR}${PREFIX}/,,' | ${SORT} ;
@@ -640,8 +790,8 @@ stage0-bootstrap: install
 	)
 .endif
 .if ${OS_VARIANT} == "SmartOS"
-	${CP} -R ${DESTDIR}/${PREFIX}/bin ${BOOTSTRAP_TMPDIR}/
-	${CP} -R ${DESTDIR}/${PREFIX}/lib ${BOOTSTRAP_TMPDIR}/
+	${CP} -R ${DESTDIR}/${RUST_PREFIX}/bin ${BOOTSTRAP_TMPDIR}/
+	${CP} -R ${DESTDIR}/${RUST_PREFIX}/lib ${BOOTSTRAP_TMPDIR}/
 	${MKDIR} ${BOOTSTRAP_TMPDIR}/lib/pkgsrc
 	set -e; \
 	for lib in libgcc_s.so.1 libstdc++.so.6; do \
@@ -650,12 +800,12 @@ stage0-bootstrap: install
 	done; \
 	for lib in libLLVM.so.18.1 libcrypto.so.3 libcurl.so.4 \
 		   libssl.so.3 libz.so.1 libzstd.so.1; do \
-		${CP} ${PREFIX}/lib/$${lib} ${BOOTSTRAP_TMPDIR}/lib/pkgsrc/; \
+		${CP} ${RUST_PREFIX}/lib/$${lib} ${BOOTSTRAP_TMPDIR}/lib/pkgsrc/; \
 	done; \
 	for lib in libiconv.so.2 libidn2.so.0 libintl.so.8 liblber.so.2 \
 		   libldap.so.2 libnghttp2.so.14 libsasl2.so.3 \
 		   libssh2.so.1 libunistring.so.5; do \
-		${CP} ${PREFIX}/lib/$${lib} ${BOOTSTRAP_TMPDIR}/lib/pkgsrc/; \
+		${CP} ${RUST_PREFIX}/lib/$${lib} ${BOOTSTRAP_TMPDIR}/lib/pkgsrc/; \
 	done; \
 	for f in ${BOOTSTRAP_TMPDIR}/bin/*; do \
 		/bin/file -b "$$f" | grep ^ELF >/dev/null || continue; \
@@ -675,7 +825,7 @@ stage0-bootstrap: install
 	@${ECHO} "Verify correct library paths using the following:"
 	@${ECHO} ""
 	@${ECHO} "	cd ${BOOTSTRAP_TMPDIR}"
-	@${ECHO} "	find . -type f | xargs ldd 2>/dev/null | egrep 'not.found|${PREFIX}'"
+	@${ECHO} "	find . -type f | xargs ldd 2>/dev/null | egrep 'not.found|${RUST_PREFIX}'"
 	@${ECHO} ""
 	@${ECHO} "If there is no output then this bootstrap kit is ready to go:"
 	@${ECHO} ""
@@ -698,8 +848,8 @@ stage0-bootstrap: install
 # rust i386 and sparc64 bootstraps are built for 8.0
 # and still depend on libstdc++.so.8.
 # Pull in compat80 on 9.x and newer.
-.if (${MACHINE_PLATFORM:MNetBSD-*-i386} || \
-     ${MACHINE_PLATFORM:MNetBSD-*-sparc64}) \
+.if (${NATIVE_MACHINE_PLATFORM:MNetBSD-*-i386} || \
+     ${NATIVE_MACHINE_PLATFORM:MNetBSD-*-sparc64}) \
     && empty(OS_VERSION:M8.*)
 TOOL_DEPENDS+=	compat80>=0:../../emulators/compat80
 .endif
@@ -714,8 +864,8 @@ TOOL_DEPENDS+=	compat80>=0:../../emulators/compat80
 DEPENDS+=	libatomic-links>=0:../../devel/libatomic-links
 .endif
 
-TOOL_DEPENDS+= cmake-[0-9]*:../../devel/cmake
-.include "../../devel/cmake/buildlink3.mk"
+TOOL_DEPENDS+=	cmake-[0-9]*:../../devel/cmake
+
 .include "../../devel/zlib/buildlink3.mk"
 .include "../../lang/python/tool.mk"
 .include "../../mk/bsd.pkg.mk"
diff --git a/lang/rust/arch.mk b/lang/rust/arch.mk
new file mode 100644
index 000000000000..f8b75dc5ac5c
--- /dev/null
+++ b/lang/rust/arch.mk
@@ -0,0 +1,64 @@
+#	$NetBSD$
+#
+# Common logic to map pkgsrc idea of machine platforms into Rust idea
+# of architectures.
+#
+# System-provided variables:
+#
+# RUST_ARCH
+#	The Rust architecture triple that this package is built for.
+#
+# NATIVE_RUST_ARCH
+#	The Rust architecture triple that we are doing the build on.
+#
+# TARGET_RUST_ARCH
+#	If nonempty, the Rust architecture triple that this package may
+#	be intended to support as a cross-compiler target.
+#
+#	Nonempty if and only if TARGET_MACHINE_PLATFORM is nonempty,
+#	i.e., this package is being built as a TOOL_DEPENDS dependency
+#	of another package and thus may be being built as a
+#	cross-compiler.
+#
+
+RUST_MACHINE_ARCH.i386=		i586		# not really
+RUST_MACHINE_ARCH.aarch64eb=	aarch64_be
+RUST_MACHINE_ARCH.riscv64=	riscv64gc
+
+RUST_LOWER_OPSYS.solaris=	illumos
+
+RUST_MACHINE_ARCH=	${RUST_MACHINE_ARCH.${MACHINE_ARCH}:U${MACHINE_ARCH}}
+.if empty(LOWER_VENDOR)
+RUST_LOWER_VENDOR=	unknown
+.else
+RUST_LOWER_VENDOR=	${LOWER_VENDOR}
+.endif
+RUST_LOWER_OPSYS=	${RUST_LOWER_OPSYS.${LOWER_OPSYS}:U${LOWER_OPSYS}}
+RUST_ARCH=		\
+	${RUST_MACHINE_ARCH}-${RUST_LOWER_VENDOR}-${RUST_LOWER_OPSYS}${APPEND_ABI}
+
+NATIVE_RUST_MACHINE_ARCH=	\
+	${RUST_MACHINE_ARCH.${NATIVE_MACHINE_ARCH}:U${NATIVE_MACHINE_ARCH}}
+.if empty(NATIVE_LOWER_VENDOR)
+NATIVE_RUST_LOWER_VENDOR=	unknown
+.else
+NATIVE_RUST_LOWER_VENDOR=	${NATIVE_LOWER_VENDOR}
+.endif
+NATIVE_RUST_LOWER_OPSYS=	\
+	${RUST_LOWER_OPSYS.${NATIVE_LOWER_OPSYS}:U${NATIVE_LOWER_OPSYS}}
+NATIVE_RUST_ARCH=		\
+	${NATIVE_RUST_MACHINE_ARCH}-${NATIVE_RUST_LOWER_VENDOR}-${NATIVE_RUST_LOWER_OPSYS}${NATIVE_APPEND_ABI}
+
+.if !empty(TARGET_MACHINE_PLATFORM)
+TARGET_RUST_MACHINE_ARCH=	\
+	${RUST_MACHINE_ARCH.${TARGET_MACHINE_ARCH}:U${TARGET_MACHINE_ARCH}}
+.  if empty(TARGET_LOWER_VENDOR)
+TARGET_RUST_LOWER_VENDOR=	unknown
+.  else
+TARGET_RUST_LOWER_VENDOR=	${TARGET_LOWER_VENDOR}
+.  endif
+TARGET_RUST_LOWER_OPSYS=	\
+	${RUST_LOWER_OPSYS.${TARGET_LOWER_OPSYS}:U${TARGET_LOWER_OPSYS}}
+TARGET_RUST_ARCH=		\
+	${TARGET_RUST_MACHINE_ARCH}-${TARGET_RUST_LOWER_VENDOR}-${TARGET_RUST_LOWER_OPSYS}${TARGET_APPEND_ABI}
+.endif
diff --git a/lang/rust/cargo.mk b/lang/rust/cargo.mk
index 5a3ed0cf8306..c5e78ac22794 100644
--- a/lang/rust/cargo.mk
+++ b/lang/rust/cargo.mk
@@ -72,18 +72,59 @@ print-cargo-depends:
 
 .if ${RUST_TYPE} == "native"
 CARGO=			cargo
+.elif ${USE_CROSS_COMPILE:tl} == "yes"
+# XXX Nix this conditional once we verify no fallout for native builds:
+# using TOOLS_CREATE to create a cargo tool, and writing
+# ${TOOLBASE}/bin/cargo instead of ${PREFIX}/bin/cargo, and similarly
+# for rustc, should all work just fine for native builds.
+.  include "arch.mk"
+CARGO=			cargo
+TOOLS_CREATE+=		cargo
+.  if ${USE_CROSS_COMPILE:tl} == "yes"
+TOOLS_PATH.cargo=	${TOOLBASE}/rust-${RUST_ARCH}/bin/cargo
+.  else
+TOOLS_PATH.cargo=	${TOOLBASE}/bin/cargo
+.  endif
+TOOLS_CREATE+=		rustc
+.  if ${USE_CROSS_COMPILE:tl} == "yes"
+TOOLS_PATH.rustc=	${TOOLBASE}/rust-${RUST_ARCH}/bin/rustc
+.  else
+TOOLS_PATH.rustc=	${TOOLBASE}/bin/rustc
+.  endif
 .else
 CARGO=			${PREFIX}/bin/cargo
 .endif
+
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+ALL_ENV+=		CARGO_TARGET_${NATIVE_RUST_ARCH:S/-/_/g:tu}_LINKER=native-cc
+TOOLS_CREATE+=		native-cc
+TOOLS_SCRIPT.native-cc=	${NATIVE_CC}
+.endif				# ${USE_CROSS_COMPILE:tl} == "yes"
+
 DEFAULT_CARGO_ARGS=	--offline -j${_MAKE_JOBS_N}	\
 			  ${CARGO_NO_DEFAULT_FEATURES:M[yY][eE][sS]:C/[yY][eE][sS]/--no-default-features/}	\
 			  ${CARGO_FEATURES:C/.*/--features/W}	\
 			  ${CARGO_FEATURES:S/ /,/Wg}
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+# XXX Consider setting CARGO_BUILD_TARGET=${RUST_ARCH:Q} in the
+# environment instead, for the benefit of packages built with tools
+# like py-maturin which call cargo but not directly with our do-build
+# target or CARGO_ARGS.
+DEFAULT_CARGO_ARGS+=	--target ${RUST_ARCH:Q}
+.endif
 CARGO_ARGS?=		build --release ${DEFAULT_CARGO_ARGS}
 CARGO_INSTALL_ARGS?=	install --path . --root ${DESTDIR}${PREFIX} ${DEFAULT_CARGO_ARGS}
 
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+CARGO_OUTPUT_SUBDIR=	target/${RUST_ARCH}/release
+.else
+CARGO_OUTPUT_SUBDIR=	target/release
+.endif
+CARGO_OUTPUT_DIR=	${WRKSRC}/${CARGO_OUTPUT_SUBDIR}
+
 MAKE_ENV+=		RUSTFLAGS=${RUSTFLAGS:Q}
 ALL_ENV+=		CARGO_HOME=${WRKDIR}
+ALL_ENV+=		${defined(ALLOW_NETWORK_ACCESS):?:CARGO_NET_OFFLINE=true}
 
 .if !target(do-build)
 do-build: do-cargo-build
diff --git a/lang/rust/distinfo b/lang/rust/distinfo
index 991b8ab88c85..b79a69394c08 100644
--- a/lang/rust/distinfo
+++ b/lang/rust/distinfo
@@ -121,11 +121,11 @@ SHA1 (patch-config.example.toml) = 520ad7a26249780ae79a5dc1d2b534a8c6aef0a5
 SHA1 (patch-library_backtrace_src_symbolize_gimli.rs) = 9d5ef634c5a454e474ea5fee76da9bb768f5b3d9
 SHA1 (patch-library_backtrace_src_symbolize_gimli_elf.rs) = 3b84a462c6bc8245d579452e4c37e3ce13314952
 SHA1 (patch-library_std_src_sys_pal_unix_mod.rs) = bfc59ae4568547e3ed71c8b31ba5b5b5363d5d40
-SHA1 (patch-src_bootstrap_bootstrap.py) = 6f1d3068da49f19c3e092230ba1c7d99af628d3a
+SHA1 (patch-src_bootstrap_bootstrap.py) = 6ce15a434d163f921cc77c15c4b0c759a4de39f5
 SHA1 (patch-src_bootstrap_src_core_build__steps_compile.rs) = e928203ed4734c93cc33c5a3f7879cf18dcecc83
 SHA1 (patch-src_bootstrap_src_core_build__steps_dist.rs) = eb228d43e1cf21ec646b516b8c67c648c7183f8a
 SHA1 (patch-src_bootstrap_src_core_build__steps_install.rs) = cc6558df42c9c9ac28fdb2ff180bdaa7f22ce816
-SHA1 (patch-src_bootstrap_src_core_builder.rs) = e3fd19e0a18f1e79e287c85035ea431b98d91d9a
+SHA1 (patch-src_bootstrap_src_core_builder.rs) = b077845e04d83a500eeac3cae4d4b0baa5b3bafe
 SHA1 (patch-src_bootstrap_src_core_config_config.rs) = fa9d93602693bce064aa155ad0a204b176b47d99
 SHA1 (patch-src_bootstrap_src_lib.rs) = d29bc3c0b335d5e788eecbb02fc08966beef0fb1
 SHA1 (patch-src_llvm-project_llvm_CMakeLists.txt) = 7abfabb6ec70df229a69355f8c76825610165c37
diff --git a/lang/rust/patches/patch-src_bootstrap_bootstrap.py b/lang/rust/patches/patch-src_bootstrap_bootstrap.py
index 3166c52a7f37..f29c058d0056 100644
--- a/lang/rust/patches/patch-src_bootstrap_bootstrap.py
+++ b/lang/rust/patches/patch-src_bootstrap_bootstrap.py
@@ -36,10 +36,11 @@ Also use @PREFIX@ and not $ORIGIN in rpath.
          else:
              kernel += 'eabihf'
      elif cputype == 'mips':
-@@ -734,6 +745,7 @@ class RustBuild(object):
+@@ -734,6 +745,8 @@ class RustBuild(object):
  
          patchelf = "{}/bin/patchelf".format(nix_deps_dir)
          rpath_entries = [
++            "@RUST_PREFIX@/lib",
 +	    "@PREFIX@/lib",
              os.path.join(os.path.realpath(nix_deps_dir), "lib")
          ]
diff --git a/lang/rust/patches/patch-src_bootstrap_src_core_builder.rs b/lang/rust/patches/patch-src_bootstrap_src_core_builder.rs
index 7db4e8beb1ac..e2c076d2850c 100644
--- a/lang/rust/patches/patch-src_bootstrap_src_core_builder.rs
+++ b/lang/rust/patches/patch-src_bootstrap_src_core_builder.rs
@@ -1,7 +1,7 @@
 $NetBSD: patch-src_bootstrap_src_core_builder.rs,v 1.5 2024/07/27 02:35:24 tnn Exp $
 
 Find external libunwind on Linux.
-Use @PREFIX@, not $ORIGIN in rpath.
+Use @RUST_PREFIX@ and @PREFIX@, not $ORIGIN in rpath.
 
 --- src/bootstrap/src/core/builder.rs.orig	2006-07-24 01:21:28.000000000 +0000
 +++ src/bootstrap/src/core/builder.rs
@@ -22,7 +22,7 @@ Use @PREFIX@, not $ORIGIN in rpath.
              } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
                  self.rustflags.arg("-Clink-args=-Wl,-z,origin");
 -                Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
-+                Some(format!("-Wl,-rpath,@PREFIX@/{libdir}"))
++                Some(format!("-Wl,-rpath,@RUST_PREFIX@/{libdir},-rpath,@PREFIX@/lib"))
              } else {
                  None
              };
diff --git a/lang/rust/rust.mk b/lang/rust/rust.mk
index 82185914b67b..9b7cefbb6882 100644
--- a/lang/rust/rust.mk
+++ b/lang/rust/rust.mk
@@ -40,17 +40,51 @@ RUST_RUNTIME?=	no
 RUST_TYPE?=	src
 
 .if ${RUST_TYPE} == "bin"
+# XXX Remove this ${USE_CROSS_COMPILE} conditional once we confirm no
+# fallout in native builds from the TOOL_DEPENDS approach.
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+.  include "arch.mk"
+.  if ${USE_CROSS_COMPILE:tl} == "yes"
+TOOL_DEPENDS+=			rust-${MACHINE_PLATFORM}-bin>=${RUST_REQ}:../../lang/rust-bin
+BUILDLINK_PASSTHRU_DIRS+=	${TOOLBASE}/rust-${RUST_ARCH}/lib/rustlib
+.  else
+TOOL_DEPENDS+=			rust-bin>=${RUST_REQ}:../../lang/rust-bin
+BUILDLINK_PASSTHRU_DIRS+=	${TOOLBASE}/lib/rustlib
+.  endif
+.  if ${RUST_RUNTIME} != "no"
+BUILDLINK_API_DEPENDS.rust-bin+=	rust-bin>=${RUST_REQ}
+.    include "${RUST_DIR}-bin/buildlink3.mk"
+.  endif
+.else
 .  if ${RUST_RUNTIME} == "no"
 BUILDLINK_DEPMETHOD.rust-bin?=		build
 .  endif
 BUILDLINK_API_DEPENDS.rust-bin+=	rust-bin>=${RUST_REQ}
 .  include "${RUST_DIR}-bin/buildlink3.mk"
 .endif
+.endif
 
 .if ${RUST_TYPE} == "src"
+# XXX Remove this ${USE_CROSS_COMPILE} conditional once we confirm no
+# fallout in native builds from the TOOL_DEPENDS approach.
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+.  include "arch.mk"
+.  if ${USE_CROSS_COMPILE:tl} == "yes"
+TOOL_DEPENDS+=			rust-${MACHINE_PLATFORM}>=${RUST_REQ}:../../lang/rust
+BUILDLINK_PASSTHRU_DIRS+=	${TOOLBASE}/rust-${RUST_ARCH}/lib/rustlib
+.  else
+TOOL_DEPENDS+=			rust>=${RUST_REQ}:../../lang/rust
+BUILDLINK_PASSTHRU_DIRS+=	${TOOLBASE}/lib/rustlib
+.  endif
+.  if ${RUST_RUNTIME} != "no"
+BUILDLINK_API_DEPENDS.rust+=		rust>=${RUST_REQ}
+.    include "${RUST_DIR}/buildlink3.mk"
+.  endif
+.else
 .  if ${RUST_RUNTIME} == "no"
 BUILDLINK_DEPMETHOD.rust?=		build
 .  endif
 BUILDLINK_API_DEPENDS.rust+=		rust>=${RUST_REQ}
 .  include "${RUST_DIR}/buildlink3.mk"
 .endif
+.endif
diff --git a/security/py-cryptography/Makefile b/security/py-cryptography/Makefile
index f9a5bb3fad77..1849cc984102 100644
--- a/security/py-cryptography/Makefile
+++ b/security/py-cryptography/Makefile
@@ -11,6 +11,7 @@ COMMENT=	Cryptographic recipes and primitives for Python
 LICENSE=	apache-2.0 OR modified-bsd
 
 TOOL_DEPENDS+=	${PYPKGPREFIX}-setuptools>=61.0.0:../../devel/py-setuptools
+TOOL_DEPENDS+=	${PYPKGPREFIX}-cffi>=1.12:../../devel/py-cffi
 DEPENDS+=	${PYPKGPREFIX}-cffi>=1.12:../../devel/py-cffi
 TEST_DEPENDS+=	${PYPKGPREFIX}-cryptography_vectors-${PKGVERSION_NOREV}:../../security/py-cryptography_vectors
 TEST_DEPENDS+=	${PYPKGPREFIX}-certifi-[0-9]*:../../security/py-certifi
@@ -25,6 +26,16 @@ MAKE_ENV+=	CARGO_NET_OFFLINE=true
 MAKE_ENV+=	OPENSSL_DIR=${BUILDLINK_PREFIX.openssl}
 RUSTFLAGS+=	-C link-arg=${COMPILER_RPATH_FLAG}${BUILDLINK_PREFIX.openssl}/lib
 
+.include "../../mk/bsd.prefs.mk"
+
+# With Cargo we use `cargo --target ${RUST_ARCH}', but we need to pass
+# this through py-maturin instead.
+#
+# XXX Maybe this should be in devel/py-maturin/tool.mk.
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+MAKE_ENV+=	CARGO_BUILD_TARGET=${RUST_ARCH:Q}
+.endif
+
 pre-build:
 	cd ${WRKSRC} && ${LN} -f -s src/rust/.cargo .cargo
 
diff --git a/textproc/dbcat/Makefile b/textproc/dbcat/Makefile
index abeddf5474ed..58cfd70b0e69 100644
--- a/textproc/dbcat/Makefile
+++ b/textproc/dbcat/Makefile
@@ -15,7 +15,7 @@ LICENSE=	mit
 INSTALLATION_DIRS=	bin
 
 do-install:
-	${INSTALL_PROGRAM} ${WRKSRC}/target/release/dbcat ${DESTDIR}${PREFIX}/bin
+	${INSTALL_PROGRAM} ${CARGO_OUTPUT_DIR}/dbcat ${DESTDIR}${PREFIX}/bin
 
 .include "../../lang/rust/cargo.mk"
 .include "../../mk/bsd.pkg.mk"
diff --git a/x11/xcolor/Makefile b/x11/xcolor/Makefile
index 037c3c6eb57d..7c134fc65490 100644
--- a/x11/xcolor/Makefile
+++ b/x11/xcolor/Makefile
@@ -22,7 +22,7 @@ RUSTFLAGS+=	-C link-arg=${COMPILER_RPATH_FLAG}${BUILDLINK_PREFIX.libX11}/lib
 RUSTFLAGS+=	-C link-arg=${COMPILER_RPATH_FLAG}${BUILDLINK_PREFIX.libxcb}/lib
 
 do-install:
-	${INSTALL_PROGRAM} ${WRKSRC}/target/release/xcolor ${DESTDIR}${PREFIX}/bin
+	${INSTALL_PROGRAM} ${CARGO_OUTPUT_DIR}/xcolor ${DESTDIR}${PREFIX}/bin
 	${INSTALL_MAN} ${WRKSRC}/man/xcolor.1 ${DESTDIR}${PREFIX}/${PKGMANDIR}/man1/xcolor.1
 
 .include "../../lang/rust/cargo.mk"


Home | Main Index | Thread Index | Old Index