nushell: Fix build for riscv32 musl

Add patches to the vendored crates:

- libc: Add the syscall numbers 443 to 450, which riscv32 musl lacks
  and rustix needs for SYS_futex_waitv.
- fff-search, rmcp, nu-command and nu-dap: Use the 64-bit atomics from
  portable-atomic on targets without 64-bit atomics, where std does not
  provide them, and record the dependency in Cargo.lock since the build
  uses --frozen.

AI-Generated: Uses Claude Code
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
Khem Raj committed 2026-10-22 09:58:55 -07:00
1 parent 53c933fbf6
commit 685776c556
7 files changed
+444

No files matched your search

@@ -0,0 +1,39 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Thu, 22 Oct 2026 10:00:00 -0700
Subject: [PATCH] musl/riscv32: Add syscall numbers 443 to 450
The riscv32 musl syscall list stops at SYS_mount_setattr (442), while
the other musl targets and riscv32 glibc also define the newer generic
syscalls. rustix uses SYS_futex_waitv, so it fails to build for
riscv32 musl:
error[E0425]: cannot find value `SYS_futex_waitv` in this scope
--> rustix-1.1.4/src/backend/libc/thread/syscalls.rs:678:15
Add quotactl_fd, landlock_*, memfd_secret, process_mrelease,
futex_waitv and set_mempolicy_home_node, which use the asm-generic
numbers on riscv32 as well.
Upstream-Status: Pending
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
src/unix/linux_like/linux/musl/b32/riscv32/mod.rs | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs
+++ b/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs
@@ -623,6 +623,14 @@
pub const SYS_process_madvise: c_long = 440;
pub const SYS_epoll_pwait2: c_long = 441;
pub const SYS_mount_setattr: c_long = 442;
+pub const SYS_quotactl_fd: c_long = 443;
+pub const SYS_landlock_create_ruleset: c_long = 444;
+pub const SYS_landlock_add_rule: c_long = 445;
+pub const SYS_landlock_restrict_self: c_long = 446;
+pub const SYS_memfd_secret: c_long = 447;
+pub const SYS_process_mrelease: c_long = 448;
+pub const SYS_futex_waitv: c_long = 449;
+pub const SYS_set_mempolicy_home_node: c_long = 450;
// Plain syscalls aliased to their time64 variants
pub const SYS_clock_gettime: c_long = SYS_clock_gettime64;
@@ -0,0 +1,108 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Thu, 22 Oct 2026 11:00:00 -0700
Subject: [PATCH] Use portable-atomic for AtomicU64 on targets without 64-bit
atomics
std only provides AtomicU64 on targets with 64-bit atomics, so
fff-search fails to build for e.g. riscv32:
error[E0432]: unresolved import `std::sync::atomic::AtomicU64`
--> src/rescan_throttle.rs:1:25
|
1 | use std::sync::atomic::{AtomicU64, Ordering};
| ^^^^^^^^^ no `AtomicU64` in `sync::atomic`
The counters, timestamps and ids kept in AtomicU64 need 64 bits, so
use the AtomicU64 from portable-atomic on such targets instead,
through a crate-level import, and keep std's on all other targets.
Upstream-Status: Pending
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
Cargo.toml | 5 +++++
src/lib.rs | 6 ++++++
src/log.rs | 3 ++-
src/rescan_throttle.rs | 3 ++-
src/types.rs | 4 +++-
src/watcher/watch.rs | 3 ++-
6 files changed, 20 insertions(+), 4 deletions(-)
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -320,6 +320,11 @@
version = "0.3"
features = ["env-filter"]
+[target."cfg(not(target_has_atomic = \"64\"))".dependencies.portable-atomic]
+version = "1.13.1"
+features = ["fallback"]
+default-features = false
+
[target."cfg(unix)".dependencies.signal-hook-registry]
version = "1.4"
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -103,6 +103,12 @@
Enable one, e.g. `--features ripgrep` or `--features zlob`."
);
+// std only provides AtomicU64 on targets with 64-bit atomics.
+#[cfg(target_has_atomic = "64")]
+pub(crate) use std::sync::atomic::AtomicU64;
+#[cfg(not(target_has_atomic = "64"))]
+pub(crate) use portable_atomic::AtomicU64;
+
/// Primary entry points with thread-safe [`SharedFilePicker`](shared::FilePicker) instance
pub mod shared;
pub use shared::*;
--- a/src/log.rs
+++ b/src/log.rs
@@ -135,7 +135,8 @@
const DEFAULT_RETAIN_RUNS: usize = 20;
pub fn generate_trace_id() -> String {
- use std::sync::atomic::{AtomicU64, Ordering};
+ use crate::AtomicU64;
+ use std::sync::atomic::Ordering;
static TRACE_COUNTER: AtomicU64 = AtomicU64::new(0);
let nanos = std::time::SystemTime::now()
--- a/src/rescan_throttle.rs
+++ b/src/rescan_throttle.rs
@@ -1,6 +1,7 @@
-use std::sync::atomic::{AtomicU64, Ordering};
+use std::sync::atomic::Ordering;
use std::time::Instant;
+use crate::AtomicU64;
use crate::constants::{
LARGE_INDEX_FILE_COUNT, RESCAN_MIN_INTERVAL, RESCAN_MIN_INTERVAL_LARGE_INDEX,
};
--- a/src/types.rs
+++ b/src/types.rs
@@ -2,7 +2,9 @@
use std::path::{Path, PathBuf};
#[cfg(not(target_os = "windows"))]
use std::sync::atomic::AtomicPtr;
-use std::sync::atomic::{AtomicI32, AtomicU8, AtomicU64, AtomicUsize, Ordering};
+use std::sync::atomic::{AtomicI32, AtomicU8, AtomicUsize, Ordering};
+
+use crate::AtomicU64;
#[cfg(not(target_os = "windows"))]
use crate::constants::{FRESH_MMAP_THRESHOLD, MMAP_THRESHOLD};
--- a/src/watcher/watch.rs
+++ b/src/watcher/watch.rs
@@ -1,9 +1,10 @@
use crate::error::Error;
use crate::index::constraints::{GlobPattern, compile_one, glob_matches_into};
+use crate::AtomicU64;
use parking_lot::Mutex;
use std::path::{Path, PathBuf};
use std::sync::Arc;
-use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
+use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc;
use tracing::{debug, error};
@@ -0,0 +1,97 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Thu, 22 Oct 2026 11:30:00 -0700
Subject: [PATCH] Use portable-atomic for AtomicU64 on targets without 64-bit
atomics
std only provides AtomicU64 on targets with 64-bit atomics, so rmcp
fails to build for e.g. riscv32:
error[E0432]: unresolved import `std::sync::atomic::AtomicU64`
--> src/service.rs:455:17
|
455 | sync::{Arc, atomic::AtomicU64},
| ^^^^^^^^---------
| |
| no `AtomicU64` in `sync::atomic`
The request id and control generation counters are 64-bit, so use the
AtomicU64 from portable-atomic on such targets instead, through a
crate-level import, and keep std's on all other targets.
Upstream-Status: Pending
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
Cargo.toml | 5 +++++
src/lib.rs | 8 ++++++++
src/service.rs | 4 +++-
src/transport/worker.rs | 3 ++-
4 files changed, 18 insertions(+), 2 deletions(-)
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -930,6 +930,11 @@
[dev-dependencies.url]
version = "2.4"
+[target.'cfg(not(target_has_atomic = "64"))'.dependencies.portable-atomic]
+version = "1.13.1"
+features = ["fallback"]
+default-features = false
+
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies.chrono]
version = "0.4.38"
features = [
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,14 @@
#![cfg_attr(docsrs, allow(unused_attributes))]
#![doc = include_str!("../README.md")]
+// std only provides AtomicU64 on targets with 64-bit atomics.
+#[cfg(target_has_atomic = "64")]
+#[allow(unused_imports)]
+pub(crate) use std::sync::atomic::AtomicU64;
+#[cfg(not(target_has_atomic = "64"))]
+#[allow(unused_imports)]
+pub(crate) use portable_atomic::AtomicU64;
+
mod error;
pub use error::{ErrorData, RmcpError};
--- a/src/service.rs
+++ b/src/service.rs
@@ -452,12 +452,14 @@
use std::{
collections::{HashMap, VecDeque},
ops::Deref,
- sync::{Arc, atomic::AtomicU64},
+ sync::Arc,
time::Duration,
};
use tokio::sync::mpsc;
+use crate::AtomicU64;
+
pub trait RequestIdProvider: Send + Sync + 'static {
fn next_request_id(&self) -> RequestId;
}
--- a/src/transport/worker.rs
+++ b/src/transport/worker.rs
@@ -3,7 +3,7 @@
collections::HashMap,
sync::{
Arc, Mutex, PoisonError, Weak,
- atomic::{AtomicU64, Ordering},
+ atomic::Ordering,
},
time::Duration,
};
@@ -12,6 +12,7 @@
use tracing::{Instrument, Level};
use super::{IntoTransport, Transport};
+use crate::AtomicU64;
use crate::{
model::{CancelledNotification, JsonRpcMessage, RequestId},
service::{RxJsonRpcMessage, ServiceRole, TxJsonRpcMessage},
@@ -0,0 +1,66 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Thu, 22 Oct 2026 12:00:00 -0700
Subject: [PATCH] nu-command: Use portable-atomic for AtomicU64 on targets
without 64-bit atomics
std only provides AtomicU64 on targets with 64-bit atomics, so
nu-command fails to build for e.g. riscv32:
error[E0432]: unresolved import `std::sync::atomic::AtomicU64`
--> src/filesystem/idx/state.rs:18:39
The scan duration is kept in nanoseconds and needs 64 bits, so use the
AtomicU64 from portable-atomic on such targets instead, through a
crate-level import, and keep std's on all other targets.
Upstream-Status: Pending
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
Cargo.toml | 5 +++++
src/filesystem/idx/state.rs | 3 ++-
src/lib.rs | 7 +++++++
3 files changed, 14 insertions(+), 1 deletion(-)
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -596,6 +596,11 @@
"mode",
]
+[target."cfg(not(target_has_atomic = \"64\"))".dependencies.portable-atomic]
+version = "1.13.1"
+features = ["fallback"]
+default-features = false
+
[target."cfg(unix)".dependencies.nix]
version = "0.31.3"
features = [
--- a/src/filesystem/idx/state.rs
+++ b/src/filesystem/idx/state.rs
@@ -13,9 +13,10 @@
use nu_protocol::shell_error::generic::GenericError;
use nu_protocol::{ListStream, PipelineMetadata, Signals};
use nu_utils::time::Instant;
+use crate::AtomicU64;
use pathdiff::diff_paths;
use std::path::{Path, PathBuf};
-use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
+use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Receiver, RecvTimeoutError, Sender, channel};
use std::sync::{Arc, Mutex, OnceLock};
use std::time::Duration;
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,12 @@
#![cfg_attr(not(feature = "os"), allow(unused))]
#![doc = include_str!("../README.md")]
+
+// std only provides AtomicU64 on targets with 64-bit atomics.
+#[cfg(target_has_atomic = "64")]
+use std::sync::atomic::AtomicU64;
+#[cfg(not(target_has_atomic = "64"))]
+use portable_atomic::AtomicU64;
+
mod bytes;
mod charting;
mod conversions;
@@ -0,0 +1,77 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Thu, 22 Oct 2026 12:00:00 -0700
Subject: [PATCH] nu-dap: Use portable-atomic for 64-bit atomics on targets
without them
std only provides AtomicI64 and AtomicU64 on targets with 64-bit
atomics, so nu-dap fails to build for e.g. riscv32:
error[E0425]: cannot find type `AtomicU64` in module `std::sync::atomic`
--> src/state.rs:428:37
The protocol sequence number and the UI request ids are 64-bit, so use
the atomics from portable-atomic on such targets instead, through
crate-level imports, and keep std's on all other targets.
Upstream-Status: Pending
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
Cargo.toml | 5 +++++
src/dap/protocol.rs | 4 +++-
src/lib.rs | 6 ++++++
src/state.rs | 2 +-
4 files changed, 15 insertions(+), 2 deletions(-)
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -101,6 +101,11 @@
[dev-dependencies.typetag]
version = "0.2"
+[target."cfg(not(target_has_atomic = \"64\"))".dependencies.portable-atomic]
+version = "1.13.1"
+features = ["fallback"]
+default-features = false
+
[target."cfg(unix)".dependencies.libc]
version = "0.2.185"
--- a/src/dap/protocol.rs
+++ b/src/dap/protocol.rs
@@ -9,7 +9,9 @@
use serde_json::Value as Json;
use std::io::{BufRead, Write};
use std::sync::Arc;
-use std::sync::atomic::{AtomicI64, Ordering};
+use std::sync::atomic::Ordering;
+
+use crate::AtomicI64;
#[derive(Debug, Deserialize)]
pub struct Request {
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -35,6 +35,12 @@
// Tests may `unwrap` (matches nushell); production code stays `unwrap`-free.
#![cfg_attr(test, allow(clippy::unwrap_used))]
+// std only provides 64-bit atomics on targets that support them.
+#[cfg(target_has_atomic = "64")]
+use std::sync::atomic::{AtomicI64, AtomicU64};
+#[cfg(not(target_has_atomic = "64"))]
+use portable_atomic::{AtomicI64, AtomicU64};
+
mod debugger;
mod engine;
mod eval_scratch;
--- a/src/state.rs
+++ b/src/state.rs
@@ -425,7 +425,7 @@
pub(crate) struct UiBridge {
pub replies: Mutex<HashMap<u64, UiReply>>,
pub cv: Condvar,
- pub next_id: std::sync::atomic::AtomicU64,
+ pub next_id: crate::AtomicU64,
}
/// How the client numbers lines and columns, from the `initialize` request.
@@ -0,0 +1,49 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Thu, 22 Oct 2026 12:00:00 -0700
Subject: [PATCH] Cargo.lock: Add portable-atomic to patched crates
fff-search, rmcp, nu-command and nu-dap are patched to depend on
portable-atomic on targets without 64-bit atomics. The build uses
--frozen, so record the dependencies in the lock file. portable-atomic
1.13.1 is already locked.
Upstream-Status: Inappropriate [OE-specific, follows the crate patches]
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
Cargo.lock | 4 ++++
1 file changed, 4 insertions(+)
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1629,6 +1629,7 @@
"notify 9.0.0-rc.4",
"parking_lot",
"pathdiff",
+ "portable-atomic",
"rayon",
"regex",
"regex-syntax",
@@ -3732,6 +3733,7 @@
"os_pipe",
"pathdiff",
"percent-encoding",
+ "portable-atomic",
"print-positions",
"procfs",
"pure-rust-locales",
@@ -3812,6 +3814,7 @@
"nu-protocol",
"nu-utils",
"parking_lot",
+ "portable-atomic",
"serde",
"serde_json",
"windows-sys 0.61.2",
@@ -5512,6 +5515,7 @@
"indexmap",
"pastey",
"pin-project-lite",
+ "portable-atomic",
"rand 0.10.2",
"rmcp-macros",
"schemars",
@@ -13,6 +13,14 @@ LIC_FILES_CHKSUM = " \
DEPENDS = "libgit2 sqlite3"
SRC_URI = "crate://crates.io/nu/${PV};name=nu"
SRC_URI += " \
file://0001-musl-riscv32-Add-syscall-numbers-443-to-450.patch;patchdir=${CARGO_VENDORING_DIRECTORY}/libc-0.2.186 \
file://0002-Use-portable-atomic-for-AtomicU64-on-targets-without.patch;patchdir=${CARGO_VENDORING_DIRECTORY}/fff-search-0.11.0 \
file://0003-Use-portable-atomic-for-AtomicU64-on-targets-without.patch;patchdir=${CARGO_VENDORING_DIRECTORY}/rmcp-3.4.0 \
file://0004-nu-command-Use-portable-atomic-for-AtomicU64-on-targ.patch;patchdir=${CARGO_VENDORING_DIRECTORY}/nu-command-0.116.1 \
file://0005-nu-dap-Use-portable-atomic-for-64-bit-atomics-on-tar.patch;patchdir=${CARGO_VENDORING_DIRECTORY}/nu-dap-0.116.1 \
file://0006-Cargo.lock-Add-portable-atomic-to-patched-crates.patch \
"
SRC_URI[nu.sha256sum] = "62e21f2d6a14430ae2701a4e6f11be42d40a11204c204bef32a8b9879f79e767"
S = "${CARGO_VENDORING_DIRECTORY}/nu-${PV}"