|
|
@ -32,7 +32,6 @@ |
|
|
|
#endregion |
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
using System; |
|
|
|
using System; |
|
|
|
using System.Globalization; |
|
|
|
|
|
|
|
using System.IO; |
|
|
|
using System.IO; |
|
|
|
using System.Reflection; |
|
|
|
using System.Reflection; |
|
|
|
|
|
|
|
|
|
|
@ -46,6 +45,7 @@ namespace Grpc.Core.Internal |
|
|
|
internal sealed class NativeExtension |
|
|
|
internal sealed class NativeExtension |
|
|
|
{ |
|
|
|
{ |
|
|
|
const string NativeLibrariesDir = "nativelibs"; |
|
|
|
const string NativeLibrariesDir = "nativelibs"; |
|
|
|
|
|
|
|
const string DnxStyleNativeLibrariesDir = "../../build/native/bin/"; |
|
|
|
|
|
|
|
|
|
|
|
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeExtension>(); |
|
|
|
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeExtension>(); |
|
|
|
static readonly object staticLock = new object(); |
|
|
|
static readonly object staticLock = new object(); |
|
|
@ -100,31 +100,48 @@ namespace Grpc.Core.Internal |
|
|
|
// TODO: allow customizing path to native extension (possibly through exposing a GrpcEnvironment property). |
|
|
|
// TODO: allow customizing path to native extension (possibly through exposing a GrpcEnvironment property). |
|
|
|
|
|
|
|
|
|
|
|
var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString()); |
|
|
|
var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString()); |
|
|
|
var fullPath = Path.Combine(Path.GetDirectoryName(GetAssemblyPath()), |
|
|
|
|
|
|
|
NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename()); |
|
|
|
var assemblyDirectory = Path.GetDirectoryName(GetAssemblyPath()); |
|
|
|
return new UnmanagedLibrary(fullPath); |
|
|
|
|
|
|
|
|
|
|
|
// With old-style VS projects, the native libraries get copied using a .targets rule to the build output folder |
|
|
|
|
|
|
|
// alongside the compiled assembly. |
|
|
|
|
|
|
|
var classicPath = Path.Combine(assemblyDirectory, NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// DNX-style project.json projects will use Grpc.Core assembly directly in the location where it got restored |
|
|
|
|
|
|
|
// by nuget. We locate the native libraries based on known structure of Grpc.Core nuget package. |
|
|
|
|
|
|
|
var dnxStylePath = Path.Combine(assemblyDirectory, DnxStyleNativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new UnmanagedLibrary(new string[] {classicPath, dnxStylePath}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static string GetAssemblyPath() |
|
|
|
private static string GetAssemblyPath() |
|
|
|
{ |
|
|
|
{ |
|
|
|
var assembly = typeof(NativeExtension).GetTypeInfo().Assembly; |
|
|
|
var assembly = typeof(NativeExtension).GetTypeInfo().Assembly; |
|
|
|
|
|
|
|
#if DOTNET5_4 |
|
|
|
|
|
|
|
// Assembly.EscapedCodeBase does not exit under CoreCLR, but assemblies imported from a nuget package |
|
|
|
|
|
|
|
// don't seem to be shadowed by DNX-based projects at all. |
|
|
|
|
|
|
|
return assembly.Location; |
|
|
|
|
|
|
|
#else |
|
|
|
// If assembly is shadowed (e.g. in a webapp), EscapedCodeBase is pointing |
|
|
|
// If assembly is shadowed (e.g. in a webapp), EscapedCodeBase is pointing |
|
|
|
// to the original location of the assembly, and Location is pointing |
|
|
|
// to the original location of the assembly, and Location is pointing |
|
|
|
// to the shadow copy. We care about the original location because |
|
|
|
// to the shadow copy. We care about the original location because |
|
|
|
// the native dlls don't get shadowed. |
|
|
|
// the native dlls don't get shadowed. |
|
|
|
|
|
|
|
|
|
|
|
var escapedCodeBase = assembly.EscapedCodeBase; |
|
|
|
var escapedCodeBase = assembly.EscapedCodeBase; |
|
|
|
if (IsFileUri(escapedCodeBase)) |
|
|
|
if (IsFileUri(escapedCodeBase)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return new Uri(escapedCodeBase).LocalPath; |
|
|
|
return new Uri(escapedCodeBase).LocalPath; |
|
|
|
} |
|
|
|
} |
|
|
|
return assembly.Location; |
|
|
|
return assembly.Location; |
|
|
|
|
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if !DOTNET5_4 |
|
|
|
private static bool IsFileUri(string uri) |
|
|
|
private static bool IsFileUri(string uri) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return uri.ToLowerInvariant().StartsWith(Uri.UriSchemeFile); |
|
|
|
return uri.ToLowerInvariant().StartsWith(Uri.UriSchemeFile); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
private static string GetPlatformString() |
|
|
|
private static string GetPlatformString() |
|
|
|
{ |
|
|
|
{ |
|
|
|