Xamarin support: introduce PlatformApis.isXamarin*, working NativeMethods for Xamarin.Android, do not use System.Runtime.Loader on Android for the moment

pull/15969/head
Alexander Houben 7 years ago
parent 86aa172d9b
commit 7a7e09cf8a
  1. 15
      src/csharp/Grpc.Core/Grpc.Core.csproj
  2. 3
      src/csharp/Grpc.Core/GrpcEnvironment.cs
  3. 18
      src/csharp/Grpc.Core/Internal/NativeExtension.cs
  4. 33
      src/csharp/Grpc.Core/Internal/PlatformApis.cs
  5. 2
      src/csharp/Grpc.Core/Version.csproj.include
  6. 21
      src/csharp/Grpc.Core/build/MonoAndroid/Grpc.Core.targets
  7. 0
      src/csharp/Grpc.Core/build/net45/Grpc.Core.targets
  8. 23
      src/csharp/experimental/build_native_ext_for_android.sh

@ -46,8 +46,12 @@
<PackagePath>runtimes/win/native/grpc_csharp_ext.x86.dll</PackagePath>
<Pack>true</Pack>
</Content>
<Content Include="Grpc.Core.targets">
<PackagePath>build/net45/</PackagePath>
<Content Include="..\nativelibs\csharp_ext_monoandroid81_x86\libgrpc_csharp_ext.so">
<PackagePath>runtimes/monoandroid/armeabi-v7a/libgrpc_csharp_ext.so</PackagePath>
<Pack>true</Pack>
</Content>
<Content Include="..\nativelibs\csharp_ext_monoandroid81_x64\libgrpc_csharp_ext.so">
<PackagePath>runtimes/monoandroid/arm64-v8a/libgrpc_csharp_ext.so</PackagePath>
<Pack>true</Pack>
</Content>
</ItemGroup>
@ -69,4 +73,11 @@
<Import Project="NativeDeps.csproj.include" />
<ItemGroup>
<Content Include="build\**\*.*">
<Pack>true</Pack>
<PackagePath>build</PackagePath>
</Content>
</ItemGroup>
</Project>

