-
Notifications
You must be signed in to change notification settings - Fork 48
Conversation
Using linker hacks.
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
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).
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.
nicoburns
commented
Dec 27, 2025
Would the following work?
[lib] crate-type = ["cdylib"] path = "./main.rs"
(I haven't managed to make it work yet)
MarijnS95
commented
Dec 28, 2025
@nicoburns that approach would "break" existing crates consisting of a library and one or more binaries, and also isn't applicable to example targets.
Over the years I've tried all these methods and while explicitly setting cdylib (plus relevant Rust code) to make sure all targets are proper shared libraries isn't the least path of resistance, its explicitness did result in the least amount of inconsistent and unexpected behaviour in the setup.
I strongly dislike the extra
*_android.rsexample files that we need insoftbuffer. These are required because we have to tell Cargo to generate acdylibwithcrate-type = ["cdylib"]for each example that runs on Android.Instead of that, we can pass
-Clink-arg=-shared -Clink-arg=-no-pietorustc, together with#![no_main], which tricks the linker into thinking that thebin/ executable target is actually a dynamic library.This means that all a user of
winithas to do is: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.