From 2cb02aa1024f7b912830b17531ba779dff7d1e80 Mon Sep 17 00:00:00 2001 From: peoplemiau1 Date: Thu, 28 May 2026 22:48:51 +0300 Subject: [PATCH] Add full FreeBSD, OpenBSD, NetBSD, and DragonflyBSD target support --- src/cli/build.rs | 30 ++++++++++--- src/cli/clean.rs | 13 +++++- src/cli/fmt.rs | 2 +- src/cli/run.rs | 21 ++++++--- src/platform/bsd.rs | 88 ++++++++++++++++++++++++++++++++++++++ src/platform/mod.rs | 102 +++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 239 insertions(+), 17 deletions(-) create mode 100644 src/platform/bsd.rs diff --git a/src/cli/build.rs b/src/cli/build.rs index f16e511..7a751ff 100644 --- a/src/cli/build.rs +++ b/src/cli/build.rs @@ -80,15 +80,26 @@ pub fn build(args: &[String]) -> i32 { } if flags.target.is_none() { let default_target = if cfg!(target_os = "linux") { - "x86_64-unknown-linux-gnu" + format!("{}-unknown-linux-gnu", std::env::consts::ARCH) } else if cfg!(target_os = "macos") { - "x86_64-apple-darwin" + "x86_64-apple-darwin".to_string() } else if cfg!(target_os = "windows") { - "x86_64-pc-windows-msvc" + "x86_64-pc-windows-msvc".to_string() + } else if cfg!(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )) { + format!( + "{}-unknown-{}", + std::env::consts::ARCH, + std::env::consts::OS + ) } else { - "unknown" + "unknown".to_string() }; - flags.target = Some(default_target.to_string()); + flags.target = Some(default_target); } if flags.clean { let mut clean_args = Vec::new(); @@ -390,6 +401,15 @@ fn ensure_target_dirs( let default_dir = if cfg!(target_os = "linux") { let arch = std::env::consts::ARCH; format!("{arch}-unknown-linux-gnu/{profile}") + } else if cfg!(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )) { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + format!("{arch}-unknown-{os}/{profile}") } else { profile.to_string() }; diff --git a/src/cli/clean.rs b/src/cli/clean.rs index 521eb65..73e82bc 100644 --- a/src/cli/clean.rs +++ b/src/cli/clean.rs @@ -120,11 +120,22 @@ fn clean_from_root(root: &Path, flags: &CleanFlags) -> Result<(), String> { }) .or_else(|| { Some(if cfg!(target_os = "linux") { - "x86_64-unknown-linux-gnu".to_string() + format!("{}-unknown-linux-gnu", std::env::consts::ARCH) } else if cfg!(target_os = "macos") { "x86_64-apple-darwin".to_string() } else if cfg!(target_os = "windows") { "x86_64-pc-windows-msvc".to_string() + } else if cfg!(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )) { + format!( + "{}-unknown-{}", + std::env::consts::ARCH, + std::env::consts::OS + ) } else { "unknown".to_string() }) diff --git a/src/cli/fmt.rs b/src/cli/fmt.rs index 1c1ef64..c016f1b 100644 --- a/src/cli/fmt.rs +++ b/src/cli/fmt.rs @@ -1,5 +1,5 @@ use crate::utils::log::error; -use crate::utils::text::{colored, BOLD_GREEN}; +use crate::utils::text::{BOLD_GREEN, colored}; use glob::glob; use std::process::Command; diff --git a/src/cli/run.rs b/src/cli/run.rs index a7ca498..e1b09f4 100644 --- a/src/cli/run.rs +++ b/src/cli/run.rs @@ -160,15 +160,26 @@ fn run_project( let mut target = flags.target.clone(); if target.is_none() { let default_target = if cfg!(target_os = "linux") { - "x86_64-unknown-linux-gnu" + format!("{}-unknown-linux-gnu", std::env::consts::ARCH) } else if cfg!(target_os = "macos") { - "x86_64-apple-darwin" + "x86_64-apple-darwin".to_string() } else if cfg!(target_os = "windows") { - "x86_64-pc-windows-msvc" + "x86_64-pc-windows-msvc".to_string() + } else if cfg!(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )) { + format!( + "{}-unknown-{}", + std::env::consts::ARCH, + std::env::consts::OS + ) } else { - "unknown" + "unknown".to_string() }; - target = Some(default_target.to_string()); + target = Some(default_target); } let build_kind = config diff --git a/src/platform/bsd.rs b/src/platform/bsd.rs new file mode 100644 index 0000000..42f3c2d --- /dev/null +++ b/src/platform/bsd.rs @@ -0,0 +1,88 @@ +pub fn bin_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { + match target_dir { + Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name), + None => { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + let target = format!("{arch}-unknown-{os}"); + format!("./target/{target}/{profile}/{name}") + } + } +} + +pub fn lib_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { + match target_dir { + Some(dir) => format!("{}/lib{}.a", dir.trim_end_matches('/'), name), + None => { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + let target = format!("{arch}-unknown-{os}"); + format!("./target/{target}/{profile}/lib{name}.a") + } + } +} + +pub fn elf_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { + match target_dir { + Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name), + None => { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + let target = format!("{arch}-unknown-{os}"); + format!("./target/{target}/{profile}/{name}") + } + } +} + +pub fn efi_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { + match target_dir { + Some(dir) => format!("{}/{}.efi", dir.trim_end_matches('/'), name), + None => { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + let target = format!("{arch}-unknown-{os}"); + format!("./target/{target}/{profile}/{name}.efi") + } + } +} + +pub fn shared_lib_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { + match target_dir { + Some(dir) => format!("{}/lib{}.so", dir.trim_end_matches('/'), name), + None => { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + let target = format!("{arch}-unknown-{os}"); + format!("./target/{target}/{profile}/lib{name}.so") + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn bin_path_default() { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + let expected = format!("./target/{arch}-unknown-{os}/debug/hello"); + assert_eq!(bin_path("debug", "hello", None), expected); + } + + #[test] + fn lib_path_default() { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + let expected = format!("./target/{arch}-unknown-{os}/debug/libmylib.a"); + assert_eq!(lib_path("debug", "mylib", None), expected); + } + + #[test] + fn shared_lib_path_default() { + let arch = std::env::consts::ARCH; + let os = std::env::consts::OS; + let expected = format!("./target/{arch}-unknown-{os}/debug/libmylib.so"); + assert_eq!(shared_lib_path("debug", "mylib", None), expected); + } +} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index bde52b5..5465db5 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -15,6 +15,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#[cfg(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" +))] +pub mod bsd; #[cfg(target_os = "linux")] pub mod linux; #[cfg(target_os = "macos")] @@ -35,7 +42,24 @@ pub fn bin_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { { return windows::bin_path(profile, name, target_dir); } - #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] + #[cfg(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + ))] + { + return bsd::bin_path(profile, name, target_dir); + } + #[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "windows", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )))] { match target_dir { Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name), @@ -57,7 +81,24 @@ pub fn elf_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { { return windows::elf_path(profile, name, target_dir); } - #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] + #[cfg(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + ))] + { + return bsd::elf_path(profile, name, target_dir); + } + #[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "windows", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )))] { match target_dir { Some(dir) => format!("{}/{}", dir.trim_end_matches('/'), name), @@ -79,7 +120,24 @@ pub fn efi_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { { return windows::efi_path(profile, name, target_dir); } - #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] + #[cfg(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + ))] + { + return bsd::efi_path(profile, name, target_dir); + } + #[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "windows", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )))] { match target_dir { Some(dir) => format!("{}/{}.efi", dir.trim_end_matches('/'), name), @@ -101,7 +159,24 @@ pub fn lib_path(profile: &str, name: &str, target_dir: Option<&str>) -> String { { return windows::lib_path(profile, name, target_dir); } - #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] + #[cfg(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + ))] + { + return bsd::lib_path(profile, name, target_dir); + } + #[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "windows", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )))] { match target_dir { Some(dir) => format!("{}/lib{}.a", dir.trim_end_matches('/'), name), @@ -123,7 +198,24 @@ pub fn shared_lib_path(profile: &str, name: &str, target_dir: Option<&str>) -> S { return windows::shared_lib_path(profile, name, target_dir); } - #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] + #[cfg(any( + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + ))] + { + return bsd::shared_lib_path(profile, name, target_dir); + } + #[cfg(not(any( + target_os = "linux", + target_os = "macos", + target_os = "windows", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly" + )))] { match target_dir { Some(dir) => format!("{}/lib{}.so", dir.trim_end_matches('/'), name),