Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support building application for Android #1997

Open
sp1ritCS opened this issue Mar 9, 2025 · 21 comments
Open

Support building application for Android #1997

sp1ritCS opened this issue Mar 9, 2025 · 21 comments
Labels
enhancement New feature or request

Comments

@sp1ritCS
Copy link

sp1ritCS commented Mar 9, 2025

It should be possible to build gtk applications written in rust for the new android backend, given that the rust bindings do not use introspection at build time (sources are pregenerated).

As far as I see, there are two issues that are currently preventing this:

  1. For android, we want a "single-pass" ninja invocation to build the whole source+dependency tree, which as far as I understand isn't possible with rust, as it wants to use pkg-config to resolve the dependencies.
  2. The glue code wants to call main(int argc, char **argv, char **envp), as I doubt that rustc will expose such an entry symbol by itself, there is likely need for more glue.

My potential idea was to build the rust application as static library, as to avoid rustc doing any symbol resolving. Instead meson should take the produced static library and link it with its dependencies built from the subprojects (this has the added benefit of meson also automatically linking the glue in correctly).

@sp1ritCS sp1ritCS added the enhancement New feature or request label Mar 9, 2025
@sdroege
Copy link
Member

sdroege commented Mar 9, 2025

GStreamer is building plugins on Android (and iOS) since quite a while (using gstreamer-rs etc), but has all kinds of hacks to make this work. We did not figure out a clean way to also build Android (or iOS) apps unfortunately, but there are ideas/plans. You might want to look at GStreamer first to get an idea as most problems will also apply to GTK.

Related is also gtk-rs/gtk-rs-core#1196 gtk-rs/gir#1600 and linked issues, etc.

@sp1ritCS
Copy link
Author

sp1ritCS commented Mar 9, 2025

@sdroege I did get gstreamer itself to build on android already (for getting the Clapper media player working). Probably not the way it was intended to work (gstreamer building itself and plugins into a single shared object, instead I had to manually copy all built plugins into libdir and set GST_PLUGIN_SYSTEM_PATH_1_0 to libdir, which seemingly worked), but adding gstreamer caused the number of ninja targets to jump up from about 2500 to 10000 and this probably excludes any rust plugins as I doubt it was able to find the right compiler.

gtk-rs/gir#1600

Moved the link instruction into the build.rs, but as far as I understand there is currently no mechanism to prevent link instructions (/ pkg-config lookups) altogether, is there?

@bilelmoussaoui
Copy link
Member

Moved the link instruction into the build.rs, but as far as I understand there is currently no mechanism to prevent link instructions (/ pkg-config lookups) altogether, is there?

That is done through system-deps, in https://github.com/gtk-rs/gtk4-rs/blob/main/gtk4/sys/build.rs#L13 for example. If using that for Android is not possible, we can add a #[cfg(not(target_os = "android"))] there.

@sp1ritCS
Copy link
Author

sp1ritCS commented Mar 9, 2025

@bilelmoussaoui I'd be interested in hearing your opinion in moving the final linking stage into meson.

If using that for Android is not possible, we can add a #[cfg(not(target_os = "android"))] there.

I'd be a lot better if you could detect if the target it is building is a static library (or rlib?) and skip it based on that.

@bilelmoussaoui
Copy link
Member

@bilelmoussaoui I'd be interested in hearing your opinion in moving the final linking stage into meson.

That is up to the applications, the code in build.rs doesn't do any linking as far as I know, it just ensures the right version is available.

@sp1ritCS
Copy link
Author

the code in build.rs doesn't do any linking as far as I know, it just ensures the right version is available

It doesn't? Building gtk-rs applications do fail tho if the pkg-config packages aren't installed.

@bilelmoussaoui
Copy link
Member

As I mentioned above, that is because of the system-deps checks.

@sp1ritCS
Copy link
Author

Could these be skipped when building a static library?

@sdroege
Copy link
Member

sdroege commented Mar 10, 2025

I'm not sure what you're proposing here. Why would you want to skip the pkg-config checks at all for any target?

@sp1ritCS
Copy link
Author

I'm not sure what you're proposing here. Why would you want to skip the pkg-config checks at all for any target?

To avoid needing to install the dependencies, as the whole project+dependency tree should be built by a single ninja invocation.

@sdroege
Copy link
Member

sdroege commented Mar 10, 2025

But you would need to have those dependencies in place anyway. If you build them as part of the whole project, then e.g. meson gives you -uninstalled.pc files that can be used for that purpose.

Skipping the pkg-config files seems like a hack to work around other problems.

@sp1ritCS
Copy link
Author

sp1ritCS commented Mar 10, 2025

@sdroege The -uninstalled.pc won't work as meson considers pkg-config to not exist (which is the correct behaviour as there is no pkg-config in the NDK)

Skipping the pkg-config files seems like a hack to work around other problems.

There really is just no need for pkg-config, that's all.

I've got a working build by setting PKG_CONFIG to /bin/echo before running cargo, but that is obv. not a solution.

@sdroege
Copy link
Member

sdroege commented Mar 10, 2025

The -uninstalled.pc won't work as meson considers pkg-config to not exist (which is the correct behaviour as there is no pkg-config in the NDK)