@ -423,7 +423,8 @@ namespace Grpc.Core
if (!hooksRegistered)
{
#if NETSTANDARD1_5
System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += (assemblyLoadContext) => { HandleShutdown(); };
// FIXME couldn't get around a "cannot resolve type" runtime exception on Xamarin.Android
//System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += (assemblyLoadContext) => { HandleShutdown(); };
#else
AppDomain.CurrentDomain.ProcessExit += (sender, eventArgs) => { HandleShutdown(); };
AppDomain.CurrentDomain.DomainUnload += (sender, eventArgs) => { HandleShutdown(); };

@ -106,7 +106,9 @@ namespace Grpc.Core.Internal
/// </summary>
private static NativeMethods LoadNativeMethods()
{
return PlatformApis.IsUnity ? LoadNativeMethodsUnity() : new NativeMethods(LoadUnmanagedLibrary());
return PlatformApis.IsUnity ? LoadNativeMethodsUnity() :
PlatformApis.IsXamarin ? LoadNativeMethodsXamarin() :
new NativeMethods(LoadUnmanagedLibrary());
}
/// <summary>
@ -128,6 +130,20 @@ namespace Grpc.Core.Internal
}
}
/// <summary>
/// Return native method delegates when running on the Xamarin platform.
/// WARNING: Xamarin support is experimental and work-in-progress. Don't expect it to work.
/// </summary>
private static NativeMethods LoadNativeMethodsXamarin()
{
if (PlatformApis.IsXamarinAndroid)
{
return new NativeMethods(new NativeMethods.DllImportsFromSharedLib());
}
// not tested yet
return new NativeMethods(new NativeMethods.DllImportsFromStaticLib());
}
private static string GetAssemblyPath()
{
var assembly = typeof(NativeExtension).GetTypeInfo().Assembly;

@ -33,12 +33,17 @@ namespace Grpc.Core.Internal
internal static class PlatformApis
{
const string UnityEngineApplicationClassName = "UnityEngine.Application, UnityEngine";
const string XamarinAndroidActivityClassName = "Android.App.Activity, Mono.Android";
const string XamariniOSEnumClassName = "Mono.CSharp.Enum, Mono.CSharp";
static readonly bool isLinux;
static readonly bool isMacOSX;
static readonly bool isWindows;
static readonly bool isMono;
static readonly bool isNetCore;
static readonly bool isUnity;
static readonly bool isXamarin;
static readonly bool isXamariniOS;
static readonly bool isXamarinAndroid;
static PlatformApis()
{
@ -58,6 +63,9 @@ namespace Grpc.Core.Internal
#endif
isMono = Type.GetType("Mono.Runtime") != null;
isUnity = Type.GetType(UnityEngineApplicationClassName) != null;
isXamariniOS = Type.GetType(XamariniOSEnumClassName) != null;
isXamarinAndroid = Type.GetType(XamarinAndroidActivityClassName) != null;
isXamarin = isXamariniOS || isXamarinAndroid;
}
public static bool IsLinux
@ -88,6 +96,31 @@ namespace Grpc.Core.Internal
get { return isUnity; }
}
/// <summary>
/// true if running on a Xamarin platform (either Xamarin.Android or Xamarin.iOS),
/// false otherwise.
/// </summary>
public static bool IsXamarin
{
get { return isXamarin; }
}
/// <summary>
/// true if running on Xamarin.iOS, false otherwise.
/// </summary>
public static bool IsXamariniOS
{
get { return isXamariniOS; }
}
/// <summary>
/// true if running on Xamarin.Android, false otherwise.
/// </summary>
public static bool IsXamarinAndroid
{
get { return isXamarinAndroid; }
}
/// <summary>
/// true if running on .NET Core (CoreCLR), false otherwise.
/// </summary>

@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
<GrpcCsharpVersion>1.14.0-dev</GrpcCsharpVersion>
<GrpcCsharpVersion>1.14.1-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.5.1</GoogleProtobufVersion>
</PropertyGroup>
</Project>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_GrpcCoreNugetNativePath Condition="'$(_GrpcCoreNugetNativePath)' == ''">$(MSBuildThisFileDirectory)..\..\</_GrpcCoreNugetNativePath>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == 'MonoAndroid'">
<AndroidNativeLibrary Include="$(_GrpcCoreNugetNativePath)runtimes\monoandroid\arm64-v8a\libgrpc_csharp_ext.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Abi>arm64-v8a</Abi>
</AndroidNativeLibrary>
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == 'MonoAndroid'">
<AndroidNativeLibrary Include="$(_GrpcCoreNugetNativePath)runtimes\monoandroid\armeabi-v7a\libgrpc_csharp_ext.so">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Abi>armeabi-v7a</Abi>
</AndroidNativeLibrary>
</ItemGroup>
</Project>

@ -23,17 +23,28 @@ mkdir -p build
cd build
# set to the location where Android SDK is installed
# e.g. ANDROID_NDK_PATH="$HOME/android-ndk-r16b"
ANDROID_SDK_PATH="$HOME/Android/Sdk"
cmake ../.. \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_SYSTEM_VERSION=15 \
-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a \
# set to location where Android NDK is installed, usually a subfolder of Android SDK
# install the Android NDK through the Android SDK Manager
ANDROID_NDK_PATH=${ANDROID_SDK_PATH}/ndk-bundle
# set to location of the cmake executable
# by default, use cmake binary from the Android SDK
CMAKE_PATH="${ANDROID_SDK_PATH}/cmake/3.6.4111459/bin/cmake"
# ANDROID_ABI in ('arm64-v8a', 'armeabi-v7a')
${CMAKE_PATH} ../.. \
-DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake" \
-DCMAKE_ANDROID_NDK="${ANDROID_NDK_PATH}" \
-DCMAKE_ANDROID_STL_TYPE=c++_static \
-DRUN_HAVE_POSIX_REGEX=0 \
-DRUN_HAVE_STD_REGEX=0 \
-DRUN_HAVE_STEADY_CLOCK=0 \
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_PLATFORM=android-28 \
-DANDROID_ABI=arm64-v8a \
-DANDROID_NDK="${ANDROID_NDK_PATH}"
make -j4 grpc_csharp_ext

Loading…
Cancel
Save