Skip to content

Port Tauri Android build to Bazel, cross-compile macOS x64, etc. #54

Open
MulverineX wants to merge 40 commits intoMoosync:bazelfrom
MulverineX:bazel
Open

Port Tauri Android build to Bazel, cross-compile macOS x64, etc. #54
MulverineX wants to merge 40 commits intoMoosync:bazelfrom
MulverineX:bazel

Conversation

@MulverineX
Copy link
Copy Markdown

@MulverineX MulverineX commented Mar 24, 2026

Summary by Sourcery

Introduce Bazel-based Android and cross-platform build support, including Linux, macOS, Windows, and cross-compiled macOS x64 from Linux, while improving audio handling and platform-specific integrations.

New Features:

  • Add Bazel-backed Android build pipeline producing arm64 and x86_64 APKs and integrate Tauri Android crates and plugins into the Gradle project.
  • Introduce a Rust shared library target for Android (moosync_android) and JNI wiring for Tauri-based mobile builds.
  • Add macOS x64 cross-compilation from Linux using rules_applecross, including external dependency and toolchain configuration, plus a workflow to package and publish the Apple SDK for CI use.
  • Provide optional Android NDK toolchain integration so non-Android builds can run without a local NDK install.

Bug Fixes:

  • Fix rodio decoder sample-rate handling by always resampling to the system/device rate, avoiding mismatches and audio issues.
  • Resolve Android database build issues by using ANDROID_NDK_HOME instead of NDK_HOME for x86_64 builds.
  • Avoid panics when loading the active theme in the web UI by handling missing or malformed theme values gracefully.
  • Stabilize proto dependency collection for rust_prost_library rules by using transitive_sources instead of transitive_imports.

Enhancements:

  • Refine GitHub Actions build matrix and steps to build per-arch desktop artifacts, keep Android SDK where needed, add swap on Linux, and split artifacts by format and platform.
  • Enhance audio pipeline by detecting system sample rate (including PulseAudio/PipeWire on Linux) and wiring it through RodioPlayer and the FFmpeg decoder, plus adding debug logging and Linux-only PulseAudio monitoring support.
  • Make rodio and mpris functionality platform-aware, adding mobile stubs that defer to tauri-plugin-audioplayer on Android and integrating Android-specific MPRIS handling.
  • Wire Android variants of core features (file scanner, self-update, audioplayer) into the Bazel build via tauri_android sources and build-script environment, and adjust dependencies to use protobuf-generated types.
  • Tighten and modernize Bazel module dependencies, toolchains, and external builds (protobuf, rules_cc, rules_python, JS tooling, foreign_cc preinstalled toolchains, and Darwin cross flags for ffmpeg/openssl/ogg/opus/vorbis/lame).
  • Document future work and CI/debugging plans via new TODO and CONTEXT markdown files and add small dev convenience scripts for installing/uninstalling local builds.

Build:

  • Restructure CI build workflow inputs to be arch-specific, adjust artifact upload strategy, and add Android APK and macOS x64 cross-compile steps.
  • Switch Bazel setup in CI to a custom fork with smarter disk/repository cache handling and add swap space configuration on Ubuntu runners.
  • Extend Bazel MODULE and toolchain configuration with Android, Apple cross-compilation, and optional Android NDK support, plus target_os build settings and platform definitions for Android and Darwin.

CI:

  • Add a dedicated workflow to package and publish an Apple SDK archive from macOS runners for use by Linux cross-compilation.
  • Provide notes and configuration guidance for locally emulating CI with act and a custom Docker image.

Documentation:

  • Add multiple TODO and context documents describing dynamic sample-rate switching, Android plugin and protobuf refactors, local CI emulation, FFmpeg shared-library plans, and high-level project/AI usage notes.

Tests:

  • Add or update platform-specific Rust tests and sources where required by new modules (for example pulse_monitor and Android-specific code paths).

Chores:

  • Clean up obsolete Android Gradle metadata and logs, adjust .gitignore and VS Code workspace settings, and add helper scripts for dev installation flows.

…ed on accident before the correct gitignore was added
- Use anonymous object implementing Action<ExecSpec> instead of lambda
- KLS can now properly infer types from the execute() method signature
- Full completion support for spec.workingDir, spec.executable, etc.
- Also adds kotlin-gradle-plugin to buildSrc dependencies for completeness
… the linux x64 artifact handling above the Android CI
Extracts macOS SDK from Xcode on a macOS runner and uploads
it to a GitHub pre-release for use by Linux cross-compilation.

