Port std library to RTEMS

This commit is contained in:
Jan Sommer 2023-08-21 19:03:17 +02:00
parent 6199b69c53
commit 6f435cb07f
22 changed files with 488 additions and 14 deletions

View File

@ -43,6 +43,8 @@ check-cfg = [
'cfg(bootstrap)',
'cfg(no_fp_fmt_parse)',
'cfg(stdarch_intel_sde)',
# #[cfg(bootstrap)] rtems
'cfg(target_os, values("rtems"))',
# core use #[path] imports to portable-simd `core_simd` crate
# and to stdarch `core_arch` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg

View File

@ -110,7 +110,7 @@ mod c_char_definition {
all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")),
all(target_os = "l4re", target_arch = "x86_64"),
all(
any(target_os = "freebsd", target_os = "openbsd"),
any(target_os = "freebsd", target_os = "openbsd", target_os = "rtems"),
any(
target_arch = "aarch64",
target_arch = "arm",

View File

@ -20,3 +20,10 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
libc = { version = "0.2", default-features = false }
[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [
# #[cfg(bootstrap)] rtems
'cfg(target_os, values("rtems"))',
]

View File

@ -48,7 +48,7 @@
target_os = "psp",
target_os = "xous",
target_os = "solid_asp3",
all(target_family = "unix", not(target_os = "espidf")),
all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems"))),
all(target_vendor = "fortanix", target_env = "sgx"),
target_family = "wasm",
))] {

View File

@ -146,4 +146,6 @@ check-cfg = [
# and to the `backtrace` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg
'cfg(feature, values(any()))',
# #[cfg(bootstrap)] rtems
'cfg(target_os, values("rtems"))',
]

View File

@ -53,6 +53,7 @@ fn main() {
|| target_os == "uefi"
|| target_os == "teeos"
|| target_os == "zkvm"
|| target_os == "rtems"
// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()

View File

@ -143,6 +143,8 @@ pub mod windows {}
pub mod openbsd;
#[cfg(target_os = "redox")]
pub mod redox;
#[cfg(target_os = "rtems")]
pub mod rtems;
#[cfg(target_os = "solaris")]
pub mod solaris;
#[cfg(target_os = "solid_asp3")]

View File

@ -0,0 +1,374 @@
#![stable(feature = "metadata_ext", since = "1.1.0")]
use crate::fs::Metadata;
use crate::sys_common::AsInner;
/// OS-specific extensions to [`fs::Metadata`].
///
/// [`fs::Metadata`]: crate::fs::Metadata
#[stable(feature = "metadata_ext", since = "1.1.0")]
pub trait MetadataExt {
/// Returns the device ID on which this file resides.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_dev());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_dev(&self) -> u64;
/// Returns the inode number.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_ino());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ino(&self) -> u64;
/// Returns the file type and mode.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_mode());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mode(&self) -> u32;
/// Returns the number of hard links to file.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_nlink());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_nlink(&self) -> u64;
/// Returns the user ID of the file owner.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_uid());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_uid(&self) -> u32;
/// Returns the group ID of the file owner.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_gid());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_gid(&self) -> u32;
/// Returns the device ID that this file represents. Only relevant for special file.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_rdev());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_rdev(&self) -> u64;
/// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
///
/// The size of a symbolic link is the length of the pathname it contains,
/// without a terminating null byte.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_size());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_size(&self) -> u64;
/// Returns the last access time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_atime());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime(&self) -> i64;
/// Returns the last access time of the file, in nanoseconds since [`st_atime`].
///
/// [`st_atime`]: Self::st_atime
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_atime_nsec());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime_nsec(&self) -> i64;
/// Returns the last modification time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_mtime());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime(&self) -> i64;
/// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
///
/// [`st_mtime`]: Self::st_mtime
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_mtime_nsec());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime_nsec(&self) -> i64;
/// Returns the last status change time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_ctime());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime(&self) -> i64;
/// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
///
/// [`st_ctime`]: Self::st_ctime
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_ctime_nsec());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime_nsec(&self) -> i64;
/// Returns the "preferred" block size for efficient filesystem I/O.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_blksize());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blksize(&self) -> u64;
/// Returns the number of blocks allocated to the file, 512-byte units.
///
/// # Examples
///
/// ```no_run
/// use std::fs;
/// use std::io;
/// use std::os::rtems::fs::MetadataExt;
///
/// fn main() -> io::Result<()> {
/// let meta = fs::metadata("some_file")?;
/// println!("{}", meta.st_blocks());
/// Ok(())
/// }
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blocks(&self) -> u64;
}
#[stable(feature = "metadata_ext", since = "1.1.0")]
impl MetadataExt for Metadata {
fn st_dev(&self) -> u64 {
self.as_inner().as_inner().st_dev as u64
}
fn st_ino(&self) -> u64 {
self.as_inner().as_inner().st_ino as u64
}
fn st_mode(&self) -> u32 {
self.as_inner().as_inner().st_mode as u32
}
fn st_nlink(&self) -> u64 {
self.as_inner().as_inner().st_nlink as u64
}
fn st_uid(&self) -> u32 {
self.as_inner().as_inner().st_uid as u32
}
fn st_gid(&self) -> u32 {
self.as_inner().as_inner().st_gid as u32
}
fn st_rdev(&self) -> u64 {
self.as_inner().as_inner().st_rdev as u64
}
fn st_size(&self) -> u64 {
self.as_inner().as_inner().st_size as u64
}
fn st_atime(&self) -> i64 {
self.as_inner().as_inner().st_atime as i64
}
fn st_atime_nsec(&self) -> i64 {
0
}
fn st_mtime(&self) -> i64 {
self.as_inner().as_inner().st_mtime as i64
}
fn st_mtime_nsec(&self) -> i64 {
0
}
fn st_ctime(&self) -> i64 {
self.as_inner().as_inner().st_ctime as i64
}
fn st_ctime_nsec(&self) -> i64 {
0
}
fn st_blksize(&self) -> u64 {
self.as_inner().as_inner().st_blksize as u64
}
fn st_blocks(&self) -> u64 {
self.as_inner().as_inner().st_blocks as u64
}
}

View File

@ -0,0 +1,4 @@
#![stable(feature = "raw_ext", since = "1.1.0")]
#![forbid(unsafe_op_in_unsafe_fn)]
pub mod fs;
pub(crate) mod raw;

View File

@ -0,0 +1,33 @@
//! rtems raw type definitions
#![stable(feature = "raw_ext", since = "1.1.0")]
#![deprecated(
since = "1.8.0",
note = "these type aliases are no longer supported by \
the standard library, the `libc` crate on \
crates.io should be used instead for the correct \
definitions"
)]
#![allow(deprecated)]
#[stable(feature = "pthread_t", since = "1.8.0")]
pub type pthread_t = libc::pthread_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = libc::blkcnt_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = libc::blksize_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type dev_t = libc::dev_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = libc::ino_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type mode_t = libc::mode_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = libc::nlink_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = libc::off_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = libc::time_t;

