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

Possible to work with cargo binaries? #113

Closed
swiftcoder opened this issue Jan 14, 2021 · 12 comments
Closed

Possible to work with cargo binaries? #113

swiftcoder opened this issue Jan 14, 2021 · 12 comments
Labels
status: waiting Waiting for a response or another PR

Comments

@swiftcoder
Copy link

Is it possible for ndk_glue::main to operate on binary targets? At the moment I'm having to make fake library targets for each of my binaries and example binaries, in order to get ndk_glue::main to generate the appropriate shim.

@MarijnS95
Copy link
Member

@swiftcoder I don't think so because Android expects shared libraries (cdylib) and cargo/rustc needs to know what to link the result as.

I have however seen cargo-apk-like programs adding cdylib to the build without explicitly specifying it in Cargo.toml, that is something I wish to investigate and add to cargo-apk soon! (whether those need to be lib or bin types I don't remember)

@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 14, 2021

An Android application is always a Java application. How cargo-apk works is it enables the native activity which forwards all Java events to the ndk glue. So that the rust application can be used it needs to be loaded as a cdylib from the Java VM. The reason we don't have any Java code in this repo is because the default native activity works well, and replacing it with our own Java would not yield any benefit.

@swiftcoder
Copy link
Author

Yes, I understand the technical limitation. However the end result is that it is quite inconvenient to work with android binaries in a normal rust workflow. I'm going to end up scattering dozens of empty lib.rs/main.rs around to keep both cargo run and cargo apk run happy (or, more likely, not include android examples).

In an ideal world we would be able to augment cargo apk to hook cargo behaviour a little and synthesize a cdylib crate wrapping each file with the glue macro?

@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 14, 2021

The original cargo-apk did that. It was very complex and unmaintainable. This is the sacrifice that was made to have a clean and hackable codebase that has had many contributors contribute features and improvements.

@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 14, 2021

Maybe cargo-mobile can help take care of the boilerplate? @francesca64

@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 14, 2021

Fyi I think the real problem is this rust-lang/cargo#4881

@swiftcoder
Copy link
Author

Fyi I think the real problem is this rust-lang/cargo#4881

That's definitely an issue I've run into in the past, but I'm not sure to what extent it intersects with this issue. If I have a pretty standard single-crate rust project like so:

examples/
  hello_world.rs
src/
  lib.rs
  main.rs
Cargo.toml

Then cargo treats that as if it were a library crate, plus additional anonymous crates for the main binary and each of the example binaries. Whereas cargo apk is going to treat the crate as a singular entity, and ignore the presence of binaries entirely.

I haven't been deep inside cargo - is there any way for us to get at the anonymous crates for each binary, rather than relying on the singular library crate?

@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 14, 2021

So main.rs is an entry point for desktop, you don't need that for mobile. So you should be able to use cargo run and cargo apk run by adding very little boilerplate.

The problem with the examples is that we can't select a crate type depending on the target. If we could you could use cargo apk run --example for Android and cargo run --example for desktop. But as it stands now you can only have one or the other work, by explicitly setting the crate-type for the example in the Cargo.toml

@swiftcoder
Copy link
Author

main.rs is an entry point for desktop, you don't need it on mobile

Indeed, but I want it on mobile. Main.rs contains program logic (and relies on dependencies) that aren't relevant to the library crate.

@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 14, 2021

I'll reiterate some downsides imo of the approach you're suggesting for reference and discussion:

  • more complexity and much longer compile times and an unstable api that may change at any time:
    To do this we'd have to have cargo as a dependency and mess about with it's internals

  • less flexibility:
    At the moment you can write your own glue or replace the native activity, if we hide this in cargo-apk it would be very tied to the glue implementation in this repo

  • hides how it works:
    The original cargo-apk had a lot of magic in it, making it hard to understand what it was doing and how it works

If someone comes up with a good solution I might change my mind, this is just my opinion at the moment.

@MarijnS95
Copy link
Member

Indeed, but I want it on mobile. Main.rs contains program logic (and relies on dependencies) that aren't relevant to the library crate.

You can always make a separate crate that references your library crate, and has:

...
autobins = true # The default

[lib]
path = "src/main.rs"
crate-type = ["cdylib"]

Other than that I think this issue covered all the reasoning and can be closed? Android native applications are libraries loaded by Android instead of executables and there's nothing we should hack in to change or hide that IMO - unless it's trivial.

@MarijnS95 MarijnS95 added the status: waiting Waiting for a response or another PR label May 18, 2021
@francesca64
Copy link
Contributor

@dvc94ch

Maybe cargo-mobile can help take care of the boilerplate? @francesca64

@swiftcoder

Indeed, but I want it on mobile. Main.rs contains program logic (and relies on dependencies) that aren't relevant to the library crate.

So, cargo-mobile can indeed help you generate boilerplate for pretending your lib.rs is a regular main.rs, and wrapping it as a binary on desktop platforms. I'm not sure if that's exactly what you want, and it also sounds like you want to actually have some separate logic in your main.rs, that you wouldn't want to have in your library crate at all?

It also can't currently help with your examples problem, though it's not necessarily out of scope.

@dvc94ch dvc94ch closed this as completed Feb 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting Waiting for a response or another PR
Projects
None yet
Development

No branches or pull requests

4 participants