From 1b38503f77765a6bc86ed624b23de2612e1d8e8f Mon Sep 17 00:00:00 2001 From: Asuna Date: Wed, 17 Sep 2025 14:02:28 +0800 Subject: [PATCH 1/6] Implement `AndroidSink` --- spdlog/Cargo.toml | 4 + spdlog/src/sink/android_sink.rs | 227 ++++++++++++++++++++++++++++++++ spdlog/src/sink/mod.rs | 10 ++ 3 files changed, 241 insertions(+) create mode 100644 spdlog/src/sink/android_sink.rs diff --git a/spdlog/Cargo.toml b/spdlog/Cargo.toml index 026a5d49..1b8c75b5 100644 --- a/spdlog/Cargo.toml +++ b/spdlog/Cargo.toml @@ -35,6 +35,7 @@ release-level-trace = [] source-location = [] native = [] libsystemd = ["dep:libsystemd-sys"] +android_log = ["dep:android_log-sys"] multi-thread = ["dep:crossbeam"] runtime-pattern = ["dep:spdlog-internal"] serde = ["dep:serde", "value-bag/serde"] @@ -70,6 +71,9 @@ libc = "0.2" [target.'cfg(target_os = "linux")'.dependencies] libsystemd-sys = { version = "0.9.3", optional = true } +[target.'cfg(target_os = "android")'.dependencies] +android_log-sys = { version = "0.3.0", optional = true } + [dev-dependencies] clap = { version = "3.2.23", features = ["derive"] } crossbeam = "0.8.2" diff --git a/spdlog/src/sink/android_sink.rs b/spdlog/src/sink/android_sink.rs new file mode 100644 index 00000000..c5c1dcbf --- /dev/null +++ b/spdlog/src/sink/android_sink.rs @@ -0,0 +1,227 @@ +use std::{ffi::CString, io, ptr::null, result::Result as StdResult}; + +use libc::EPERM; + +use crate::{ + formatter::{Formatter, FormatterContext}, + prelude::*, + sink::{GetSinkProp, Sink, SinkProp}, + Error, ErrorHandler, Record, Result, StringBuf, +}; + +#[cfg(not(doc))] +mod ffi { + use android_log_sys::{LogPriority, __android_log_write, c_int}; + + use super::*; + + pub(super) struct AndroidLevelsMapping([LogPriority; Level::count()]); + + impl AndroidLevelsMapping { + #[must_use] + pub(super) const fn new() -> Self { + Self([ + LogPriority::FATAL, // spdlog::Critical + LogPriority::ERROR, // spdlog::Error + LogPriority::WARN, // spdlog::Warn + LogPriority::INFO, // spdlog::Info + LogPriority::DEBUG, // spdlog::Debug + LogPriority::VERBOSE, // spdlog::Trace + ]) + } + + #[must_use] + pub(super) fn level(&self, level: Level) -> LogPriority { + self.0[level as usize] + } + } + + pub(super) fn android_log_write( + priority: LogPriority, + tag: Option<&str>, + text: &str, + ) -> StdResult<(), io::Error> { + let tag = tag + .map(CString::new) + .transpose() + .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?; + let text = + CString::new(text).map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?; + + let tag_ptr = tag.as_deref().map(|tag| tag.as_ptr()).unwrap_or_else(null); + let text_ptr = text.as_ptr(); + + let result = unsafe { __android_log_write(priority as c_int, tag_ptr, text_ptr) }; + + // Explicitly drop to ensure that they have not been moved to cause dangling + // pointers. + drop((tag, text)); + + if result == 1 { + Ok(()) + } else { + // Doc: https://developer.android.com/ndk/reference/group/logging#group___logging_1ga32a7173b092ec978b50490bd12ee523b + // 1 if the message was written to the log, or -EPERM if it was not; + debug_assert_eq!(result, -EPERM); + Err(io::Error::from_raw_os_error(EPERM)) + } + } +} + +/// Represents how to choose a tag for Android logs. +/// +/// # Log Level Mapping +/// +/// | spdlog-rs | Android NDK | +/// |------------|-------------| +/// | `Critical` | `FATAL` | +/// | `Error` | `ERROR` | +/// | `Warn` | `WARN` | +/// | `Info` | `INFO` | +/// | `Debug` | `DEBUG` | +/// | `Trace` | `VERBOSE` | +/// +/// # Note +/// +/// It requires linking to Android NDK `liblog`. +pub enum AndroidLogTag { + /// The default tag determined by Android NDK. + Default, + /// The name of the `spdlog-rs` logger that generated the log. + LoggerName, + /// A custom string. + Custom(String), +} + +#[allow(missing_docs)] +pub struct AndroidSinkBuilder { + prop: SinkProp, + tag: AndroidLogTag, +} + +impl AndroidSinkBuilder { + /// Specifies how to choose a tag for Android logs. + /// + /// This parameter is **optional**. + #[must_use] + pub fn tag(mut self, tag: AndroidLogTag) -> Self { + self.tag = tag; + self + } + + // Prop + // + + /// Specifies a log level filter. + /// + /// This parameter is **optional**. + #[must_use] + pub fn level_filter(self, level_filter: LevelFilter) -> Self { + self.prop.set_level_filter(level_filter); + self + } + + /// Specifies a formatter. + /// + /// This parameter is **optional**. + #[must_use] + pub fn formatter(self, formatter: F) -> Self + where + F: Formatter + 'static, + { + self.prop.set_formatter(formatter); + self + } + + /// Specifies an error handler. + /// + /// This parameter is **optional**. + #[must_use] + pub fn error_handler>(self, handler: F) -> Self { + self.prop.set_error_handler(handler); + self + } + + // + + /// Constructs a `AndroidSink`. + pub fn build(self) -> Result { + Ok(AndroidSink { + prop: self.prop, + tag: self.tag, + }) + } +} + +/// A sink with Android NDK API `__android_log_write` as the target. +pub struct AndroidSink { + prop: SinkProp, + tag: AndroidLogTag, +} + +impl AndroidSink { + #[cfg(not(doc))] + const LEVELS_MAPPING: ffi::AndroidLevelsMapping = ffi::AndroidLevelsMapping::new(); + + /// Gets a builder of `AndroidSink` with default parameters: + /// + /// | Parameter | Default Value | + /// |-----------------|-----------------------------| + /// | [level_filter] | `All` | + /// | [formatter] | `FullFormatter` | + /// | [error_handler] | [`ErrorHandler::default()`] | + /// | | | + /// | [tag] | `AndroidSink::Default` | + /// + /// [level_filter]: AndroidSinkBuilder::level_filter + /// [formatter]: AndroidSinkBuilder::formatter + /// [error_handler]: AndroidSinkBuilder::error_handler + /// [`ErrorHandler::default()`]: crate::error::ErrorHandler::default() + /// [tag]: AndroidSinkBuilder::tag + #[must_use] + pub fn builder() -> AndroidSinkBuilder { + AndroidSinkBuilder { + prop: SinkProp::default(), + tag: AndroidLogTag::Default, + } + } + + /// Gets how to choose a tag for Android logs. + #[must_use] + pub fn tag(&self) -> &AndroidLogTag { + &self.tag + } + + /// Sets how to choose a tag for Android logs. + pub fn set_tag(&mut self, tag: AndroidLogTag) { + self.tag = tag; + } +} + +impl GetSinkProp for AndroidSink { + fn prop(&self) -> &SinkProp { + &self.prop + } +} + +impl Sink for AndroidSink { + fn log(&self, record: &Record) -> Result<()> { + let mut string_buf = StringBuf::new(); + let mut ctx = FormatterContext::new(); + self.prop + .formatter() + .format(record, &mut string_buf, &mut ctx)?; + + let priority = Self::LEVELS_MAPPING.level(record.level()); + let tag = match &self.tag { + AndroidLogTag::Default => None, + AndroidLogTag::LoggerName => record.logger_name(), + AndroidLogTag::Custom(tag) => Some(tag.as_str()), + }; + ffi::android_log_write(priority, tag, &string_buf).map_err(Error::WriteRecord) + } + + fn flush(&self) -> Result<()> { + Ok(()) + } +} diff --git a/spdlog/src/sink/mod.rs b/spdlog/src/sink/mod.rs index 6f467e78..f24dc7b6 100644 --- a/spdlog/src/sink/mod.rs +++ b/spdlog/src/sink/mod.rs @@ -19,6 +19,11 @@ //! //! [`Logger`]: crate::logger::Logger +#[cfg(any( + all(target_os = "android", feature = "native", feature = "android_log"), + all(doc, not(doctest)) +))] +mod android_sink; #[cfg(feature = "multi-thread")] pub(crate) mod async_sink; mod dedup_sink; @@ -36,6 +41,11 @@ mod write_sink; use std::ops::Deref; +#[cfg(any( + all(target_os = "android", feature = "native", feature = "android_log"), + all(doc, not(doctest)) +))] +pub use android_sink::*; #[cfg(feature = "multi-thread")] pub use async_sink::*; pub use dedup_sink::*; From d7c02370e9521e32a0edb85b860c37c5116fa9ca Mon Sep 17 00:00:00 2001 From: Asuna Date: Fri, 19 Sep 2025 19:51:12 +0800 Subject: [PATCH 2/6] Handle the return value of `__android_log_write` for API before 30 --- spdlog/src/sink/android_sink.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/spdlog/src/sink/android_sink.rs b/spdlog/src/sink/android_sink.rs index c5c1dcbf..e144261b 100644 --- a/spdlog/src/sink/android_sink.rs +++ b/spdlog/src/sink/android_sink.rs @@ -57,13 +57,29 @@ mod ffi { // pointers. drop((tag, text)); - if result == 1 { + // Although the documentation [^1] says that: + // 1 if the message was written to the log, or -EPERM if it was not; + // + // It doesn't point out that the behavior differs between versions. The above + // behavior is available since Android 11 (API 30). Before that, the behavior of + // the return value was not clarified in the documentation, but referring to the + // implementation, for a successful log write, the number of bytes written is + // actually returned. This behavior is changed in this commit [^2]. + // + // For compatible with more versions, we do not use `result == 1` as the success + // condition, but `result >= 0` instead. + // + // [^1]: https://developer.android.com/ndk/reference/group/logging#group___logging_1ga32a7173b092ec978b50490bd12ee523b + // [^2]: https://android.googlesource.com/platform/system/logging/+/c17613c4582d4f6eecb3965bb96584f25762b827%5E%21/ + // + // --- + // + // For the condition `result == -EPERM`, see + // https://github.com/gabime/spdlog/commit/01b3724c484eebb42d83fa21aa8d71a57b2b8fb6 + if result >= 0 || /* !__android_log_is_loggable */ result == -EPERM { Ok(()) } else { - // Doc: https://developer.android.com/ndk/reference/group/logging#group___logging_1ga32a7173b092ec978b50490bd12ee523b - // 1 if the message was written to the log, or -EPERM if it was not; - debug_assert_eq!(result, -EPERM); - Err(io::Error::from_raw_os_error(EPERM)) + Err(io::Error::from_raw_os_error(-result)) } } } From 1511dbdc28abf8f6dd3a43b369e036195c63e40c Mon Sep 17 00:00:00 2001 From: Asuna Date: Sat, 20 Sep 2025 02:04:02 +0800 Subject: [PATCH 3/6] Implement private `AndroidFormatter` for `AndroidSink` --- spdlog/src/formatter/android_formatter.rs | 75 +++++++++++++++++++++++ spdlog/src/formatter/mod.rs | 10 +++ spdlog/src/sink/android_sink.rs | 9 ++- 3 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 spdlog/src/formatter/android_formatter.rs diff --git a/spdlog/src/formatter/android_formatter.rs b/spdlog/src/formatter/android_formatter.rs new file mode 100644 index 00000000..7eada186 --- /dev/null +++ b/spdlog/src/formatter/android_formatter.rs @@ -0,0 +1,75 @@ +// TODO: Remove this file, use `PatternFormatter` instead +// +// Need to keep waiting for conditional space and brackets to be supported in +// pattern template strings (optional fields require these, e.g. `logger_name`) + +use std::fmt::{self, Write}; + +use cfg_if::cfg_if; + +use crate::{ + formatter::{Formatter, FormatterContext}, + Error, Record, StringBuf, +}; + +#[derive(Clone)] +pub(crate) struct AndroidFormatter {} + +impl AndroidFormatter { + #[must_use] + pub(crate) fn new() -> Self { + Self {} + } + + fn format_impl( + &self, + record: &Record, + dest: &mut StringBuf, + _ctx: &mut FormatterContext, + ) -> Result<(), fmt::Error> { + cfg_if! { + if #[cfg(not(feature = "flexible-string"))] { + dest.reserve(crate::string_buf::RESERVE_SIZE); + } + } + + if let Some(logger_name) = record.logger_name() { + dest.write_str("[")?; + dest.write_str(logger_name)?; + dest.write_str("] ")?; + } + + if let Some(srcloc) = record.source_location() { + dest.write_str("[")?; + dest.write_str(srcloc.module_path())?; + dest.write_str(", ")?; + dest.write_str(srcloc.file())?; + dest.write_str(":")?; + write!(dest, "{}", srcloc.line())?; + dest.write_str("] ")?; + } + + dest.write_str(record.payload())?; + + record.key_values().write_to(dest, true)?; + Ok(()) + } +} + +impl Formatter for AndroidFormatter { + fn format( + &self, + record: &Record, + dest: &mut StringBuf, + ctx: &mut FormatterContext, + ) -> crate::Result<()> { + self.format_impl(record, dest, ctx) + .map_err(Error::FormatRecord) + } +} + +impl Default for AndroidFormatter { + fn default() -> Self { + Self::new() + } +} diff --git a/spdlog/src/formatter/mod.rs b/spdlog/src/formatter/mod.rs index 279eb615..422cb87d 100644 --- a/spdlog/src/formatter/mod.rs +++ b/spdlog/src/formatter/mod.rs @@ -51,6 +51,11 @@ //! [`SinkPropAccess::set_formatter`]: crate::sink::SinkPropAccess::set_formatter //! [./examples]: https://github.com/SpriteOvO/spdlog-rs/tree/main/spdlog/examples +#[cfg(any( + all(target_os = "android", feature = "native", feature = "android_log"), + all(doc, not(doctest)) +))] +mod android_formatter; mod full_formatter; #[cfg(any( all(target_os = "linux", feature = "native", feature = "libsystemd"), @@ -65,6 +70,11 @@ mod unreachable_formatter; use std::ops::Range; +#[cfg(any( + all(target_os = "android", feature = "native", feature = "android_log"), + all(doc, not(doctest)) +))] +pub(crate) use android_formatter::*; use dyn_clone::*; pub use full_formatter::*; #[cfg(any( diff --git a/spdlog/src/sink/android_sink.rs b/spdlog/src/sink/android_sink.rs index e144261b..8db06eb3 100644 --- a/spdlog/src/sink/android_sink.rs +++ b/spdlog/src/sink/android_sink.rs @@ -3,7 +3,7 @@ use std::{ffi::CString, io, ptr::null, result::Result as StdResult}; use libc::EPERM; use crate::{ - formatter::{Formatter, FormatterContext}, + formatter::{AndroidFormatter, Formatter, FormatterContext}, prelude::*, sink::{GetSinkProp, Sink, SinkProp}, Error, ErrorHandler, Record, Result, StringBuf, @@ -184,7 +184,7 @@ impl AndroidSink { /// | Parameter | Default Value | /// |-----------------|-----------------------------| /// | [level_filter] | `All` | - /// | [formatter] | `FullFormatter` | + /// | [formatter] | `AndroidFormatter` | /// | [error_handler] | [`ErrorHandler::default()`] | /// | | | /// | [tag] | `AndroidSink::Default` | @@ -196,8 +196,11 @@ impl AndroidSink { /// [tag]: AndroidSinkBuilder::tag #[must_use] pub fn builder() -> AndroidSinkBuilder { + let prop = SinkProp::default(); + prop.set_formatter(AndroidFormatter::new()); + AndroidSinkBuilder { - prop: SinkProp::default(), + prop, tag: AndroidLogTag::Default, } } From 1c7254e610f877b915b64b16bcc877a90c95a606 Mon Sep 17 00:00:00 2001 From: Asuna Date: Fri, 19 Sep 2025 19:53:00 +0800 Subject: [PATCH 4/6] Add a native integration test for `AndroidSink` --- .github/workflows/ci.yml | 41 +++++++++++++++++++++++++++++++ spdlog/Cargo.toml | 4 +++ spdlog/examples/native/android.rs | 30 ++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 spdlog/examples/native/android.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f4b4724..1a454f94 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -196,6 +196,47 @@ jobs: - name: Check MSRV for core with Rust ${{ env.rust_minver }} run: cargo +${{ env.rust_minver }} check --locked --all-features --verbose + native-test-android: + strategy: + fail-fast: false + runs-on: 'ubuntu-latest' + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Restore cargo caches + uses: Swatinem/rust-cache@v2 + - name: Install cross + run: cargo install cross --git https://github.com/cross-rs/cross --verbose + - name: Build example + run: | + cross build --target x86_64-linux-android --example native_android --features native,android_log,source-location --verbose + mv ./target/x86_64-linux-android/debug/examples/native_android ./target/x86_64-linux-android/debug/examples/native_android_srcloc + cross build --target x86_64-linux-android --example native_android --features native,android_log --verbose + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Run emulator and test + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 29 + arch: x86_64 + script: | + adb root + adb push ./target/x86_64-linux-android/debug/examples/native_android /data + adb push ./target/x86_64-linux-android/debug/examples/native_android_srcloc /data + + adb logcat -b all -c + adb shell /data/native_android + adb shell /data/native_android_srcloc + adb logcat -s "spdlog-rs-example" -d > ./logcat.log + cat ./logcat.log + cat ./logcat.log | grep "I spdlog-rs-example: \[demo] info message from spdlog-rs's AndroidSink" + cat ./logcat.log | grep "E spdlog-rs-example: \[demo] error message from spdlog-rs's AndroidSink { error_code=114514 }" + cat ./logcat.log | grep -E "I spdlog-rs-example: \[demo] \[native_android, .+.rs:[0-9]+] info message from spdlog-rs's AndroidSink" + cat ./logcat.log | grep -E "E spdlog-rs-example: \[demo] \[native_android, .+.rs:[0-9]+] error message from spdlog-rs's AndroidSink { error_code=114514 }" + bench: needs: [test, check] strategy: diff --git a/spdlog/Cargo.toml b/spdlog/Cargo.toml index 1b8c75b5..98d0560f 100644 --- a/spdlog/Cargo.toml +++ b/spdlog/Cargo.toml @@ -177,3 +177,7 @@ required-features = ["log"] [[example]] name = "07_async" required-features = ["multi-thread"] +[[example]] +name = "native_android" +path = "examples/native/android.rs" +required-features = ["native", "android_log"] diff --git a/spdlog/examples/native/android.rs b/spdlog/examples/native/android.rs new file mode 100644 index 00000000..2e20ba3b --- /dev/null +++ b/spdlog/examples/native/android.rs @@ -0,0 +1,30 @@ +#[cfg(target_os = "android")] +fn main() -> Result<(), Box> { + use std::sync::Arc; + + use spdlog::{ + prelude::*, + sink::{AndroidLogTag, AndroidSink}, + }; + + let sink = Arc::new( + AndroidSink::builder() + .tag(AndroidLogTag::Custom("spdlog-rs-example".into())) + .build()?, + ); + let logger = spdlog::default_logger().fork_with(|logger| { + logger.set_name(Some("demo")).unwrap(); + logger.sinks_mut().push(sink); + Ok(()) + })?; + spdlog::set_default_logger(logger); + + info!("info message from spdlog-rs's AndroidSink"); + error!("error message from spdlog-rs's AndroidSink", kv: { error_code = 114514 }); + Ok(()) +} + +#[cfg(not(target_os = "android"))] +fn main() { + panic!("this example is only available on Android target"); +} From 52726711ea2c0266461c27b4ee5866749f456d40 Mon Sep 17 00:00:00 2001 From: Asuna Date: Sat, 20 Sep 2025 02:17:32 +0800 Subject: [PATCH 5/6] CI run clippy for all target triplets --- .github/workflows/ci.yml | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a454f94..fb7371a2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,12 +20,24 @@ env: # - Cargo.toml # - README.md rust_minver: 1.63.0 + ci_targets: "['', 'x86_64-apple-ios', 'x86_64-unknown-freebsd', 'x86_64-unknown-illumos', 'aarch64-linux-android']" defaults: run: shell: bash jobs: + matrix: + strategy: + fail-fast: false + runs-on: ubuntu-latest + outputs: + ci_targets: ${{ steps.generate.outputs.ci_targets }} + steps: + - name: Generate matrix + id: generate + run: echo "ci_targets=${{ env.ci_targets }}" >> $GITHUB_OUTPUT + format: strategy: fail-fast: false @@ -78,17 +90,27 @@ jobs: done clippy: + needs: [matrix] strategy: fail-fast: false matrix: os: ['ubuntu-latest', 'windows-latest', 'macos-latest'] + target: ${{ fromJSON(needs.matrix.outputs.ci_targets) }} runs-on: ${{ matrix.os }} steps: - name: Checkout repository uses: actions/checkout@v4 + - name: Disable bench dependencies + if: matrix.target != '' + run: ./.github/workflows/disable-bench-deps.sh - name: Install dependencies if: matrix.os == 'ubuntu-latest' run: sudo bash ./.github/workflows/install-deps.sh + - name: Install Rust target + if: matrix.target != '' + run: | + rustup target add ${{ matrix.target }} + echo 'CARGO_BUILD_TARGET=${{ matrix.target }}' >> $GITHUB_ENV - name: Install Rust nightly run: | rustup toolchain install nightly @@ -98,6 +120,8 @@ jobs: - name: Run clippy run: cargo clippy --all-features --tests --examples -- -D warnings - name: Run clippy nightly + # For some tier-2 targets, nightly does not provide a full pre-compile toolchain + if: matrix.target == '' run: | cargo +nightly clippy --all-features --tests --examples @@ -106,6 +130,7 @@ jobs: echo "::warning title=nightly clippy::Detected $WARNS warnings" fi - name: Run clippy nightly for benches + if: matrix.target == '' run: | cargo +nightly clippy --all-features --benches -- -A clippy::incompatible_msrv @@ -115,11 +140,12 @@ jobs: fi check: + needs: [matrix] strategy: fail-fast: false matrix: os: ['ubuntu-latest', 'windows-latest', 'macos-latest'] - target: ['', 'x86_64-apple-ios', 'x86_64-unknown-freebsd', 'x86_64-unknown-illumos', 'aarch64-linux-android'] + target: ${{ fromJSON(needs.matrix.outputs.ci_targets) }} runs-on: ${{ matrix.os }} steps: - name: Checkout repository @@ -131,16 +157,13 @@ jobs: run: sudo bash ./.github/workflows/install-deps.sh - name: Install Rust target if: matrix.target != '' - run: rustup target add ${{ matrix.target }} + run: | + rustup target add ${{ matrix.target }} + echo 'CARGO_BUILD_TARGET=${{ matrix.target }}' >> $GITHUB_ENV - name: Restore cargo caches uses: Swatinem/rust-cache@v2 - name: Run check - run: | - if [[ -z "${{ matrix.target }}" ]]; then - cargo check --all-features - else - cargo check --all-features --target ${{ matrix.target }} - fi + run: cargo check --all-features --verbose check-doc: strategy: From 285a5e8001c9ddf2ed21a4a94901ae3f103d55d5 Mon Sep 17 00:00:00 2001 From: Asuna Date: Sat, 20 Sep 2025 14:01:33 +0800 Subject: [PATCH 6/6] Rename feature gate `android_log` to `android-ndk` --- .github/workflows/ci.yml | 4 ++-- spdlog/Cargo.toml | 4 ++-- spdlog/src/formatter/mod.rs | 4 ++-- spdlog/src/sink/mod.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb7371a2..a7f7d917 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -232,9 +232,9 @@ jobs: run: cargo install cross --git https://github.com/cross-rs/cross --verbose - name: Build example run: | - cross build --target x86_64-linux-android --example native_android --features native,android_log,source-location --verbose + cross build --target x86_64-linux-android --example native_android --features native,android-ndk,source-location --verbose mv ./target/x86_64-linux-android/debug/examples/native_android ./target/x86_64-linux-android/debug/examples/native_android_srcloc - cross build --target x86_64-linux-android --example native_android --features native,android_log --verbose + cross build --target x86_64-linux-android --example native_android --features native,android-ndk --verbose - name: Enable KVM run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules diff --git a/spdlog/Cargo.toml b/spdlog/Cargo.toml index 98d0560f..7352b286 100644 --- a/spdlog/Cargo.toml +++ b/spdlog/Cargo.toml @@ -35,7 +35,7 @@ release-level-trace = [] source-location = [] native = [] libsystemd = ["dep:libsystemd-sys"] -android_log = ["dep:android_log-sys"] +android-ndk = ["dep:android_log-sys"] multi-thread = ["dep:crossbeam"] runtime-pattern = ["dep:spdlog-internal"] serde = ["dep:serde", "value-bag/serde"] @@ -180,4 +180,4 @@ required-features = ["multi-thread"] [[example]] name = "native_android" path = "examples/native/android.rs" -required-features = ["native", "android_log"] +required-features = ["native", "android-ndk"] diff --git a/spdlog/src/formatter/mod.rs b/spdlog/src/formatter/mod.rs index 422cb87d..aa048ed3 100644 --- a/spdlog/src/formatter/mod.rs +++ b/spdlog/src/formatter/mod.rs @@ -52,7 +52,7 @@ //! [./examples]: https://github.com/SpriteOvO/spdlog-rs/tree/main/spdlog/examples #[cfg(any( - all(target_os = "android", feature = "native", feature = "android_log"), + all(target_os = "android", feature = "native", feature = "android-ndk"), all(doc, not(doctest)) ))] mod android_formatter; @@ -71,7 +71,7 @@ mod unreachable_formatter; use std::ops::Range; #[cfg(any( - all(target_os = "android", feature = "native", feature = "android_log"), + all(target_os = "android", feature = "native", feature = "android-ndk"), all(doc, not(doctest)) ))] pub(crate) use android_formatter::*; diff --git a/spdlog/src/sink/mod.rs b/spdlog/src/sink/mod.rs index f24dc7b6..dbdc250f 100644 --- a/spdlog/src/sink/mod.rs +++ b/spdlog/src/sink/mod.rs @@ -20,7 +20,7 @@ //! [`Logger`]: crate::logger::Logger #[cfg(any( - all(target_os = "android", feature = "native", feature = "android_log"), + all(target_os = "android", feature = "native", feature = "android-ndk"), all(doc, not(doctest)) ))] mod android_sink; @@ -42,7 +42,7 @@ mod write_sink; use std::ops::Deref; #[cfg(any( - all(target_os = "android", feature = "native", feature = "android_log"), + all(target_os = "android", feature = "native", feature = "android-ndk"), all(doc, not(doctest)) ))] pub use android_sink::*;