View File

@ -73,6 +73,8 @@ mod platform {
pub use crate::os::openbsd::*;
#[cfg(target_os = "redox")]
pub use crate::os::redox::*;
#[cfg(target_os = "rtems")]
pub use crate::os::rtems::*;
#[cfg(target_os = "solaris")]
pub use crate::os::solaris::*;
#[cfg(target_os = "vita")]

View File

@ -112,6 +112,7 @@ fn next_back(&mut self) -> Option<OsString> {
target_os = "aix",
target_os = "nto",
target_os = "hurd",
target_os = "rtems",
))]
mod imp {
use crate::ffi::c_char;

View File

@ -240,6 +240,17 @@ pub mod os {
pub const EXE_EXTENSION: &str = "";
}
#[cfg(target_os = "rtems")]
pub mod os {
pub const FAMILY: &str = "unix";
pub const OS: &str = "rtems";
pub const DLL_PREFIX: &str = "lib";
pub const DLL_SUFFIX: &str = ".so";
pub const DLL_EXTENSION: &str = "so";
pub const EXE_SUFFIX: &str = "";
pub const EXE_EXTENSION: &str = "";
}
#[cfg(target_os = "vxworks")]
pub mod os {
pub const FAMILY: &str = "unix";

View File

@ -478,6 +478,7 @@ impl FileAttr {
target_os = "horizon",
target_os = "vita",
target_os = "hurd",
target_os = "rtems",
)))]
pub fn modified(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")]
@ -490,7 +491,12 @@ pub fn modified(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_mtime as i64, self.stat.st_mtime_nsec as i64)
}
#[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))]
#[cfg(any(
target_os = "vxworks",
target_os = "espidf",
target_os = "vita",
target_os = "rtems",
))]
pub fn modified(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_mtime as i64, 0)
}
@ -506,6 +512,7 @@ pub fn modified(&self) -> io::Result<SystemTime> {
target_os = "horizon",
target_os = "vita",
target_os = "hurd",
target_os = "rtems",
)))]
pub fn accessed(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")]
@ -518,7 +525,12 @@ pub fn accessed(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_atime as i64, self.stat.st_atime_nsec as i64)
}
#[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))]
#[cfg(any(
target_os = "vxworks",
target_os = "espidf",
target_os = "vita",
target_os = "rtems"
))]
pub fn accessed(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_atime as i64, 0)
}
@ -853,6 +865,7 @@ fn drop(&mut self) {
target_os = "fuchsia",
target_os = "horizon",
target_os = "vxworks",
target_os = "rtems",
)))]
{
let fd = unsafe { libc::dirfd(self.0) };
@ -970,6 +983,7 @@ pub fn file_type(&self) -> io::Result<FileType> {
target_os = "aix",
target_os = "nto",
target_os = "hurd",
target_os = "rtems",
target_vendor = "apple",
))]
pub fn ino(&self) -> u64 {

View File

@ -79,6 +79,7 @@ unsafe fn sanitize_standard_fds() {
target_os = "l4re",
target_os = "horizon",
target_os = "vita",
target_os = "rtems",
// The poll on Darwin doesn't set POLLNVAL for closed fds.
target_vendor = "apple",
)))]

View File

@ -31,7 +31,7 @@
}
extern "C" {
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))]
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
#[cfg_attr(
any(
target_os = "linux",
@ -61,13 +61,14 @@
}
/// Returns the platform-specific value of errno
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks")))]
#[cfg(not(any(target_os = "dragonfly", target_os = "vxworks", target_os = "rtems")))]
pub fn errno() -> i32 {
unsafe { (*errno_location()) as i32 }
}
/// Sets the platform-specific value of errno
#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks")))] // needed for readdir and syscall!
// needed for readdir and syscall!
#[cfg(all(not(target_os = "dragonfly"), not(target_os = "vxworks"), not(target_os = "rtems")))]
#[allow(dead_code)] // but not all target cfgs actually end up using it
pub fn set_errno(e: i32) {
unsafe { *errno_location() = e as c_int }
@ -78,6 +79,16 @@ pub fn errno() -> i32 {
unsafe { libc::errnoGet() }
}
#[cfg(target_os = "rtems")]
pub fn errno() -> i32 {
extern "C" {
#[thread_local]
static _tls_errno: c_int;
}
unsafe { _tls_errno as i32 }
}
#[cfg(target_os = "dragonfly")]
pub fn errno() -> i32 {
extern "C" {
@ -472,7 +483,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
}
}
#[cfg(target_os = "redox")]
#[cfg(any(target_os = "redox", target_os = "rtems"))]
pub fn current_exe() -> io::Result<PathBuf> {
crate::fs::read_to_string("sys:exe").map(PathBuf::from)
}

View File

@ -1089,13 +1089,13 @@ fn signal_string(signal: i32) -> &'static str {
libc::SIGURG => " (SIGURG)",
#[cfg(not(target_os = "l4re"))]
libc::SIGXCPU => " (SIGXCPU)",
#[cfg(not(target_os = "l4re"))]
#[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
libc::SIGXFSZ => " (SIGXFSZ)",
#[cfg(not(target_os = "l4re"))]
#[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
libc::SIGVTALRM => " (SIGVTALRM)",
#[cfg(not(target_os = "l4re"))]
libc::SIGPROF => " (SIGPROF)",
#[cfg(not(target_os = "l4re"))]
#[cfg(not(any(target_os = "l4re", target_os = "rtems")))]
libc::SIGWINCH => " (SIGWINCH)",
#[cfg(not(any(target_os = "haiku", target_os = "l4re")))]
libc::SIGIO => " (SIGIO)",

View File

@ -31,7 +31,7 @@ fn rust_eh_personality() {
target_os = "psp",
target_os = "xous",
target_os = "solid_asp3",
all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re")),
all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems")),
all(target_vendor = "fortanix", target_env = "sgx"),
))] {
mod gcc;

View File

@ -34,3 +34,10 @@ llvm-libunwind = []
# If crt-static is enabled, static link to `libunwind.a` provided by system
# If crt-static is disabled, dynamic link to `libunwind.so` provided by system
system-llvm-libunwind = []
[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [
# #[cfg(bootstrap)] rtems
'cfg(target_os, values("rtems"))',
]

View File

@ -22,6 +22,7 @@
target_os = "l4re",
target_os = "none",
target_os = "espidf",
target_os = "rtems",
))] {
// These "unix" family members do not have unwinder.
} else if #[cfg(any(

View File

@ -34,6 +34,7 @@ pub struct Finder {
// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
const STAGE0_MISSING_TARGETS: &[&str] = &[
// just a dummy comment so the list doesn't get onelined
"armv7-rtems-eabihf",
];
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM

View File

@ -210,7 +210,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_os = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@ -294,7 +294,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
| |
| help: there is a expected value with a similar name: `"linux"`
|
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: 30 warnings emitted