Developed with assistance from Claude Opus 4.5
The Android build introduces non-deterministic outputs (likely from
tauri-codegen HashMap iteration order), causing unnecessary cache
re-uploads. Disable re-uploads for this job while still allowing
initial cache population.

Developed with assistance from Claude Opus 4.5
Users typically only need one format, not all three.

Developed with assistance from Claude Opus 4.5
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Mar 24, 2026

Reviewer's Guide

Ports Android builds to Bazel-backed native library + Gradle APK pipeline, adds Linux-based macOS x64 cross-compilation with apple-cross toolchain and foreign_cc patches, introduces platform/target-OS aware build settings and toolchains, and improves rodio audio handling to use device-native sample rates (with PulseAudio integration) while adding mobile-specific stubs and Tauri Android integration for plugins and mpris.

Sequence diagram for Bazel-backed Android APK build pipeline

sequenceDiagram
  actor Dev
  participant GH as GitHubActions
  participant Bazel as Bazel//tauri:moosync_android
  participant Gradle as GradleAndroidProject
  participant BuildTask as BuildTask(Gradle)
  participant RustPlugin as RustPlugin(Gradle)

  Dev->>GH: Trigger build.yaml (ubuntu-22.04)
  GH->>Bazel: bazel build //tauri:moosync_android --platforms=//toolchains/android:aarch64,x86_64 --//tools:target_os=android
  Bazel-->>GH: Produce libapp_lib.so per ABI and UI dist assets

  GH->>Gradle: Setup Java 17
  GH->>Gradle: ./gradlew assembleArm64Debug assembleX86_64Debug
  Gradle->>RustPlugin: apply plugin RustPlugin
  RustPlugin->>RustPlugin: Determine abiList, archList, targetList

  Gradle->>BuildTask: assemble for each target (aarch64,x86_64)
  BuildTask->>BuildTask: Read rootDirRel, target, release
  BuildTask->>BuildTask: Map target to platform, abi
  BuildTask->>BuildTask: Locate bazel-bin/tauri/libapp_lib.so
  BuildTask->>BuildTask: Copy to src/main/jniLibs/<abi>/libapp_lib.so

  BuildTask->>BuildTask: Copy UI assets from bazel-bin/ui/gen_dist/moosync_dist to src/main/assets (once)
  BuildTask->>BuildTask: Generate Kotlin files from tauri/wry crates into src/main/java/app/moosync/moosync (once)
  BuildTask->>BuildTask: Copy proguard-tauri.pro from tauri crate (once)

  BuildTask-->>Gradle: Native libs and assets ready
  Gradle->>Gradle: Package APKs (arm64,x86_64)
  Gradle-->>GH: APK files under app/build/outputs/apk/*/debug

  GH->>GH: Upload artifacts moosync-android-arm64, moosync-android-x86_64
Loading

Class diagram for Rodio audio pipeline with PulseAudio integration

classDiagram
  class RodioPlayer {
    -Sender~RodioCommand~ tx
    -Arc~Mutex~Receiver~PlayerEvent~~ events_rx
    +new() RodioPlayer
    -initialize(events_tx Sender~PlayerEvent~) Sender~RodioCommand~
    -set_src(src String, sink Arc~rodio.Player~, output_sample_rate u32) Result~()~
  }

  class RodioCommand {
    <<enum>>
    Load(String)
    Play
    Pause
    Stop
    Seek(f64)
    SetVolume(f32)
  }

  class PlayerEvent {
    <<enum>>
    Loading(bool)
    TimeUpdate(f64)
    Error(String)
  }

  class FFMPEGDecoder {
    -format_ctx AVFormatContextInput
    -stream_idx usize
    -codec_ctx AVCodecContext
    -swr_ctx SwrContext
    -current_frame Vec~u8~
    -requested_seek_timestamp i64
    -output_sample_rate u32
    +open(path &str, output_sample_rate u32) Result~FFMPEGDecoder~
    -initialize_swr_context(codec_ctx &AVCodecContext, output_sample_rate i32) Result~SwrContext~
    -decode_frame(frame &AVFrame) Result~()~
  }

  class Source {
    <<trait>>
    +channels() ChannelCount
    +sample_rate() SampleRate
  }

  class PulseEvent {
    <<enum>>
    SampleRateDetected(u32)
    SampleRateChanged(old u32, new u32)
    DefaultSinkChanged(String)
    Error(String)
  }

  class pulse_monitor {
    +start_pulse_monitor() Receiver~PulseEvent~
    +get_default_sample_rate() Option~u32~
  }

  class rodio_cpal_helpers {
    +get_system_sample_rate() u32
    +get_cpal_default_sample_rate() u32
  }

  RodioPlayer o-- RodioCommand
  RodioPlayer o-- PlayerEvent
  RodioPlayer --> FFMPEGDecoder : uses
  FFMPEGDecoder ..|> Source
  rodio_cpal_helpers --> pulse_monitor : calls
  RodioPlayer --> rodio_cpal_helpers : uses for sample rate
  PulseEvent <.. pulse_monitor
Loading

Class diagram for Tauri rodio desktop vs mobile audio commands

classDiagram
  class RodioModuleDesktop {
    <<tauri module>>
    +get_rodio_state(app AppHandle) RodioPlayer
    +rodio_load(app AppHandle, src String) Result~()~
    +rodio_play(app AppHandle) Result~()~
    +rodio_pause(app AppHandle) Result~()~
    +rodio_stop(app AppHandle) Result~()~
    +rodio_seek(app AppHandle, pos f64) Result~()~
    +rodio_set_volume(app AppHandle, volume f32) Result~()~
    +rodio_get_volume(app AppHandle) Result~f32~
  }

  class RodioModuleMobile {
    <<tauri module>>
    +RodioPlayerStub
    +get_rodio_state(app AppHandle) RodioPlayerStub
    +rodio_load(app AppHandle, src String) Result~()~
    +rodio_play(app AppHandle) Result~()~
    +rodio_pause(app AppHandle) Result~()~
    +rodio_stop(app AppHandle) Result~()~
    +rodio_seek(app AppHandle, pos f64) Result~()~
    +rodio_set_volume(app AppHandle, volume f32) Result~()~
    +rodio_get_volume(app AppHandle) Result~f32~
  }

  class RodioPlayerStub {
    <<struct>>
  }

  class RodioPlayer {
    <<struct>>
    +new() RodioPlayer
  }

  class tauri_plugin_audioplayer {
    <<plugin>>
    +AudioplayerExt
    +MprisPlayerDetails
  }

  RodioModuleDesktop --> RodioPlayer : desktop
  RodioModuleMobile --> RodioPlayerStub : mobile stub
  RodioModuleMobile --> tauri_plugin_audioplayer : audio handled by plugin
Loading

File-Level Changes

Change Details Files
Restructured GitHub CI workflow to support per-arch desktop builds, Android APK builds, and macOS x64 cross-compilation from Linux with refined caching and artifact handling.
  • Changed workflow input platform choices to explicit arch-specific variants (linux-x64, linux-arm64, macos-arm64, windows-x64) and updated matrix expansion logic accordingly
  • Switched Bazel setup action to a fork with configurable disk/repository cache usage and disabled Android SDK cleanup while adding manual swap space setup on Ubuntu runners
  • Simplified Linux dependency installation by dropping cache-apt action, adding linker/clang packages, and adjusting ARM-only dependencies
  • Tweaked Bazel build step to pass PATH via action_env and clear Android env vars on ARM runners lacking SDK
  • Split Linux artifact upload into separate RPM/DEB/AppImage artifacts, kept non-Linux as a single artifact, and appended new steps to build/upload Android arm64/x86_64 APKs plus cross-compiled macOS x64 zip from Linux
.github/workflows/build.yaml
Reworked Android Gradle integration to use Bazel-built shared library and auto-discovered Tauri/ plugin Android sources instead of cargo-based Tauri CLI, and wired up APK projects to use plugin modules.
  • Replaced BuildTask to invoke Bazel on a rust_shared_library target per-ABI, copy the resulting libapp_lib.so into jniLibs, copy UI assets from Bazel UI gen_dist output, generate Kotlin glue code and Proguard rules from external tauri/wry crates, and support a skipBazel flag for Java-only rebuilds
  • Added Gradle settings logic in the main Android project and each plugin Android project to resolve Bazel output_base, locate tauri crate and plugin Android code in either local lib/ or external/, and include them as Gradle modules
  • Adjusted Android app Gradle config to point rust.rootDirRel one level higher, register jniLibs source dir, and explicitly depend on tauri-android and the plugin projects instead of applying tauri build scripts
  • Updated RustPlugin Kotlin Gradle plugin to drop legacy x86/i686 ABI targets and only build arm64-v8a, armeabi-v7a, and x86_64
  • Enabled AndroidX via gradle.properties in plugin Android projects
tauri/gen/android/buildSrc/src/main/java/app/moosync/moosync/kotlin/BuildTask.kt
tauri/gen/android/settings.gradle
tauri/gen/android/app/build.gradle.kts
tauri/gen/android/buildSrc/src/main/java/app/moosync/moosync/kotlin/RustPlugin.kt
lib/tauri-plugin-audioplayer/android/settings.gradle
lib/tauri-plugin-file-scanner/android/settings.gradle
lib/tauri-plugin-self-update/android/settings.gradle
Introduced Bazel module, toolchain, and extension machinery for Android NDK optionality and Linux-to-macOS cross-compilation using rules_applecross and patched foreign_cc consumers (ffmpeg, openssl, ogg, opus, vorbis, lame).
  • Updated MODULE.bazel dependencies (protobuf, rules_python, aspect_rules_js, rules_cc) and registered preinstalled toolchains for foreign_cc plus new Bazel module includes for apple-cross, Android rules, and tauri crate discovery via a custom module_extension
  • Added android_ndk_optional module extension that wraps rules_android_ndk to provide a stub androidndk repo when no NDK is installed, and registered its toolchains
  • Defined Android and Darwin platform targets under toolchains/, and introduced a target_os build setting with config_settings for android/linux/windows/macos selection used by select()s
  • Patched external ffmpeg, openssl, ogg, opus, vorbis, and lame builds to be position-independent, cross-compile-aware on macOS via apple-cross toolchain files, and to invoke a custom darwin ar wrapper and SDK env; added minor config hacks (e.g., closesocket detection for ffmpeg)
  • Added Apple-specific helper scripts and BUILD glue (darwin_ar_wrapper.sh, bindgen_clang_wrapper.sh, darwin_cc_wrapper.sh, apple_sdk_ref alias) plus patches to rules_applecross and related repos, along with a GitHub workflow to package and upload an Apple SDK archive as a release asset
MODULE.bazel
modules/apple_cross.MODULE.bazel
modules/external_deps.MODULE.bazel
modules/rust_toolchains.MODULE.bazel
modules/crates.MODULE.bazel
modules/wasm_crates.MODULE.bazel
toolchains/BUILD
toolchains/android/BUILD
toolchains/darwin/BUILD
tools/BUILD
tools/settings.bzl
tools/android_ndk_optional.bzl
tools/darwin_ar_wrapper.sh
tools/bindgen_clang_wrapper.sh
tools/darwin_cc_wrapper.sh
external/ffmpeg/BUILD
external/openssl/BUILD
external/ogg/BUILD
external/opus/BUILD
external/vorbis/BUILD
external/lame/BUILD
patches/BUILD
patches/*.patch
.github/workflows/package-apple-sdk.yaml
Refactored tauri Rust targets and plugins to support Android shared-library builds, Android-targeted build scripts, and platform-conditional dependencies (rodio/mpris/file-scanner/self-update).
  • Extended tauri/BUILD with a rust_shared_library target moosync_android that builds app_lib for Android with proper link flags, wired its dependencies, and added semver plus target_os-based conditional inclusion of core/rodio_player and tauri crate sources in build scripts when targeting android
  • Updated plugin BUILD.bazel files to expose android_sources filegroups and feed tauri Android library paths into build script env/data via the tauri_android_sources copy_to_directory target, so build.rs can locate Java/Kotlin code under Bazel
  • Adjusted core mpris and file_scanner Rust libs to add Android-specific modules (mpris_android.rs, scanner_android.rs), switch to plugin-provided MprisPlayerDetails and songs_proto types on Android, and select different deps per-platform (e.g., tauri plugin + serde_json for Android vs souvlaki/windows on desktop)
  • Introduced mobile stubs for rodio commands in tauri/src/rodio/mod.rs to no-op on mobile while keeping desktop implementations behind cfg(desktop)
  • Added an android_entry.rs shim re-exporting app_lib::run as the Android cdylib entry point
tauri/BUILD
tauri/src/android_entry.rs
tauri/src/rodio/mod.rs
core/mpris/BUILD
core/mpris/src/lib.rs
core/mpris/src/mpris_android.rs
core/file_scanner/BUILD
core/file_scanner/src/scanner_android.rs
lib/tauri-plugin-audioplayer/BUILD.bazel
lib/tauri-plugin-audioplayer/src/lib.rs
lib/tauri-plugin-file-scanner/BUILD.bazel
lib/tauri-plugin-self-update/BUILD.bazel
Improved rodio-based audio playback to consistently resample to the system output sample rate, with PulseAudio/PipeWire integration on Linux and diagnostic logging.
  • Changed FFMPEGDecoder to always use a SwrContext for both sample format and sample rate conversion, store output_sample_rate and return that via Source::sample_rate, and removed the planar/format-only branch; added one-time channel/sample-rate logging
  • Extended core rodio_player crate to query a system-preferred sample rate via PulseAudio on Linux (using new pulse_monitor module) or cpal defaults elsewhere, and to open the rodio sink with that rate via DeviceSinkBuilder::with_sample_rate, logging the resulting stream config
  • Adjusted RodioPlayer::set_src/open to pass the chosen output sample rate into FFMPEGDecoder, and conditionally depend on libpulse-binding and PulseAudio monitor module only on Linux
  • Annotated TODOs for future dynamic sample-rate switching and FFmpeg shared-library bundling in dedicated markdown docs
core/rodio_player/src/decoder.rs
core/rodio_player/src/lib.rs
core/rodio_player/BUILD
core/rodio_player/src/pulse_monitor.rs
TODO/DYNAMIC_SAMPLE_RATE_SWITCHING.md
TODO/FFMPEG_BUNDLED_SHARED_LIBS.md
Miscellaneous quality-of-life and robustness improvements across UI, database build, Bazel tooling, and documentation.
  • Made Leptos UI theme initialization resilient to missing storage keys by checking Result/serde errors before applying theme
  • Fixed Android x86_64 database build script to use ANDROID_NDK_HOME instead of deprecated NDK_HOME
  • Corrected bazel Rust protos generator to use transitive_sources instead of transitive_imports, ensuring all proto files are considered
  • Added local dev helper scripts to install/uninstall dev binaries as symlinks, local CI and Android/Tauri design TODO docs, a project workspace file, and CLAUDE.md for assistant context
  • Tweaked various gitignore, Bazel, and Gradle metadata files and removed obsolete Android workflow and Gradle cache artifacts
ui/leptos/src/app.rs
core/database/build.rs
tools/rust/cargo_gen.bzl
tools/install-dev.sh
tools/uninstall-dev.sh
TODO/LOCAL_CI_EMULATION.md
TODO/ANDROID_PLUGIN_ACTIVITY_HOOKS.md
TODO/ANDROID_PROTOBUF_REFACTOR.md
TODO/INDEX.md
CLAUDE.md
.github/workflows/android.yaml
misc config and ignore files

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • There are multiple eprintln! debug prints added in the audio path (FFMPEGDecoder and RodioPlayer, e.g. >>> RODIO PLAYER BUILD TEST 1 <<< and channel/sample_rate logs); consider gating these behind a feature flag, log level, or tracing so they don’t spam output in normal runs.
  • The macOS cross-compile setup hardcodes specific Xcode/SDK paths and versions (e.g. MacOSX15.5.sdk, Xcode.app/Contents/Developer in several BUILD files and shell wrappers); it would be more robust to centralize this in one place or derive it from a small set of configurable variables to ease upgrades and local deviations.
  • The Gradle settings for locating bazelOutputBase and tauri-android are duplicated across multiple settings.gradle files (app and several plugins); consider extracting this discovery logic into a shared Gradle script or function to avoid divergence and simplify future changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- There are multiple `eprintln!` debug prints added in the audio path (FFMPEGDecoder and RodioPlayer, e.g. `>>> RODIO PLAYER BUILD TEST 1 <<<` and channel/sample_rate logs); consider gating these behind a feature flag, log level, or `tracing` so they don’t spam output in normal runs.
- The macOS cross-compile setup hardcodes specific Xcode/SDK paths and versions (e.g. `MacOSX15.5.sdk`, `Xcode.app/Contents/Developer` in several BUILD files and shell wrappers); it would be more robust to centralize this in one place or derive it from a small set of configurable variables to ease upgrades and local deviations.
- The Gradle settings for locating `bazelOutputBase` and `tauri-android` are duplicated across multiple `settings.gradle` files (app and several plugins); consider extracting this discovery logic into a shared Gradle script or function to avoid divergence and simplify future changes.

## Individual Comments

### Comment 1
<location path="core/rodio_player/src/decoder.rs" line_range="281-286" />
<code_context>
     #[inline]
     fn channels(&self) -> ChannelCount {
-        NonZero::new(self.codec_ctx.ch_layout.nb_channels as u16).unwrap()
+        static CH_LOGGED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
+        let ch = self.codec_ctx.ch_layout.nb_channels as u16;
+        if !CH_LOGGED.swap(true, std::sync::atomic::Ordering::Relaxed) {
+            eprintln!(">>> SOURCE: channels={}, sample_rate={}", ch, self.output_sample_rate);
+        }
+        NonZero::new(ch).unwrap()
     }

</code_context>
<issue_to_address>
**issue (bug_risk):** Move the `CH_LOGGED` static out of the `channels` method into module scope

This won’t compile because Rust doesn’t allow `static` items inside functions. Instead, declare `static CH_LOGGED: AtomicBool = AtomicBool::new(false);` at module scope (e.g., near the top of `decoder.rs`) and use it from `channels()` to preserve the one-time logging behavior.
</issue_to_address>

### Comment 2
<location path="core/rodio_player/src/lib.rs" line_range="90-94" />
<code_context>
 impl RodioPlayer {
     #[tracing::instrument(level = "debug", skip())]
     pub fn new() -> Self {
+        eprintln!(">>> RODIO PLAYER BUILD TEST 1 <<<");
         let (events_tx, events_rx) = channel::<PlayerEvent>();
         let tx = Self::initialize(events_tx);
</code_context>
<issue_to_address>
**suggestion:** Drop or gate the hard‑coded debug `eprintln!` in `RodioPlayer::new`

This unconditional `eprintln!` will fire on every player construction and clutter user output/logs. If you still need it, please gate it with a feature flag or `cfg!(debug_assertions)`, or remove it before merging.

```suggestion
    #[tracing::instrument(level = "debug", skip())]
    pub fn new() -> Self {
        if cfg!(debug_assertions) {
            eprintln!(">>> RODIO PLAYER BUILD TEST 1 <<<");
        }
        let (events_tx, events_rx) = channel::<PlayerEvent>();
        let tx = Self::initialize(events_tx);
```
</issue_to_address>

### Comment 3
<location path="tools/tauri_crate.bzl" line_range="11-13" />
<code_context>
+            idx = line.find(marker)
+            if idx == -1:
+                continue
+            remainder = line[idx + len(marker):]
+            version_chars = []
+            for c in remainder.elems():
+                if c.isdigit() or c == ".":
+                    version_chars.append(c)
</code_context>
<issue_to_address>
**issue (bug_risk):** Replace the Python‑style `.elems()` usage with valid Starlark string iteration

Starlark strings are directly iterable and don’t support `.elems()`, so this will fail at analysis time. Iterate with `for c in remainder:` instead; the rest of the logic can stay the same.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

common --enable_platform_specific_config

# Android NDK path (inherit from environment, or set in .bazelrc.user)
common --repo_env=ANDROID_NDK_HOME
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First here

"@rules_foreign_cc//toolchains:preinstalled_autoconf_toolchain",
"@rules_foreign_cc//toolchains:preinstalled_automake_toolchain",
"@rules_foreign_cc//toolchains:preinstalled_m4_toolchain",
"@rules_foreign_cc//toolchains:preinstalled_pkgconfig_toolchain",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep these as hermetic? Sort of defeats the purpose of using bazel

},
crate = "openssl-sys",
)
# NOTE: openssl/openssl-sys removed - using rustls instead
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Openssl is pulled regardless for ffmpeg. Is it actually better to use rustls?

"@crates//:webkit2gtk",
],
"//conditions:default": [],
"@platforms//os:android": [],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? Why no rodio on android?


// Build with Bazel (includes UI as a dependency)
val bazelArgs = mutableListOf(
"build",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gradle should not call bazel. It should be the other way around.

The point of bazel was to get rid of all other build systems calling each other

#[cfg(desktop)]
generate_command_async!(rodio_get_volume, RodioPlayer, f32,);

// Mobile stubs - rodio is not used on mobile, audio is handled by tauri-plugin-audioplayer
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plugin audio player cannot handle his streams and weird audio types. I planned on eventually getting rid of it as it was a makeshift solution.

Doesn't make sense replacing rodio completely with it

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I am informed enough to get Radio working on Android

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it compile for android and iOS? Or straight up breaks?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC it just breaks for the Android build, and this PR doesn't do anything with iOS

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll dig into this some more tomorrow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants