From eff2283dab963a21e14a71585003051d3ea9056c Mon Sep 17 00:00:00 2001 From: Winter Date: Mon, 30 Jan 2023 21:34:33 -0500 Subject: [PATCH] Hide `iconv` functions on Apple devices behind a feature flag --- Cargo.toml | 1 + README.md | 2 ++ src/unix/bsd/apple/iconv.rs | 11 +++++++++++ src/unix/bsd/apple/mod.rs | 26 +++++++++++++------------- 4 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 src/unix/bsd/apple/iconv.rs diff --git a/Cargo.toml b/Cargo.toml index 15c2b9bf53b8d..52c2151379cb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ align = [] rustc-dep-of-std = ['align', 'rustc-std-workspace-core'] extra_traits = [] const-extern-fn = [] +iconv-apple = [] # use_std is deprecated, use `std` instead use_std = [ 'std' ] diff --git a/README.md b/README.md index bc5ad18f6b1b8..4f87ce57779eb 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ libc = "0.2" If you use Rust >= 1.62, this feature is implicitly enabled. Otherwise it requires a nightly rustc. +* `iconv-apple`: Enables usage of `iconv_open`, `iconv`, and `iconv_close` on Apple devices. + * **deprecated**: `use_std` is deprecated, and is equivalent to `std`. ## Rust version support diff --git a/src/unix/bsd/apple/iconv.rs b/src/unix/bsd/apple/iconv.rs new file mode 100644 index 0000000000000..5c9e39ec212ab --- /dev/null +++ b/src/unix/bsd/apple/iconv.rs @@ -0,0 +1,11 @@ +extern "C" { + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + pub fn iconv( + cd: iconv_t, + inbuf: *mut *mut ::c_char, + inbytesleft: *mut ::size_t, + outbuf: *mut *mut ::c_char, + outbytesleft: *mut ::size_t, + ) -> ::size_t; + pub fn iconv_close(cd: iconv_t) -> ::c_int; +} diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs index 24a6d61033dd1..1d0f81a608ac6 100644 --- a/src/unix/bsd/apple/mod.rs +++ b/src/unix/bsd/apple/mod.rs @@ -5908,19 +5908,19 @@ cfg_if! { } // These require a dependency on `libiconv`, and including this when built as -// part of `std` means every Rust program gets it. Ideally we would have a link -// modifier to only include these if they are used, but we do not. -#[cfg_attr(not(feature = "rustc-dep-of-std"), link(name = "iconv"))] -extern "C" { - pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; - pub fn iconv( - cd: iconv_t, - inbuf: *mut *mut ::c_char, - inbytesleft: *mut ::size_t, - outbuf: *mut *mut ::c_char, - outbytesleft: *mut ::size_t, - ) -> ::size_t; - pub fn iconv_close(cd: iconv_t) -> ::c_int; +// part of `std` means every Rust program gets it. Additionally, when not built +// as part of `std`, merely using `libc` on an Apple target will pull in `libiconv`. +// +// Therefore, due to these functions very low usage numbers on the platform, we hide it +// behind a feature flag. +// +// Ideally we would have a link modifier to only include these if they are used, but we do not. +cfg_if! { + if #[cfg(feature = "iconv-apple")] { + #[link(name = "iconv")] + mod iconv; + pub use self::iconv::*; + } } cfg_if! {