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

Linking against C++ STL and using it at runtime #19

Closed
Tracked by #2
MarijnS95 opened this issue May 13, 2020 · 4 comments · Fixed by #20
Closed
Tracked by #2

Linking against C++ STL and using it at runtime #19

MarijnS95 opened this issue May 13, 2020 · 4 comments · Fixed by #20

Comments

@MarijnS95
Copy link
Member

Native C++ code (in external dependencies) that utilize the STL have a hard time linking and running on-device. Dependencies usually set cpp_link_stdlib (if using the cc crate) to something sensible or leave it at the default stdc++ which only works for GNU but not Clang, requiring c++ instead. Only a single dependency needs to set it to c++ or c++_shared for the right library to be linked in and succeed the build. Leaving stdc++ in there is fine, this library is available on-device, providing only new and delete.
I assume the right course of action is to add an android case with c++ to the defaults in cc? (Or in the exceptional case, do that for all of clang? The documentation mentions this case yet does not account for it.)

As mentioned here libc++_shared is not available on Android devices - it needs to be bundled with the APK. Builds link against c++_static by default and have no runtime dependencies, but aforementioned native projects would force linking against c++.

A simple solution adds the path to libc++_shared.so from android_search_paths to artifacts in readelf.rs, if it is found in the needed libs (like this - forgive the awful code and duplication from a Rust novice). A more sophisticated implementation would provide the option to choose between none, static or runtime STL (including the file for the latter) and clean up linker flags to accommodate this choice.

Any suggestions going forward? I'm willing to take this onwards but am not sure how to proceed.

@dvc94ch
Copy link
Contributor

dvc94ch commented May 14, 2020

Looks good. I think you can turn it into a one liner:

let search_path = if c++ { android_search_path } else { search_path }

@MarijnS95
Copy link
Member Author

@dvc94ch That would be a nice solution, but android_search_path and search_path are different types (Vec and slice, containing a PathBuf and Path respectively), requiring normalization to the arguments. Luckily this is rather simple, as PathBuf Derefs or Borrows into a Path.

Furthermore, this specific library needs to be excluded from the provided list, or not checked when it comes across.

Would this work for you?

As for the other points: should I bring the default lib issue up over at cc-rs? Is there anything android-ndk-rs can (and should) do about linking shared or static STL?

@dvc94ch
Copy link
Contributor

dvc94ch commented May 14, 2020

Looks good, if you PR that, I'll merge it. Don't know how common it is to only use new and delete. If you need that for your project, you can make a suggestion, but I'd rather not add features no one is using.

@MarijnS95
Copy link
Member Author

Don't know how common it is to only use new and delete. If you need that for your project, you can make a suggestion, but I'd rather not add features no one is using.

It is not so much about the barebones stdc++, rather about linking static vs dynamic. Fortunately static is selected by default even when -lstdc++ is provided to the compiler (leading to little to no errors), but it would still be advantageous to be able to toggle the shared runtime at least somewhere. This is commonly used as space-saving measure as the shared STL is about 6MB. I did however not manage to get it to ignore the static STL in some limited testing, and need the shared STL regardless for a stray ndk::mutex pulled in by some external dependency. I'll update this whenever I have the need to continue it, but will leave it for now as everything works correctly.

Thanks for accepting the patches thus far!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants