Skip to content

Conversation

@madsmtm
Copy link
Member

@madsmtm madsmtm commented Nov 24, 2025

I strongly dislike the extra *_android.rs example files that we need in softbuffer. These are required because we have to tell Cargo to generate a cdylib with crate-type = ["cdylib"] for each example that runs on Android.

Instead of that, we can pass -Clink-arg=-shared -Clink-arg=-no-pie to rustc, together with #![no_main], which tricks the linker into thinking that the bin / executable target is actually a dynamic library.

This means that all a user of winit has to do is:

#![cfg_attr(target_os = "android", no_main)]
use winit::event_loop::EventLoop;

#[cfg(target_os = "android")]
#[no_mangle]
fn android_main(app: winit::platform::android::activity::AndroidApp) {
    use winit::platform::android::EventLoopBuilderExtAndroid;
    let mut builder = EventLoop::builder();
    builder.with_android_app(app);
    entrypoint(builder.build().unwrap())
}

#[cfg(not(target_os = "android"))]
fn main() {
    entrypoint(EventLoop::new().unwrap())
}

fn entrypoint(event_loop: EventLoop<()>) {
    todo!()
}

Which, to be fair, is still a mouthful, but it's better, and it could be reduced with macros. Have a look at this branch for trying it out in softbuffer.

Opened as a draft to show you that it's possible. I haven't polished it yet, but I'd like to know if a hack like this is something you'd be interested in before proceeding.

@madsmtm madsmtm added the enhancement New feature or request label Nov 24, 2025
@madsmtm
Copy link
Member Author

madsmtm commented Nov 24, 2025

Actually, I tested, even the #![no_main] can be avoided if you want, though I'm a bit unsure if we can rely on that? It probably depends on whether Rust is fine with the fn main being completely bypassed, which I think it is, but I'd have to check to make sure.

If it is though, then we can maybe even do some trickery in android-activity to make android_main run the _start/main function in this dylib, which, if we're fine with assigning AndroidApp to a thread local, could probably allow completely normal looking fn main()s!

@madsmtm
Copy link
Member Author

madsmtm commented Nov 24, 2025

Another option is something I discussed with @daxpedda years ago, which is that newer versions of Android seems to allow loading libraries with the executable bit set (though IIRC you may have to configure some manifest option or smth).

@MarijnS95
Copy link
Member

MarijnS95 commented Dec 5, 2025

In xbuild I've implemented exactly the last option: compile an executable, and "convert" that to a library by modifying the ELF a bit. We know all of this is possible, but cargo-apk has just been "on ice" for a few years during the "xbuild distraction".

That still resulted in some warning I have yet to resolve, but might be a viable alternative to telling the linker to produce a shared library from an executable which may in some extreme cases clash with (user-set?) compilation flags.

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants