Skip to content

Commit 318dd7e

Browse files
dellis1972jonpryor
authored andcommitted
[Xamarin.Android.Build.Tasks] No .dll's in Release if Optimize != True (#749)
Context: https://bugzilla.xamarin.com/show_bug.cgi?id=58580 Unable to locate assemblies when running projects when `$(Configuration)`=Release and `$(Optimize)` != True. Commit edabe8a reworked the build logic so that `$(Optimize)` controls the deployment of the debug or release runtimes. Input Property: || Output Property DebugSymbols | DebugType | EmbedAssembliesIntoApk | Optimize || AndroidIncludeDebugSymbols ================+============+==========================+============++=========================== True *any* True True False (Release runtime) True *any* True False True (Debug runtime) True *any* False True True (Debug runtime) True *any* False False True (Debug runtime) True *empty* True True True (Debug runtime) True *empty* True False True (Debug runtime) True *empty* False True True (Debug runtime) True *empty* False False True (Debug runtime) False - - - False (Release runtime) *empty* *any* *empty* False True (Debug runtime) In this scenario, `$(DebugSymols)` and `$(EmbedAssembliesIntoApk)` are both empty. As a result `$(EmbedAssembliesIntoApk)` gets a default value of 'False'. But because `$(DebugSymols)` is empty we fall through the MSBuild case statement and end up with `$(AndroidIncludeDebugSymbols)` = `True`. Which is NOT what we want in this case. So if `$(EmbedAssembliesIntoApk)` we should always default `$(AndroidIncludeDebugSymbols)` to false. In addition there was a weird issue with the way we install debug apps. If the app is using the Shared Runtime the deployment process sends a broadcast to the Shared Runtime app which returns the external storage directory. This tends to be something like /mnt/shell/emulated/0/ So when we deploy our debug assemblies we do so to a directory like /mnt/shell/emulated/0/Android/data/$(PackageName)/files/.__override__ This works as expected. Now if we try to debug an app without using the Shared Runtime it will work as expected.. unless the Shared Runtime was not installed. In this case the broadcast fails and we fall back to getting the external storage using adb shell echo -b ${EXTERNAL_STORAGE} This returns /mnt/shell/emulated/legacy so we end up deploying the debug assemblies to /mnt/shell/emulated/legacy/Android/data/$(PackageName)/files/.__override__ So all is well and good. However problems start in our runtime and the MonoPackageManager. We use android.os.Environment.getExternalStorageDirectory (); to get the external storage directory. In this case it ALWAYS returns /mnt/shell/emulated/0/ So if we are debugging without the Shared Runtime being installed, we will NEVER find the fast deployed assebmies. So the app will crash. The fix in this case is to check both directories when we are running the debug runtime.
1 parent 993f540 commit 318dd7e

File tree

6 files changed

+42
-13
lines changed

6 files changed

+42
-13
lines changed

src/Mono.Android/java/mono/android/Runtime.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ private Runtime ()
66
{
77
}
88

9-
public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, ClassLoader loader, String externalStorageDir, String[] assemblies, String packageName);
9+
public static native void init (String lang, String[] runtimeApks, String runtimeDataDir, String[] appDirs, ClassLoader loader, String[] externalStorageDirs, String[] assemblies, String packageName);
1010
public static native void register (String managedType, java.lang.Class nativeClass, String methods);
1111
public static native void notifyTimeZoneChanged ();
1212
public static native int createNewContext (String[] runtimeApks, String[] assemblies, ClassLoader loader);

src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.api4.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack
3838
String cacheDir = context.getCacheDir ().getAbsolutePath ();
3939
String dataDir = context.getApplicationInfo ().dataDir + "/lib";
4040
ClassLoader loader = context.getClassLoader ();
41+
java.io.File external0 = android.os.Environment.getExternalStorageDirectory ();
42+
String externalDir = new java.io.File (
43+
external0,
44+
"Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath ();
45+
String externalLegacyDir = new java.io.File (
46+
external0,
47+
"../legacy/Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath ();
4148

4249
Runtime.init (
4350
language,
@@ -49,9 +56,10 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack
4956
dataDir,
5057
},
5158
loader,
52-
new java.io.File (
53-
android.os.Environment.getExternalStorageDirectory (),
54-
"Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (),
59+
new String[] {
60+
externalDir,
61+
externalLegacyDir
62+
},
5563
MonoPackageManager_Resources.Assemblies,
5664
context.getPackageName ());
5765

src/Xamarin.Android.Build.Tasks/Resources/MonoPackageManager.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack
3838
String cacheDir = context.getCacheDir ().getAbsolutePath ();
3939
String dataDir = getNativeLibraryPath (context);
4040
ClassLoader loader = context.getClassLoader ();
41+
java.io.File external0 = android.os.Environment.getExternalStorageDirectory ();
42+
String externalDir = new java.io.File (
43+
external0,
44+
"Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath ();
45+
String externalLegacyDir = new java.io.File (
46+
external0,
47+
"../legacy/Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath ();
4148

4249
Runtime.init (
4350
language,
@@ -49,9 +56,10 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack
4956
dataDir,
5057
},
5158
loader,
52-
new java.io.File (
53-
android.os.Environment.getExternalStorageDirectory (),
54-
"Android/data/" + context.getPackageName () + "/files/.__override__").getAbsolutePath (),
59+
new String[] {
60+
externalDir,
61+
externalLegacyDir
62+
},
5563
MonoPackageManager_Resources.Assemblies,
5664
context.getPackageName ());
5765

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
279279
<AndroidIncludeDebugSymbols>True</AndroidIncludeDebugSymbols>
280280
</PropertyGroup>
281281
</When>
282+
<When Condition=" '$(EmbedAssembliesIntoApk)' == 'False' ">
283+
<PropertyGroup>
284+
<AndroidIncludeDebugSymbols>True</AndroidIncludeDebugSymbols>
285+
</PropertyGroup>
286+
</When>
282287
<Otherwise>
283288
<PropertyGroup>
284289
<AndroidIncludeDebugSymbols>False</AndroidIncludeDebugSymbols>

src/monodroid/jni/mono_android_Runtime.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/monodroid/jni/monodroid-glue.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ monodroid_get_system_property (const char *name, char **value)
329329
#ifdef RELEASE
330330
#define MAX_OVERRIDES 1
331331
#else
332-
#define MAX_OVERRIDES 2
332+
#define MAX_OVERRIDES 3
333333
#endif
334334
static char* override_dirs [MAX_OVERRIDES];
335335

@@ -410,6 +410,7 @@ get_primary_override_dir (JNIEnv *env, jstring home)
410410

411411
static char *primary_override_dir;
412412
static char *external_override_dir;
413+
static char *external_legacy_override_dir;
413414

414415
static void
415416
create_update_dir (char *override_dir)
@@ -651,6 +652,7 @@ get_libmonosgen_path ()
651652
// external storage locations so we need to file copy the shared object to an internal
652653
// storage location before loading it.
653654
copy_monosgen_to_internal_location (primary_override_dir, external_override_dir);
655+
copy_monosgen_to_internal_location (primary_override_dir, external_legacy_override_dir);
654656

655657
int i;
656658
for (i = 0; i < MAX_OVERRIDES; ++i)
@@ -2512,6 +2514,7 @@ get_ds2_path ()
25122514
for (i = 0; i < sizeof (gdbservers)/sizeof (gdbservers [0]); ++i) {
25132515
file = monodroid_strdup_printf ("%s", gdbservers [i]);
25142516
copy_file_to_internal_location (primary_override_dir, external_override_dir, file);
2517+
copy_file_to_internal_location (primary_override_dir, external_legacy_override_dir, file);
25152518
free (file);
25162519
}
25172520

@@ -3893,7 +3896,7 @@ create_and_initialize_domain (JNIEnv* env, jobjectArray runtimeApks, jobjectArra
38933896
}
38943897

38953898
JNIEXPORT void JNICALL
3896-
Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApks, jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, jstring externalStorageDir, jobjectArray assemblies, jstring packageName)
3899+
Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApks, jstring runtimeNativeLibDir, jobjectArray appDirs, jobject loader, jobjectArray externalStorageDirs, jobjectArray assemblies, jstring packageName)
38973900
{
38983901
char *runtime_args = NULL;
38993902
char *connect_args;
@@ -3923,9 +3926,13 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject
39233926
setup_environment (env, runtimeApks);
39243927

39253928
primary_override_dir = get_primary_override_dir (env, (*env)->GetObjectArrayElement (env, appDirs, 0));
3926-
esd = (*env)->GetStringUTFChars (env, externalStorageDir, NULL);
3929+
esd = (*env)->GetStringUTFChars (env, (*env)->GetObjectArrayElement (env, externalStorageDirs, 0), NULL);
39273930
external_override_dir = monodroid_strdup_printf ("%s", esd);
3928-
(*env)->ReleaseStringUTFChars (env, externalStorageDir, esd);
3931+
(*env)->ReleaseStringUTFChars (env, (*env)->GetObjectArrayElement (env, externalStorageDirs, 0), esd);
3932+
3933+
esd = (*env)->GetStringUTFChars (env, (*env)->GetObjectArrayElement (env, externalStorageDirs, 1), NULL);
3934+
external_legacy_override_dir = monodroid_strdup_printf ("%s", esd);
3935+
(*env)->ReleaseStringUTFChars (env, (*env)->GetObjectArrayElement (env, externalStorageDirs, 1), esd);
39293936

39303937
init_categories (primary_override_dir);
39313938
create_update_dir (primary_override_dir);
@@ -3937,6 +3944,7 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject
39373944

39383945
#ifndef RELEASE
39393946
override_dirs [1] = external_override_dir;
3947+
override_dirs [2] = external_legacy_override_dir;
39403948
for (i = 0; i < MAX_OVERRIDES; ++i) {
39413949
const char *p = override_dirs [i];
39423950
if (!directory_exists (p))

0 commit comments

Comments
 (0)