We're using pkg-config to link the correct libraries for GStreamer (on Android and elsewhere), so simply disabling this will break things for us.

There really is just no need for pkg-config, that's all.

The only supported way to link against GLib and everything else is via pkg-config though :)

@sp1ritCS
Copy link
Author

We're using pkg-config to link the correct libraries for GStreamer (on Android and elsewhere)

GStreamer itself resolves its libraries via meson, which may (or may not) use pkg-config. Where are you explicitly using pkg-config to resolve stuff?

so simply disabling this will break things for us.

I still don't see why you'd need pkg-config when building a static library, given that this won't do any foreign "linking".

The only supported way to link against GLib and everything else is via pkg-config though :)

Its perfectly legitimate to pull in glib as a meson subproject, in which case pkg-config is not used.

@sdroege
Copy link
Member

sdroege commented Mar 10, 2025

GStreamer itself resolves its libraries via meson, which may (or may not) use pkg-config. Where are you explicitly using pkg-config to resolve stuff?

When building gst-plugins-rs

@nirbheek
Copy link

Where are you explicitly using pkg-config to resolve stuff?

When you statically link to gstreamer + plugins to create a single libgstreamer_android.so, all the dep resolution is done with pkg-config. This doesn't involve meson at all, it uses CMake inside gradle. We ship pkg-config with our "GStreamer SDK" (the official binary releases for all platforms).

When we do the same for building android apps that use Rust + GStreamer, the same mechanism will need to be used, except using Cargo + system-deps, see: gdesmott/system-deps#116. I would recommend that gtk4 do the same, otherwise you will have to reinvent everything. The proposal is completely agnostic to the project, and would work for any project that makes binary releases available.

@sp1ritCS
Copy link
Author

I was of the understanding that doing anything with pkg-config on platforms where it doesn't belong ought to be considered very hacky.

Building a gtk application on android also doesn't involve any cmake at all.

see: gdesmott/system-deps#116. I would recommend that gtk4 do the same, otherwise you will have to reinvent everything. The proposal is completely agnostic to the project, and would work for any project that makes binary releases available.

Under no circumstances would that be acceptable. There won't be any binary releases for GTK.

I'm not necessarily opposed to reinventing everything (moving final linkage into meson), which applications having to pay the price of modifying their meson scripts & entry point in order to target android. But obv. I don't want to break any existing workflows but I still don't see why gstreamer-rs needs pkg-config when building static libraries.

@nirbheek
Copy link

I was of the understanding that doing anything with pkg-config on platforms where it doesn't belong ought to be considered very hacky.
I still don't see why gstreamer-rs needs pkg-config when building static libraries.

It's not hacky at all, it's just a very convenient and (the only) declarative way to figure out dependencies of libraries. The only reason why it's not used more widely is because CMake used to have awful support for it.

Building a gtk application on android also doesn't involve any cmake at all.

But it involves Gradle, yes? If you can't consume GTK inside Android Studio then most people won't be able to build Android apps with GTK. With Gradle your options are to use plain make or cmake.

Under no circumstances would that be acceptable. There won't be any binary releases for GTK.

Well that's your choice, but in GStreamer we understand that making it easy for people to consume your project in the IDEs and development environments they use is the bare-minimum if you want people to use it.

@sp1ritCS
Copy link
Author

But it involves Gradle, yes? If you can't consume GTK inside Android Studio then most people won't be able to build Android apps with GTK.

I guess this is the main difference between gstreamer and GTK. Unlike gstreamer it isn't possible to "import gtk" into an Android project, instead you generate am Android project for your GTK application. There is no need for Android Studio for this (outside of debugging facilities), as people ought to use the IDE they are already using.

We just have the build script which builds the meson project of the application for all supported architectures in parallel, generates the application skeleton Gradle/AGP expects (developers are not expected to check those in to VCS) and copies the built/installed files to their correct locations that Gradle/AGP can bundle those into the APK.

@sdroege
Copy link
Member

sdroege commented Mar 12, 2025

That doesn't sound like great user experience, or at least nothing that would seem appealing to existing Android developers but maybe that's not your target audience.

In any case, to move forward here maybe you can make a concrete proposal that makes your approach work without breaking workflows of existing users.

Also note that you can override the pkg-config calls from system-deps and provide your own results for that via environment variables: https://docs.rs/system-deps/latest/system_deps/#overriding-build-flags

@sp1ritCS
Copy link
Author

or at least nothing that would seem appealing to existing Android developers but maybe that's not your target audience.

not a goal. Might be in the future once its possible to have generate java bindings for gi that work on android (the old one is very much abandoned and the new one depends on very new JVM features that aren't supported by ART), but definitively not right now.

Also note that you can override the pkg-config calls from system-deps and provide your own results for that via environment variables

I've tried that and it doesn't seem to work just right. I'd also preferably not have to deal with needing to set a few dozen environment variables.

maybe you can make a concrete proposal that makes your approach work without breaking workflows of existing users.

I still haven't received a satisfying answer why skipping pkg-config for static libraries breaks existing workflows. Something like SYSTEM_DEPS_SKIP_PKG_CONFIG might be fine too but I'd rather have pkg-config resolution be skipped in general for static libraries.

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

No branches or pull requests

4 participants