diff --git a/Cargo.toml b/Cargo.toml index 317dae3b..c3cdf7c1 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,11 +13,12 @@ description = "A unified interface for reading and writing object file formats." features = ['doc'] [dependencies] -crc32fast = { version = "1.2", optional = true } +crc32fast = { version = "1.2", default-features = false, optional = true } flate2 = { version = "1", optional = true } indexmap = { version = "1.1", optional = true } wasmparser = { version = "0.57", optional = true } memchr = { version = "2.4.1", default-features = false } +hashbrown = { version = "0.11", features = ["ahash"], default-features = false, optional = true } # Internal feature, only used when building as part of libstd, not part of the # stable interface of this crate. @@ -34,9 +35,11 @@ read_core = [] # Read support for all file formats (including unaligned files). read = ["read_core", "archive", "coff", "elf", "macho", "pe", "unaligned"] # Core write support. You will need to enable some file formats too. -write_core = ["crc32fast", "indexmap/std", "std"] -# Write support for all file formats. -write = ["write_core", "coff", "elf", "macho", "pe"] +write_core = ["crc32fast", "indexmap", "hashbrown"] +# Core write support with libstd features. You will need to enable some file formats too. +write_std = ["write_core", "std", "indexmap/std", "crc32fast/std"] +# Write support for all file formats, including libstd features. +write = ["write_std", "coff", "elf", "macho", "pe"] #======================================= # Misc features. @@ -79,7 +82,7 @@ cargo-all = [] #======================================= # Documentation should be generated with everything in "all" except for "unaligned". doc = [ - "read_core", "write_core", + "read_core", "write_std", "std", "compression", "archive", "coff", "elf", "macho", "pe", "wasm", ] diff --git a/crates/examples/Cargo.toml b/crates/examples/Cargo.toml index 43197389..312d50fb 100644 --- a/crates/examples/Cargo.toml +++ b/crates/examples/Cargo.toml @@ -24,11 +24,11 @@ required-features = ["object/read"] [[bin]] name = "elfcopy" -required-features = ["object/read_core", "object/write_core", "object/elf"] +required-features = ["object/read_core", "object/write_core", "object/elf", "object/std"] [[bin]] name = "elftoefi" -required-features = ["object/read_core", "object/write_core", "object/elf", "object/pe"] +required-features = ["object/read_core", "object/write_core", "object/elf", "object/pe", "object/std"] [[bin]] name = "objcopy" @@ -48,7 +48,7 @@ required-features = ["object/read"] [[bin]] name = "pecopy" -required-features = ["object/read_core", "object/write_core", "object/pe"] +required-features = ["object/read_core", "object/write_core", "object/pe", "object/std"] [[bin]] name = "readobj" diff --git a/src/lib.rs b/src/lib.rs index 63c387d9..13eda90e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,7 +73,7 @@ #[cfg(feature = "cargo-all")] compile_error!("'--all-features' is not supported; use '--features all' instead"); -#[cfg(feature = "read_core")] +#[cfg(any(feature = "read_core", feature = "write_core"))] #[allow(unused_imports)] #[macro_use] extern crate alloc; diff --git a/src/write/coff.rs b/src/write/coff.rs index 5b6a27dc..23684efa 100644 --- a/src/write/coff.rs +++ b/src/write/coff.rs @@ -1,5 +1,5 @@ -use std::mem; -use std::vec::Vec; +use alloc::vec::Vec; +use core::mem; use crate::endian::{LittleEndian as LE, U16Bytes, U32Bytes, U16, U32}; use crate::pe as coff; diff --git a/src/write/elf/object.rs b/src/write/elf/object.rs index ffa09ffa..efcb8944 100644 --- a/src/write/elf/object.rs +++ b/src/write/elf/object.rs @@ -1,4 +1,4 @@ -use std::vec::Vec; +use alloc::vec::Vec; use crate::elf; use crate::write::elf::writer::*; diff --git a/src/write/elf/writer.rs b/src/write/elf/writer.rs index eb815856..80740a29 100644 --- a/src/write/elf/writer.rs +++ b/src/write/elf/writer.rs @@ -1,7 +1,7 @@ //! Helper for writing ELF files. -use std::mem; -use std::string::String; -use std::vec::Vec; +use alloc::string::String; +use alloc::vec::Vec; +use core::mem; use crate::elf; use crate::endian::*; diff --git a/src/write/macho.rs b/src/write/macho.rs index 1aec4428..db4a1dab 100644 --- a/src/write/macho.rs +++ b/src/write/macho.rs @@ -1,4 +1,4 @@ -use std::mem; +use core::mem; use crate::endian::*; use crate::macho; diff --git a/src/write/mod.rs b/src/write/mod.rs index 9113df08..d7c5132b 100644 --- a/src/write/mod.rs +++ b/src/write/mod.rs @@ -1,11 +1,13 @@ //! Interface for writing object files. -use std::borrow::Cow; -use std::boxed::Box; -use std::collections::HashMap; -use std::string::String; -use std::vec::Vec; -use std::{error, fmt, io, result, str}; +use alloc::borrow::Cow; +use alloc::string::String; +use alloc::vec::Vec; +use core::{fmt, result, str}; +#[cfg(not(feature = "std"))] +use hashbrown::HashMap; +#[cfg(feature = "std")] +use std::{boxed::Box, collections::HashMap, error, io}; use crate::endian::{Endianness, U32, U64}; use crate::{ @@ -42,6 +44,7 @@ impl fmt::Display for Error { } } +#[cfg(feature = "std")] impl error::Error for Error {} /// The result type used within the write module. @@ -551,6 +554,7 @@ impl<'a> Object<'a> { /// /// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter) /// instead of an unbuffered writer like [`File`](std::fs::File). + #[cfg(feature = "std")] pub fn write_stream(&self, w: W) -> result::Result<(), Box> { let mut stream = StreamingBuffer::new(w); self.emit(&mut stream)?; diff --git a/src/write/pe.rs b/src/write/pe.rs index 27d03097..70da3a09 100644 --- a/src/write/pe.rs +++ b/src/write/pe.rs @@ -1,7 +1,7 @@ //! Helper for writing PE files. -use std::mem; -use std::string::String; -use std::vec::Vec; +use alloc::string::String; +use alloc::vec::Vec; +use core::mem; use crate::endian::{LittleEndian as LE, *}; use crate::pe; diff --git a/src/write/string.rs b/src/write/string.rs index e596fb27..3bdfccca 100644 --- a/src/write/string.rs +++ b/src/write/string.rs @@ -1,5 +1,9 @@ -use indexmap::IndexSet; -use std::vec::Vec; +use alloc::vec::Vec; + +#[cfg(feature = "std")] +type IndexSet = indexmap::IndexSet; +#[cfg(not(feature = "std"))] +type IndexSet = indexmap::IndexSet; /// An identifer for an entry in a string table. #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/write/util.rs b/src/write/util.rs index 02b96e47..51bc3515 100644 --- a/src/write/util.rs +++ b/src/write/util.rs @@ -1,6 +1,6 @@ -use std::io; -use std::mem; -use std::vec::Vec; +use alloc::vec::Vec; +#[cfg(feature = "std")] +use std::{io, mem}; use crate::pod::{bytes_of, bytes_of_slice, Pod}; @@ -86,6 +86,7 @@ impl WritableBuffer for Vec { /// /// It is advisable to use a buffered writer like [`BufWriter`](std::io::BufWriter) /// instead of an unbuffered writer like [`File`](std::fs::File). +#[cfg(feature = "std")] #[derive(Debug)] pub struct StreamingBuffer { writer: W, @@ -93,6 +94,7 @@ pub struct StreamingBuffer { result: Result<(), io::Error>, } +#[cfg(feature = "std")] impl StreamingBuffer { /// Create a new `StreamingBuffer` backed by the given writer. pub fn new(writer: W) -> Self { @@ -114,6 +116,7 @@ impl StreamingBuffer { } } +#[cfg(feature = "std")] impl WritableBuffer for StreamingBuffer { #[inline] fn len(&self) -> usize {