Merge pull request #6115 from jtattermusch/csharp_support_projectjson

Make gRPC C# nuget work with new project.json style projects
pull/6134/head
Jan Tattermusch 9 years ago
commit d4f04e8e9c
  1. 8
      src/csharp/Grpc.Core/Grpc.Core.nuspec
  2. 0
      src/csharp/Grpc.Core/Grpc.Core.targets
  3. 27
      src/csharp/Grpc.Core/Internal/NativeExtension.cs
  4. 24
      src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
  5. 13
      src/csharp/build_packages.bat
  6. 22
      src/csharp/grpc.native.csharp/README.md
  7. 13
      templates/src/csharp/build_packages.bat.template

@ -16,7 +16,6 @@
<tags>gRPC RPC Protocol HTTP/2</tags>
<dependencies>
<dependency id="Ix-Async" version="1.2.5" />
<dependency id="grpc.native.csharp" version="$version$" />
</dependencies>
</metadata>
<files>
@ -24,5 +23,12 @@
<file src="bin/ReleaseSigned/Grpc.Core.pdb" target="lib/net45" />
<file src="bin/ReleaseSigned/Grpc.Core.xml" target="lib/net45" />
<file src="**\*.cs" target="src" />
<file src="Grpc.Core.targets" target="\build\net45\Grpc.Core.targets" />
<file src="windows_x86/grpc_csharp_ext.dll" target="/build/native/bin/windows_x86/grpc_csharp_ext.dll" />
<file src="windows_x64/grpc_csharp_ext.dll" target="/build/native/bin/windows_x64/grpc_csharp_ext.dll" />
<file src="linux_x86/libgrpc_csharp_ext.so" target="/build/native/bin/linux_x86/libgrpc_csharp_ext.so" />
<file src="linux_x64/libgrpc_csharp_ext.so" target="/build/native/bin/linux_x64/libgrpc_csharp_ext.so" />
<file src="macosx_x86/libgrpc_csharp_ext.dylib" target="/build/native/bin/macosx_x86/libgrpc_csharp_ext.dylib" />
<file src="macosx_x64/libgrpc_csharp_ext.dylib" target="/build/native/bin/macosx_x64/libgrpc_csharp_ext.dylib" />
</files>
</package>

@ -32,7 +32,6 @@
#endregion
using System;
using System.Globalization;
using System.IO;
using System.Reflection;
@ -46,6 +45,7 @@ namespace Grpc.Core.Internal
internal sealed class NativeExtension
{
const string NativeLibrariesDir = "nativelibs";
const string DnxStyleNativeLibrariesDir = "../../build/native/bin/";
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeExtension>();
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).
var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString());
var fullPath = Path.Combine(Path.GetDirectoryName(GetAssemblyPath()),
NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename());
return new UnmanagedLibrary(fullPath);
var assemblyDirectory = Path.GetDirectoryName(GetAssemblyPath());
// 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()
{
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
// to the original location of the assembly, and Location is pointing
// to the shadow copy. We care about the original location because
// the native dlls don't get shadowed.
var escapedCodeBase = assembly.EscapedCodeBase;
if (IsFileUri(escapedCodeBase))
{
return new Uri(escapedCodeBase).LocalPath;
}
return assembly.Location;
#endif
}
#if !DOTNET5_4
private static bool IsFileUri(string uri)
{
return uri.ToLowerInvariant().StartsWith(Uri.UriSchemeFile);
}
#endif
private static string GetPlatformString()
{

@ -32,8 +32,6 @@
#endregion
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
@ -63,14 +61,9 @@ namespace Grpc.Core.Internal
readonly string libraryPath;
readonly IntPtr handle;
public UnmanagedLibrary(string libraryPath)
public UnmanagedLibrary(string[] libraryPathAlternatives)
{
this.libraryPath = GrpcPreconditions.CheckNotNull(libraryPath);
if (!File.Exists(this.libraryPath))
{
throw new FileNotFoundException("Error loading native library. File does not exist.", this.libraryPath);
}
this.libraryPath = FirstValidLibraryPath(libraryPathAlternatives);
Logger.Debug("Attempting to load native library \"{0}\"", this.libraryPath);
@ -139,6 +132,19 @@ namespace Grpc.Core.Internal
throw new InvalidOperationException("Unsupported platform.");
}
private static string FirstValidLibraryPath(string[] libraryPathAlternatives)
{
GrpcPreconditions.CheckArgument(libraryPathAlternatives.Length > 0, "libraryPathAlternatives cannot be empty.");
foreach (var path in libraryPathAlternatives)
{
if (File.Exists(path))
{
return path;
}
}
throw new FileNotFoundException(String.Format("Error loading native library. Not found in any of the possible locations {0}", libraryPathAlternatives));
}
private static class Windows
{
[DllImport("kernel32.dll")]

@ -12,12 +12,12 @@ set NUGET=C:\nuget\nuget.exe
@rem Collect the artifacts built by the previous build step if running on Jenkins
@rem TODO(jtattermusch): is there a better way to do this?
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=windows\artifacts\* grpc.native.csharp\windows_x86\
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=windows\artifacts\* grpc.native.csharp\windows_x64\
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=linux\artifacts\* grpc.native.csharp\linux_x86\
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=linux\artifacts\* grpc.native.csharp\linux_x64\
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x86\
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x64\
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=windows\artifacts\* Grpc.Core\windows_x86\
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=windows\artifacts\* Grpc.Core\windows_x64\
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=linux\artifacts\* Grpc.Core\linux_x86\
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=linux\artifacts\* Grpc.Core\linux_x64\
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* Grpc.Core\macosx_x86\
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* Grpc.Core\macosx_x64\
@rem Collect protoc artifacts built by the previous build step
xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x86\
@ -42,7 +42,6 @@ msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
endlocal
%NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %VERSION% || goto :error
%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error

@ -1,22 +0,0 @@
gRPC Native Nuget package
=========================
Prerequisites
-------------
NuGet binary
Building the package
--------------------
To build the native package, you need precompiled versions
of grpc_csharp_ext library artifacts for Windows, Linux and Mac.
In the normal gRPC release process, these are built by a Jenkins
job and they are copied to the expected location before building
the native nuget package is attempted.
See tools/run_tests/build_artifacts.py for more details how
precompiled artifacts are built.
When building the native NuGet package, ignore the "Assembly outside lib folder"
warnings (the DLLs are not assemblies, they are native libraries).

@ -14,12 +14,12 @@
@rem Collect the artifacts built by the previous build step if running on Jenkins
@rem TODO(jtattermusch): is there a better way to do this?
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=windows\artifacts\* grpc.native.csharp\windows_x86${"\\"}
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=windows\artifacts\* grpc.native.csharp\windows_x64${"\\"}
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=linux\artifacts\* grpc.native.csharp\linux_x86${"\\"}
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=linux\artifacts\* grpc.native.csharp\linux_x64${"\\"}
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x86${"\\"}
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x64${"\\"}
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=windows\artifacts\* Grpc.Core\windows_x86${"\\"}
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=windows\artifacts\* Grpc.Core\windows_x64${"\\"}
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=linux\artifacts\* Grpc.Core\linux_x86${"\\"}
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=linux\artifacts\* Grpc.Core\linux_x64${"\\"}
xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* Grpc.Core\macosx_x86${"\\"}
xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* Grpc.Core\macosx_x64${"\\"}
@rem Collect protoc artifacts built by the previous build step
xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x86${"\\"}
@ -44,7 +44,6 @@
endlocal
%%NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %VERSION% || goto :error
%%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
%%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
%%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error

Loading…
Cancel
Save