Bug 15394 - Native armeabi library not installed to `data/app-lib/` when using shared Mono runtime on armeabi-v7a device
Summary: Native armeabi library not installed to `data/app-lib/` when using shared Mon...
Status: RESOLVED INVALID
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.8.x
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2013-10-14 18:53 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2014-08-21 10:38 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED INVALID

Description Brendan Zagaeski (Xamarin Team, assistant) 2013-10-14 18:53:12 UTC
Reported on behalf of a user.

## Steps to reproduce

1. Open attached test case.
2. Build the "M2.Mobile.Android" project, and run it on an armeabi-v7a device or emulator.
3. Push the "Entrar" button.


## Result

The application throws an error:
Couldn't load clisitef32 from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/M2.Mobile.Android-1.apk"],nativeLibraryDirectories=[/data/app-lib/M2.Mobile.Android-1, /system/lib]]]: findLibrary returned null


Running `unzip -l M2.Mobile.Android.apk` shows that the library is present in the APK:
> lib/armeabi/libclisitef32.so


... but running `adb shell ls /data/app-lib/M2.Mobile.Android-1` shows only the mono libraries:
> libmono-profiler-log.so
> libmonodroid.so


## Workaround

1. Disable "Use shared Mono runtime" in "Project Options -> Android Build -> Packaging".
2. Select "armeabi" under "Project Options -> Android Build -> Advanced".
3. Build and run the "M2.Mobile.Android" project.


## Additional information

- Deploying to an armeabi emulator appears to work correctly even when "Use shared Mono runtime" and "Fast assembly deployment" are both enabled. 

- With "Fast assembly deployment" disabled and "Use shared Mono runtime" enabled, `libclisitef32.so` installs correctly, but not `libjCliSiTefI.so`. Interestingly, if you rename `libjCliSiTefI.so` (for example to `libjclisitef.so`), the library *does* get installed into `/data/app-lib/M2.Mobile.Android-1/`. If you then rename the library on-device back to `libjCliSiTefI.so` using `adb shell mv`, the application runs without error.

- After nulling-out the .so files, the installation behavior appears to stay the same. So the problem does not seem to depend on the contents of the native libraries.

- Moving the .so files out of the binding project and into the "M2.Mobile.Android" project does not change the installation behavior either.


## Version information
Xamarin.Android 4.8.3
Comment 2 Jonathan Pryor 2013-10-14 22:46:36 UTC
This is an unfortunate Android design decision. Some (slightly outdated) information is at:

http://docs.xamarin.com/guides/android/advanced_topics/cpu_architecture#1.3.android-native-library-installation

The problem is that on a number of Android versions, if your .apk contains _both_ armeabi and armeabi-v7a libraries, _only_ the armeabi-v7a libraries will be extracted onto armeabi-v7a targets.

Furthermore, since Mono for Android 4.4 a libmonodroid.so has been provided in Debug builds, by default, for armeabi, armeabi-v7a, and x86 architectures, and since Xamarin.Android 4.6 the default architecture for Release builds has been armeabi-v7a.

Your project only includes armeabi libraries.

Consequently, on many (most) Android versions, _only_ the armeabi-v7a libraries will be installed, and the armeabi libraries will be IGNORED.

This in turn will result in runtime errors when attempting to load the native library which doesn't exist.

The "fix" is to provide copies of your native libraries for each ABI that you need to support, and you'll need to support _at least_ armeabi-v7a. Your project is only including armeabi.

You can do this via one of three ways:

1. Copy the lib\armeabi\lib*.so into lib\armeabi-v7a\lib*.so, and set the Build action accordingly (EmbeddedNativeLibrary for binding projects, AndroidNativeLibrary for app projects).

2. Use MSBuild properties to add it as an alias, e.g.

    <EmbeddedNativeLibrary Include="lib\armeabi\libwhatever.so">
      <Link>lib\armeabi-v7a\libwhatever.so</Link>
    </EmbeddedNativeLibrary>

3. Set the <Abi/> nested element on <AndroidNativeLibrary/>:

http://docs.xamarin.com/guides/android/advanced_topics/build_process#2.9.native-library-support

Note: I don't know if the nested <Abi/> element works for <EmbeddedNativeLibrary/>.
Comment 3 Alexandre Rocha Lima e Marcondes 2014-08-21 10:38:04 UTC
Just complementing Jonathan Pryor message. There is a bug report about this issue that can be tracked:

https://code.google.com/p/android/issues/detail?id=65253