# Cross-Platform Considerations in Universal Android Debloater: Windows vs. Linux Support

> Explore cross-platform considerations for Universal Android Debloater Next Generation. Learn how Rust conditional compilation ensures seamless Windows vs Linux support for features like console attachment and self-updates.

- Repository: [Universal-Debloater-Alliance/universal-android-debloater-next-generation](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation)
- Tags: architecture
- Published: 2026-06-20

---

**The Universal Android Debloater Next Generation (UAD-NG) handles cross-platform considerations through Rust's conditional compilation attributes (`#[cfg]`), isolating platform-specific code for console attachment, font rendering, binary naming, and self-update workflows while maintaining a single shared codebase.**

UAD-NG is a Rust-based GUI application for managing Android packages that must run natively on both Windows and Linux. The codebase deliberately isolates platform-dependent behavior behind `#[cfg(target_os = "...")]` attributes to ensure clean builds without code duplication. This approach allows the application to handle Windows-specific console attachment, Linux-specific font defaults, and divergent self-update mechanisms while preserving a unified architecture across all supported platforms.

## Console Logging and Windows Subsystem Configuration

When UAD-NG is built for Windows with `windows_subsystem = "windows"` in the manifest, the process launches without an attached console, preventing log output from appearing in terminal windows. To address this cross-platform consideration, the codebase includes a Windows-specific function that reattaches to the parent console.

In [`crates/uad-gui/src/main.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-gui/src/main.rs) (lines 90-100), the `attach_windows_console()` function uses the `win32console` crate to bind the process to the parent console:

```rust
#[cfg(target_os = "windows")]
fn attach_windows_console() {
    use win32console::console::WinConsole;
    const ATTACH_PARENT_PROCESS: u32 = 0xFFFFFFFF;
    let _ = WinConsole::attach_console(ATTACH_PARENT_PROCESS);
}

```

On Linux, no additional work is required because the process maintains its terminal attachment by default. The `#[cfg(target_os = "windows")]` guard ensures this code—and the `win32console` dependency—is completely omitted from Linux builds.

## Default Font Handling for Linux Desktop Environments

Linux desktop environments often exhibit glyph clipping or rendering issues with the default font selection in the Iced GUI toolkit. To ensure consistent text rendering across distributions, UAD-NG sets a Linux-specific default font.

In [`crates/uad-gui/src/gui.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-gui/src/gui.rs) (lines 53-60), the application configures **Adwaita Sans** specifically when compiling for Linux:

```rust
#[cfg(target_os = "linux")]
default_font: iced::Font {
    family: iced::font::Family::Name("Adwaita Sans"),
    ..Default::default()
},

```

The Windows build does not override the default font, allowing the Iced toolkit to select the appropriate system font automatically.

## Binary Naming and Self-Update Architecture

The self-update mechanism must identify the correct binary name for each platform, as Windows executables require the `.exe` extension while Linux binaries use no extension.

In [`crates/uad-core/src/update.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-core/src/update.rs) (lines 27-48), the `BIN_NAME` constant uses conditional compilation to select the appropriate filename:

```rust
pub const BIN_NAME: &str = {
    #[cfg(target_os = "windows")]
    { "uad-ng-windows.exe" }

    #[cfg(not(any(target_os = "macos", target_os = "windows")))]
    { "uad-ng-linux" }
    
    // macOS variants omitted for brevity
};

```

This constant drives the entire self-update workflow, ensuring the updater requests the correct asset from the release repository regardless of the host platform.

## Platform-Specific Download and Extraction Flows

The cross-platform considerations extend to how updates are packaged and extracted. Windows releases are distributed as raw binaries, while Linux releases are compressed as gzip-compressed tarballs (`.tar.gz`).

In [`crates/uad-core/src/update.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-core/src/update.rs), the download logic branches based on the target OS:

**Linux extraction flow:**

```rust
#[cfg(not(target_os = "windows"))] {
    let asset_name = format!("{bin_name}.tar.gz");
    // ... download tarball ...
    extract_binary_from_tar(&archive_path, &bin_path)?;
    // Set executable permissions
    let mut perms = fs::metadata(&bin_path)?.permissions();
    perms.set_mode(0o755);
    fs::set_permissions(&bin_path, perms)?;
}

```

**Windows direct download:**

```rust
#[cfg(target_os = "windows")] {
    let asset = release.assets.iter()
        .find(|a| a.name == bin_name)
        .unwrap();
    // ... copy directly to download_path ...
}

```

The Linux path requires additional steps to extract the binary from the archive and set executable permissions (`chmod 0o755`), while the Windows path performs a direct file copy.

## Dependency Isolation and Conditional Imports

To prevent Windows-only crates from complicating Linux builds, UAD-NG isolates the `win32console` dependency using conditional compilation.

In [`Cargo.toml`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/Cargo.toml), the dependency is declared in the workspace, but in [`crates/uad-gui/src/main.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-gui/src/main.rs), the import is guarded:

```rust
#[cfg(target_os = "windows")]
use win32console::console::WinConsole;

```

This ensures that when compiling for Linux, the build system never pulls in or links against Windows-specific libraries, keeping the Linux binary size smaller and eliminating potential cross-compilation issues.

## Summary

- **Console attachment**: Uses `#[cfg(target_os = "windows")]` to conditionally compile the `attach_windows_console()` function in [`crates/uad-gui/src/main.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-gui/src/main.rs), utilizing the `win32console` crate only on Windows.
- **Font rendering**: Sets **Adwaita Sans** as the default font specifically for Linux in [`crates/uad-gui/src/gui.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-gui/src/gui.rs) to prevent glyph clipping.
- **Binary identification**: Defines platform-specific names (`uad-ng-windows.exe` vs `uad-ng-linux`) in [`crates/uad-core/src/update.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-core/src/update.rs) using conditional compilation.
- **Update extraction**: Handles Linux tar.gz archives with `extract_binary_from_tar` and permission setting (`chmod 0o755`), while Windows receives direct binary downloads.
- **Dependency management**: Isolates Windows-only crates like `win32console` behind `#[cfg]` attributes to ensure clean Linux builds.

## Frequently Asked Questions

### How does UAD-NG handle console output on Windows when using the GUI subsystem?

When compiled with `windows_subsystem = "windows"`, the application launches without an attached console. The `attach_windows_console()` function in [`crates/uad-gui/src/main.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-gui/src/main.rs) calls `win32console::console::WinConsole::attach_console` with `ATTACH_PARENT_PROCESS` to bind to the parent console, enabling log output in terminal windows. This function is wrapped in `#[cfg(target_os = "windows")]` so it compiles only for Windows targets.

### Why does the Linux version require a specific font configuration?

Linux desktop environments may clip glyphs or render text incorrectly with the generic default font. In [`crates/uad-gui/src/gui.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-gui/src/gui.rs), the code sets the default font to **Adwaita Sans** specifically when the `#[cfg(target_os = "linux")]` conditional is active, ensuring proper text rendering across different distributions and desktop environments.

### How does the self-update mechanism differ between Windows and Linux?

Windows downloads a raw binary file (`uad-ng-windows.exe`) directly, while Linux downloads a gzip-compressed tarball (`uad-ng-linux.tar.gz`). The Linux path requires extraction via `extract_binary_from_tar` and setting executable permissions with `chmod 0o755`, whereas the Windows path copies the binary directly to the target location. Both paths use the platform-specific `BIN_NAME` constant defined in [`crates/uad-core/src/update.rs`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/crates/uad-core/src/update.rs) to identify the correct asset.

### Are Windows-specific dependencies included when building on Linux?

No. The `win32console` crate is declared in [`Cargo.toml`](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/Cargo.toml) but is only imported and linked when the target OS is Windows, using `#[cfg(target_os = "windows")]` guards around the import statement and usage code. This ensures Linux builds remain free of Windows-specific libraries and dependencies.