tech-pkg archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[PATCH] Cross-building rusty packages
The attached patch is a substantial revision of my previous changes
for Rust cross-builds.
Using this patch (or slightly earlier revisions of it, differing by
minor tweaks and rebases of pkgsrc -- it takes a long time to build
all this stuff), I've been able to:
1. natively compile a Rust cross-toolchain without the
cross.mk/do-cross.mk scaffolding, that is, using only pkgsrc's
TARGET_* variables which are set automatically for TOOL_DEPENDS of
cross-built packages;
2. cross-compile a native Rust toolchain (and build a bootstrap kit as
a byproduct) using pkgsrc's built-in cross-compilation support; and
3. cross-compile other rusty packages including www/firefox (with some
other local changes not yet committed).
This puts back one annoying ${ :? : } ternary operator versus the
crossrust-v2.patch I posted a while ago because of tricky ordering
between the assignment of PKGNAME and use of TARGET_MACHINE_PLATFORM
relative to bsd.prefs.mk -- sorry, I don't think there is a better way
to do this right now.
I sought to minimize changes that could even potentially affect native
builds of a native toolchain and native rusty packages by keeping
almost all the logic scoped under !empty(TARGET_MACHINE_PLATFORM) or
${USE_CROSS_COMPILE:tl} == "yes". There are a couple minor changes
that _could_ affect native builds but I don't think they have any real
consequences -- see the commit message and patch for details.
I also have analogous patches queued up for pkgsrc-wip to rust181
through rust184. These patches depend on the CARGO_TARGET_DIR patch
(https://mail-index.NetBSD.org/tech-pkg/2025/02/06/msg030459.html).
OK?
From b844dbdba7adabccec61c161093467728eb8b234 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Date: Thu, 6 Feb 2025 13:54:57 +0000
Subject: [PATCH] lang/rust: Add support for cross-compiling Rust packages.
This does several things:
1. Enables lang/rust to build a cross-compiler package.
2. Enables lang/rust to be cross-compiled itself.
3. Enables other packages written in Rust to be cross-compiled.
Details:
1. Enables lang/rust to build a cross-compiler package, which is
named, e.g., rust-NetBSD-10.0-aarch64-1.82.0 instead of
rust-1.82.0, with all its files installed under
${PREFIX}/rust-NetBSD-10.0-aarch64 so it doesn't conflict.
=> The installation directory is called RUST_PREFIX in the
Makefile -- which is just PREFIX when TARGET_* is not set,
i.e., when we're building a normal Rust toolchain, not a
cross-toolchain, so no change to native builds.
=> The Rust architecture determination is moved to a data-driven
table in lang/rust/arch.mk. (For now, the conditional-driven
table is preserved in order to avoid the possibility of
regressions in native builds -- we can clean this up later and
reduce the makefile once we confirm they agree.)
NOTE: This adds two patches that potentially affect native builds,
but I don't think it will cause any trouble:
(a) Use `-L=@PREFIX@/lib/libatomic' instead of
`-L@PREFIX@/lib/libatomic' in the compiler's target spec.
=> This is unlikely to affect native builds -- the `-L='
notation means the path is to be taken relative to sysroot,
but in native builds the sysroot is empty (or /), so it
should only change things when the sysroot is nonempty as
in cross-builds.
(b) Add @RUST_PREFIX@/lib to a couple of library search paths that
already have @PREFIX@/lib.
=> In native builds, RUST_PREFIX and PREFIX coincide, so this
should be harmless.
2. Enables lang/rust to be cross-compiled itself using pkgsrc's
normal cross-compilation procedures.
=> This TOOL_DEPENDS on the cross-compiler package of (1).
=> This produces a Rust bootstrap kit as a side effect under the
wrkdir, without having to configure the rust-specific
cross.mk/do-cross.mk machinery.
3. Enables packages which are written in Rust using rust.mk or
cargo.mk to be cross-compiled using the cross-compiler package of
(1).
=> rust.mk and cargo.mk are adapted to:
- pull in the appropriate TOOL_DEPENDS for Rust cross-compiler
packages;
- create `rustc' and `cargo' tools that point at the right
place -- ${TOOLBASE}/rust-${RUST_ARCH}/bin/cargo for
cross-builds, plus a native-cc tool that uses ${NATIVE_CC} in
cross-builds;
- pass `--target ${RUST_ARCH}' to cargo, and
- set CARGO_TARGET_DIR with the extra RUST_ARCH path component
so packages' do-install targets can use it to find the build
products in native and cross builds alike.
=> I believe the logic for cross-built TOOL_DEPENDS should also
work for native builds. But to avoid the possibility of
regressions, I have kept all these changes under
USE_CROSS_COMPILE yes conditionals.
Proposed on tech-pkg:
https://mail-index.NetBSD.org/tech-pkg/2025/01/12/msg030371.html
---
lang/rust/Makefile | 234 ++++++++++++++++--
lang/rust/arch.mk | 64 +++++
lang/rust/cargo.mk | 37 +++
lang/rust/distinfo | 6 +-
lang/rust/options.mk | 8 +-
...iler_rustc__target_src_spec_base_netbsd.rs | 2 +-
.../patches/patch-src_bootstrap_bootstrap.py | 3 +-
.../patch-src_bootstrap_src_core_builder.rs | 4 +-
lang/rust/rust.mk | 34 +++
9 files changed, 365 insertions(+), 27 deletions(-)
create mode 100644 lang/rust/arch.mk
diff --git a/lang/rust/Makefile b/lang/rust/Makefile
index 6a3d5f502923..45754d824d36 100644
--- a/lang/rust/Makefile
+++ b/lang/rust/Makefile
@@ -1,7 +1,7 @@
# $NetBSD: Makefile,v 1.322 2025/02/02 13:34:47 he Exp $
DISTNAME= rustc-1.82.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/
@@ -12,6 +12,8 @@ LICENSE= mit OR apache-2.0
CONFLICTS+= rust-bin-[0-9]*
+PKGNAME_TARGET_SUFFIX= ${empty(TARGET_MACHINE_PLATFORM):?:-${TARGET_MACHINE_PLATFORM}}
+
# LLVM uses -std=c++17
USE_CXX_FEATURES+= c++17
USE_GCC_RUNTIME= yes
@@ -35,9 +37,9 @@ HAS_CONFIGURE= yes
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+= --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}
@@ -88,6 +90,22 @@ TEST_TARGET= check
CHECK_RELRO_SUPPORTED= no
CHECK_SSP_SUPPORTED= no
+# Avoid conflicts when you want native-rust-native-compiler vs
+# native-rust-cross-compiler (vs native-rust-cross-compiler targeting
+# another architecture).
+#
+# There is an annoying ordering constraint here: we have to set
+# WRKDIR_BASENAME before including bsd.prefs.mk, but bsd.prefs.mk
+# defines TARGET_MACHINE_PLATFORM. So we make the conditional be based
+# on TARGET_MACHINE_ARCH, which is passed through recursive make flags
+# (and is used to determine TARGET_MACHINE_PLATFORM).
+#
+# XXX Find a better way to do this -- shouldn't stomp on user's
+# WRKDIR_BASENAME or ignore OBJHOSTNAME.
+.if !empty(TARGET_MACHINE_ARCH)
+WRKDIR_BASENAME= work-${TARGET_MACHINE_PLATFORM}${_CROSSDIR_SUFFIX}
+.endif
+
.include "../../mk/bsd.prefs.mk"
# Allow overriding MAKE_JOBS_SAFE
@@ -103,7 +121,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 +163,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 +219,181 @@ 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}/
+
+# 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
+
+# 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}
+# XXX
+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.
+#
+# XXX Use a native bootstrap kit if available and desired -- requires
+# changing all the MACHINE_PLATFORMs below to NATIVE_MACHINE_PLATFORMs.
+TOOL_DEPENDS+= rust-${MACHINE_PLATFORM}>=${PKGVERSION}:../../${PKGPATH}
+RUST_BOOTSTRAP_PATH= ${TOOLBASE}/rust-${RUST_ARCH}
+
+# Cross-build to run on MACHINE_PLATFORM, phrased for Rust as
+# RUST_ARCH.
+CONFIGURE_ARGS+= --host=${RUST_ARCH:Q}
+
+TOOLS_CREATE+= native-cc native-cxx native-ar
+TOOLS_SCRIPT.native-cc= exec ${NATIVE_CC} "$$@"
+TOOLS_SCRIPT.native-cxx=exec ${NATIVE_CXX} "$$@"
+TOOLS_SCRIPT.native-ar= exec ${NATIVE_AR} "$$@"
+
+CONFIGURE_ARGS+= \
+ --set=target.${NATIVE_RUST_ARCH:Q}.cc=${TOOLS_CMD.native-cc:Q}
+CONFIGURE_ARGS+= \
+ --set=target.${NATIVE_RUST_ARCH:Q}.cxx=${TOOLS_CMD.native-cxx:Q}
+CONFIGURE_ARGS+= \
+ --set=target.${NATIVE_RUST_ARCH:Q}.linker=${TOOLS_CMD.native-cc:Q}
+CONFIGURE_ARGS+= \
+ --set=target.${NATIVE_RUST_ARCH:Q}.ar=${TOOLS_CMD.native-ar:Q}
+
+# Not all of the build respects --set=target options, so try harder.
+#
+# For example:
+#
+# warning: libz-sys@1.1.18: ToolExecError: Command "aarch64--netbsd-gcc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-m64" "-I" "src/zlib" "-fvisibility=hidden" "-DZ_SOLO" "-DSTDC" "-D_LARGEFILE64_SOURCE" "-D_POSIX_SOURCE" "-o" "/home/riastradh/pkgsrc/current/crosswork/wip/rust183/work.NetBSD-10.0-aarch64/rustc-1.83.0-src/build/x86_64-unknown-netbsd/stage1-tools/release/build/libz-sys-bfca60dc728da21b/out/lib/0dc752f03a07a721-zutil.o" "-c" "src/zlib/zutil.c" with args aarch64--netbsd-gcc did not execute successfully (status code exit status: 1).
+#
+# error: failed to run custom build command for `libz-sys v1.1.18`
+#
+# Caused by:
+# process didn't exit successfully: `/home/riastradh/pkgsrc/current/crosswork/wip/rust183/work.NetBSD-10.0-aarch64/rustc-1.83.0-src/build/x86_64-unknown-netbsd/stage1-tools/release/build/libz-sys-f4e66731319f71b4/build-script-build` (exit status: 1)
+# --- stdout
+# ...
+# TARGET = Some(x86_64-unknown-netbsd)
+# ...
+# HOST = Some(x86_64-unknown-netbsd)
+# cargo:rerun-if-env-changed=CC_x86_64-unknown-netbsd
+# CC_x86_64-unknown-netbsd = None
+# cargo:rerun-if-env-changed=CC_x86_64_unknown_netbsd
+# CC_x86_64_unknown_netbsd = None
+# cargo:rerun-if-env-changed=HOST_CC
+# HOST_CC = None
+# cargo:rerun-if-env-changed=CC
+# CC = Some(aarch64--netbsd-gcc)
+#
+# https://github.com/rust-lang/rust/issues/136090
+#
+MAKE_ENV+= HOST_CC=${TOOLS_CMD.native-cc:Q}
+MAKE_ENV+= HOST_CXX=${TOOLS_CMD.native-cxx:Q}
+MAKE_ENV+= HOST_AR=${TOOLS_CMD.native-ar:Q}
+
+# Prevent Rust from picking up CFLAGS/CXXFLAGS/LDFLAGS for the target
+# system when natively compiling things to run on the build system. We
+# pass any necessary arguments through the tool wrappers anyway.
+MAKE_ENV+= HOST_CFLAGS=
+MAKE_ENV+= HOST_CXXFLAGS=
+MAKE_ENV+= HOST_LDFLAGS=
+
+.else # } {
+
DISTFILES:= ${DEFAULT_DISTFILES}
.if ${MACHINE_PLATFORM:MDarwin-*-aarch64} || make(distinfo) || make (makesum) || make(mdi)
@@ -383,6 +570,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)
@@ -406,7 +595,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
@@ -548,11 +737,20 @@ do-install:
cd ${WRKSRC} && \
${SETENV} ${MAKE_ENV} ${INSTALL_ENV} \
${TOOL_PYTHONBIN} ./x.py 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} ;
@@ -607,8 +805,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 \
@@ -617,12 +815,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; \
@@ -643,7 +841,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} ""
@@ -666,8 +864,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
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 7dbc30f57aed..b6967fecdd5a 100644
--- a/lang/rust/cargo.mk
+++ b/lang/rust/cargo.mk
@@ -72,13 +72,46 @@ 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= exec ${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}
@@ -86,7 +119,11 @@ CARGO_INSTALL_ARGS?= install --path . --root ${DESTDIR}${PREFIX} ${DEFAULT_CARGO
# tuple (architecture/vendor/OS) and for the directory where build
# products go. The name CARGO_TARGET_DIR (or CARGO_BUILD_TARGET_DIR)
# is what cargo uses for the directory of build products.
+.if ${USE_CROSS_COMPILE:tl} == "yes"
+CARGO_TARGET_SUBDIR= target/${RUST_ARCH}/release
+.else
CARGO_TARGET_SUBDIR= target/release
+.endif
CARGO_TARGET_DIR= ${WRKSRC}/${CARGO_TARGET_SUBDIR}
MAKE_ENV+= RUSTFLAGS=${RUSTFLAGS:Q}
diff --git a/lang/rust/distinfo b/lang/rust/distinfo
index 60bac3f5ed33..5715f127b419 100644
--- a/lang/rust/distinfo
+++ b/lang/rust/distinfo
@@ -110,7 +110,7 @@ SHA512 (rustc-1.82.0-src.tar.gz) = 0a4b4aeffe02fae35bafd64429d15009c23e5f698c0c5
Size (rustc-1.82.0-src.tar.gz) = 434309696 bytes
SHA1 (patch-compiler_rustc__codegen__ssa_src_back_linker.rs) = f2af6e3b4925e8ca21b7cd783f7831b72700384a
SHA1 (patch-compiler_rustc__llvm_build.rs) = a4a66d449fc9eb99d648d02a041778a68f4f7ce8
-SHA1 (patch-compiler_rustc__target_src_spec_base_netbsd.rs) = 7d910631f49acf2c33fdd191fd3e0f261efae234
+SHA1 (patch-compiler_rustc__target_src_spec_base_netbsd.rs) = 8e6e53b44c044230089ab0740cc929fd8671d50c
SHA1 (patch-compiler_rustc__target_src_spec_mod.rs) = a22b5d28997ed9a5565deec9c34322165d563d00
SHA1 (patch-compiler_rustc__target_src_spec_targets_aarch64__be__unknown__netbsd.rs) = 620eaf74c1dd030973af53dfe4f9aa998be5b123
SHA1 (patch-compiler_rustc__target_src_spec_targets_aarch64__unknown__netbsd.rs) = 1a02f2dd61a5f9cc4be1f66ac3404c961810c731
@@ -122,11 +122,11 @@ SHA1 (patch-library_backtrace_src_symbolize_gimli.rs) = 9d5ef634c5a454e474ea5fee
SHA1 (patch-library_backtrace_src_symbolize_gimli_elf.rs) = 3b84a462c6bc8245d579452e4c37e3ce13314952
SHA1 (patch-library_std_src_sys_pal_unix_mod.rs) = bfc59ae4568547e3ed71c8b31ba5b5b5363d5d40
SHA1 (patch-library_stdarch_crates_std__detect_tests_cpu-detection.rs) = 97c3ad8ea39c25d41256fcad80fae1e6e4970124
-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) = 22e37d6260cbd93ca3c6d119b58e48750836b17c
SHA1 (patch-src_bootstrap_src_core_build__steps_install.rs) = cc6558df42c9c9ac28fdb2ff180bdaa7f22ce816
-SHA1 (patch-src_bootstrap_src_core_builder.rs) = 6d76366201097adc56e494fa05ebbc1696bb2d98
+SHA1 (patch-src_bootstrap_src_core_builder.rs) = 071c9a5151fb6dd5a8eabb7d5973d3e2a403062b
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/options.mk b/lang/rust/options.mk
index 2fe51498b3f8..25d105dd9010 100644
--- a/lang/rust/options.mk
+++ b/lang/rust/options.mk
@@ -14,8 +14,12 @@ PKG_SUGGESTED_OPTIONS+= rust-internal-llvm
. endif
.endif
-# If cross-building, always use the internal LLVM
-.if !empty(TARGET)
+# If cross-building, always use the internal LLVM so we don't have to
+# deal with llvm-config for the cross-built system.
+#
+# XXX We ought to be able to use llvm-config here but it'll take some
+# work to make that happen, since llvm-config is a native executable.
+.if !empty(TARGET) || ${USE_CROSS_COMPILE:tl} == "yes"
PKG_SUGGESTED_OPTIONS+= rust-internal-llvm
.endif
diff --git a/lang/rust/patches/patch-compiler_rustc__target_src_spec_base_netbsd.rs b/lang/rust/patches/patch-compiler_rustc__target_src_spec_base_netbsd.rs
index a5bdec2e50e0..7cbe33eb4c45 100644
--- a/lang/rust/patches/patch-compiler_rustc__target_src_spec_base_netbsd.rs
+++ b/lang/rust/patches/patch-compiler_rustc__target_src_spec_base_netbsd.rs
@@ -14,7 +14,7 @@ search the directory containing the symlinks to -latomic.
+ &[
+ // For the benefit of powerpc, when libatomic-links is installed,
+ "-Wl,-R@PREFIX@/lib/libatomic",
-+ "-Wl,-L@PREFIX@/lib/libatomic",
++ "-Wl,-L=@PREFIX@/lib/libatomic",
+ ];
+ let pre_link_args = TargetOptions::link_args(
+ LinkerFlavor::Gnu(Cc::Yes, Lld::No),
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 6142279cb0c8..3559cae00d44 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.6 2025/02/02 13:34:47 he 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@/{libdir}"))
} 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
Home |
Main Index |
Thread Index |
Old Index