mirror of https://github.com/grpc/grpc.git
commit
2585e0624b
104 changed files with 3133 additions and 292 deletions
@ -1,5 +1,44 @@ |
||||
workspace(name = "com_github_grpc_grpc") |
||||
workspace(name="com_github_grpc_grpc") |
||||
|
||||
load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps") |
||||
grpc_deps() |
||||
grpc_test_only_deps() |
||||
|
||||
new_http_archive( |
||||
name="cython", |
||||
sha256="d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27", |
||||
urls=[ |
||||
"https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz", |
||||
], |
||||
strip_prefix="cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c", |
||||
build_file="//third_party:cython.BUILD", |
||||
) |
||||
|
||||
load("//third_party/py:python_configure.bzl", "python_configure") |
||||
python_configure(name="local_config_python") |
||||
|
||||
git_repository( |
||||
name="io_bazel_rules_python", |
||||
remote="https://github.com/bazelbuild/rules_python.git", |
||||
commit="8b5d0683a7d878b28fffe464779c8a53659fc645", |
||||
) |
||||
|
||||
load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import") |
||||
|
||||
pip_repositories() |
||||
pip_import( |
||||
name="grpc_python_dependencies", |
||||
requirements="//:requirements.bazel.txt", |
||||
) |
||||
|
||||
load("@grpc_python_dependencies//:requirements.bzl", "pip_install") |
||||
pip_install() |
||||
|
||||
git_repository( |
||||
name="org_pubref_rules_protobuf", |
||||
remote="https://github.com/pubref/rules_protobuf", |
||||
tag="v0.8.2", |
||||
) |
||||
|
||||
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") |
||||
py_proto_repositories() |
||||
|
@ -0,0 +1,74 @@ |
||||
"""Custom rules for gRPC Python""" |
||||
|
||||
|
||||
# Adapted with modifications from |
||||
# tensorflow/tensorflow/core/platform/default/build_config.bzl |
||||
# Native Bazel rules don't exist yet to compile Cython code, but rules have |
||||
# been written at cython/cython and tensorflow/tensorflow. We branch from |
||||
# Tensorflow's version as it is more actively maintained and works for gRPC |
||||
# Python's needs. |
||||
def pyx_library(name, deps=[], py_deps=[], srcs=[], **kwargs): |
||||
"""Compiles a group of .pyx / .pxd / .py files. |
||||
|
||||
First runs Cython to create .cpp files for each input .pyx or .py + .pxd |
||||
pair. Then builds a shared object for each, passing "deps" to each cc_binary |
||||
rule (includes Python headers by default). Finally, creates a py_library rule |
||||
with the shared objects and any pure Python "srcs", with py_deps as its |
||||
dependencies; the shared objects can be imported like normal Python files. |
||||
|
||||
Args: |
||||
name: Name for the rule. |
||||
deps: C/C++ dependencies of the Cython (e.g. Numpy headers). |
||||
py_deps: Pure Python dependencies of the final library. |
||||
srcs: .py, .pyx, or .pxd files to either compile or pass through. |
||||
**kwargs: Extra keyword arguments passed to the py_library. |
||||
""" |
||||
# First filter out files that should be run compiled vs. passed through. |
||||
py_srcs = [] |
||||
pyx_srcs = [] |
||||
pxd_srcs = [] |
||||
for src in srcs: |
||||
if src.endswith(".pyx") or (src.endswith(".py") and |
||||
src[:-3] + ".pxd" in srcs): |
||||
pyx_srcs.append(src) |
||||
elif src.endswith(".py"): |
||||
py_srcs.append(src) |
||||
else: |
||||
pxd_srcs.append(src) |
||||
if src.endswith("__init__.py"): |
||||
pxd_srcs.append(src) |
||||
|
||||
# Invoke cython to produce the shared object libraries. |
||||
for filename in pyx_srcs: |
||||
native.genrule( |
||||
name=filename + "_cython_translation", |
||||
srcs=[filename], |
||||
outs=[filename.split(".")[0] + ".cpp"], |
||||
# Optionally use PYTHON_BIN_PATH on Linux platforms so that python 3 |
||||
# works. Windows has issues with cython_binary so skip PYTHON_BIN_PATH. |
||||
cmd= |
||||
"PYTHONHASHSEED=0 $(location @cython//:cython_binary) --cplus $(SRCS) --output-file $(OUTS)", |
||||
tools=["@cython//:cython_binary"] + pxd_srcs, |
||||
) |
||||
|
||||
shared_objects = [] |
||||
for src in pyx_srcs: |
||||
stem = src.split(".")[0] |
||||
shared_object_name = stem + ".so" |
||||
native.cc_binary( |
||||
name=shared_object_name, |
||||
srcs=[stem + ".cpp"], |
||||
deps=deps + ["@local_config_python//:python_headers"], |
||||
linkshared=1, |
||||
) |
||||
shared_objects.append(shared_object_name) |
||||
|
||||
# Now create a py_library with these shared objects as data. |
||||
native.py_library( |
||||
name=name, |
||||
srcs=py_srcs, |
||||
deps=py_deps, |
||||
srcs_version="PY2AND3", |
||||
data=shared_objects, |
||||
**kwargs) |
||||
|
@ -0,0 +1,41 @@ |
||||
# Autosave files |
||||
*~ |
||||
|
||||
# build |
||||
[Oo]bj/ |
||||
[Bb]in/ |
||||
packages/ |
||||
TestResults/ |
||||
|
||||
# globs |
||||
Makefile.in |
||||
*.DS_Store |
||||
*.sln.cache |
||||
*.suo |
||||
*.cache |
||||
*.pidb |
||||
*.userprefs |
||||
*.usertasks |
||||
config.log |
||||
config.make |
||||
config.status |
||||
aclocal.m4 |
||||
install-sh |
||||
autom4te.cache/ |
||||
*.user |
||||
*.tar.gz |
||||
tarballs/ |
||||
test-results/ |
||||
Thumbs.db |
||||
.vs/ |
||||
|
||||
# Mac bundle stuff |
||||
*.dmg |
||||
*.app |
||||
|
||||
# resharper |
||||
*_Resharper.* |
||||
*.Resharper |
||||
|
||||
# dotCover |
||||
*.dotCover |
@ -0,0 +1,19 @@ |
||||
Any raw assets you want to be deployed with your application can be placed in |
||||
this directory (and child directories) and given a Build Action of "AndroidAsset". |
||||
|
||||
These files will be deployed with your package and will be accessible using Android's |
||||
AssetManager, like this: |
||||
|
||||
public class ReadAsset : Activity |
||||
{ |
||||
protected override void OnCreate (Bundle bundle) |
||||
{ |
||||
base.OnCreate (bundle); |
||||
|
||||
InputStream input = Assets.Open ("my_asset.txt"); |
||||
} |
||||
} |
||||
|
||||
Additionally, some Android functions will automatically load asset files: |
||||
|
||||
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); |
@ -0,0 +1,83 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
<ProjectGuid>{B9B0D41C-1C07-4590-A919-5865E741B2EA}</ProjectGuid> |
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
||||
<OutputType>Library</OutputType> |
||||
<RootNamespace>HelloworldXamarin.Droid</RootNamespace> |
||||
<AssemblyName>HelloworldXamarin.Droid</AssemblyName> |
||||
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion> |
||||
<AndroidApplication>True</AndroidApplication> |
||||
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile> |
||||
<AndroidResgenClass>Resource</AndroidResgenClass> |
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> |
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix> |
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix> |
||||
<AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>full</DebugType> |
||||
<Optimize>false</Optimize> |
||||
<OutputPath>bin\Debug</OutputPath> |
||||
<DefineConstants>DEBUG;</DefineConstants> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
<AndroidLinkMode>None</AndroidLinkMode> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>pdbonly</DebugType> |
||||
<Optimize>true</Optimize> |
||||
<OutputPath>bin\Release</OutputPath> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
<AndroidManagedSymbols>true</AndroidManagedSymbols> |
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="System.Core" /> |
||||
<Reference Include="Mono.Android" /> |
||||
<Reference Include="System.IO.Compression" /> |
||||
<Reference Include="System.Net.Http" /> |
||||
<Reference Include="System.Runtime.Loader"> |
||||
<HintPath>..\packages\System.Runtime.Loader.4.0.0\lib\netstandard1.5\System.Runtime.Loader.dll</HintPath> |
||||
</Reference> |
||||
<Reference Include="System.Interactive.Async"> |
||||
<HintPath>..\packages\System.Interactive.Async.3.1.1\lib\netstandard1.3\System.Interactive.Async.dll</HintPath> |
||||
</Reference> |
||||
<Reference Include="Grpc.Core"> |
||||
<HintPath>..\packages\Grpc.Core.1.15.0-dev\lib\netstandard1.5\Grpc.Core.dll</HintPath> |
||||
</Reference> |
||||
<Reference Include="Google.Protobuf"> |
||||
<HintPath>..\packages\Google.Protobuf.3.6.0\lib\netstandard1.0\Google.Protobuf.dll</HintPath> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="MainActivity.cs" /> |
||||
<Compile Include="Resources\Resource.designer.cs" /> |
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<None Include="Resources\AboutResources.txt" /> |
||||
<None Include="Properties\AndroidManifest.xml" /> |
||||
<None Include="Assets\AboutAssets.txt" /> |
||||
<None Include="packages.config" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<AndroidResource Include="Resources\layout\Main.axml" /> |
||||
<AndroidResource Include="Resources\values\Strings.xml" /> |
||||
<AndroidResource Include="Resources\mipmap-hdpi\Icon.png" /> |
||||
<AndroidResource Include="Resources\mipmap-mdpi\Icon.png" /> |
||||
<AndroidResource Include="Resources\mipmap-xhdpi\Icon.png" /> |
||||
<AndroidResource Include="Resources\mipmap-xxhdpi\Icon.png" /> |
||||
<AndroidResource Include="Resources\mipmap-xxxhdpi\Icon.png" /> |
||||
</ItemGroup> |
||||
<Import Project="..\HelloworldXamarin\HelloworldXamarin.projitems" Label="Shared" Condition="Exists('..\HelloworldXamarin\HelloworldXamarin.projitems')" /> |
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> |
||||
<Import Project="..\packages\Grpc.Core.1.15.0-dev\build\MonoAndroid\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.15.0-dev\build\MonoAndroid\Grpc.Core.targets')" /> |
||||
</Project> |
@ -0,0 +1,44 @@ |
||||
Images, layout descriptions, binary blobs and string dictionaries can be included |
||||
in your application as resource files. Various Android APIs are designed to |
||||
operate on the resource IDs instead of dealing with images, strings or binary blobs |
||||
directly. |
||||
|
||||
For example, a sample Android app that contains a user interface layout (main.axml), |
||||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) |
||||
would keep its resources in the "Resources" directory of the application: |
||||
|
||||
Resources/ |
||||
drawable/ |
||||
icon.png |
||||
|
||||
layout/ |
||||
main.axml |
||||
|
||||
values/ |
||||
strings.xml |
||||
|
||||
In order to get the build system to recognize Android resources, set the build action to |
||||
"AndroidResource". The native Android APIs do not operate directly with filenames, but |
||||
instead operate on resource IDs. When you compile an Android application that uses resources, |
||||
the build system will package the resources for distribution and generate a class called "R" |
||||
(this is an Android convention) that contains the tokens for each one of the resources |
||||
included. For example, for the above Resources layout, this is what the R class would expose: |
||||
|
||||
public class R { |
||||
public class drawable { |
||||
public const int icon = 0x123; |
||||
} |
||||
|
||||
public class layout { |
||||
public const int main = 0x456; |
||||
} |
||||
|
||||
public class strings { |
||||
public const int first_string = 0xabc; |
||||
public const int second_string = 0xbcd; |
||||
} |
||||
} |
||||
|
||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main |
||||
to reference the layout/main.axml file, or R.strings.first_string to reference the first |
||||
string in the dictionary file values/strings.xml. |
@ -0,0 +1,112 @@ |
||||
#pragma warning disable 1591 |
||||
//------------------------------------------------------------------------------ |
||||
// <auto-generated> |
||||
// This code was generated by a tool. |
||||
// Runtime Version:4.0.30319.42000 |
||||
// |
||||
// Changes to this file may cause incorrect behavior and will be lost if |
||||
// the code is regenerated. |
||||
// </auto-generated> |
||||
//------------------------------------------------------------------------------ |
||||
|
||||
[assembly: global::Android.Runtime.ResourceDesignerAttribute("HelloworldXamarin.Droid.Resource", IsApplication=true)] |
||||
|
||||
namespace HelloworldXamarin.Droid |
||||
{ |
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] |
||||
public partial class Resource |
||||
{ |
||||
|
||||
static Resource() |
||||
{ |
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
} |
||||
|
||||
public static void UpdateIdValues() |
||||
{ |
||||
} |
||||
|
||||
public partial class Attribute |
||||
{ |
||||
|
||||
static Attribute() |
||||
{ |
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
} |
||||
|
||||
private Attribute() |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public partial class Id |
||||
{ |
||||
|
||||
// aapt resource value: 0x7f050000 |
||||
public const int myButton = 2131034112; |
||||
|
||||
static Id() |
||||
{ |
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
} |
||||
|
||||
private Id() |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public partial class Layout |
||||
{ |
||||
|
||||
// aapt resource value: 0x7f030000 |
||||
public const int Main = 2130903040; |
||||
|
||||
static Layout() |
||||
{ |
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
} |
||||
|
||||
private Layout() |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public partial class Mipmap |
||||
{ |
||||
|
||||
// aapt resource value: 0x7f020000 |
||||
public const int Icon = 2130837504; |
||||
|
||||
static Mipmap() |
||||
{ |
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
} |
||||
|
||||
private Mipmap() |
||||
{ |
||||
} |
||||
} |
||||
|
||||
public partial class String |
||||
{ |
||||
|
||||
// aapt resource value: 0x7f040001 |
||||
public const int app_name = 2130968577; |
||||
|
||||
// aapt resource value: 0x7f040000 |
||||
public const int hello = 2130968576; |
||||
|
||||
static String() |
||||
{ |
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
} |
||||
|
||||
private String() |
||||
{ |
||||
} |
||||
} |
||||
} |
||||
} |
||||
#pragma warning restore 1591 |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 7.6 KiB |
@ -0,0 +1,45 @@ |
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
# Visual Studio 2012 |
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "HelloworldXamarin", "HelloworldXamarin\HelloworldXamarin.shproj", "{42FFF3D8-934F-4475-8E68-08DA340BF6E8}" |
||||
EndProject |
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloworldXamarin.Droid", "Droid\HelloworldXamarin.Droid.csproj", "{B9B0D41C-1C07-4590-A919-5865E741B2EA}" |
||||
EndProject |
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloworldXamarin.iOS", "iOS\HelloworldXamarin.iOS.csproj", "{62336DF0-60D8-478F-8140-B3CB089B417E}" |
||||
EndProject |
||||
Global |
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
Debug|Any CPU = Debug|Any CPU |
||||
Release|Any CPU = Release|Any CPU |
||||
Debug|iPhoneSimulator = Debug|iPhoneSimulator |
||||
Release|iPhone = Release|iPhone |
||||
Release|iPhoneSimulator = Release|iPhoneSimulator |
||||
Debug|iPhone = Debug|iPhone |
||||
EndGlobalSection |
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|iPhone.ActiveCfg = Release|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|iPhone.Build.0 = Release|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|iPhone.ActiveCfg = Debug|Any CPU |
||||
{B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|iPhone.Build.0 = Debug|Any CPU |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Release|Any CPU.ActiveCfg = Release|iPhone |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Release|Any CPU.Build.0 = Release|iPhone |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Release|iPhone.ActiveCfg = Release|iPhone |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Release|iPhone.Build.0 = Release|iPhone |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|iPhone.ActiveCfg = Debug|iPhone |
||||
{62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|iPhone.Build.0 = Debug|iPhone |
||||
EndGlobalSection |
||||
EndGlobal |
@ -0,0 +1,286 @@ |
||||
// Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
// source: helloworld.proto |
||||
#pragma warning disable 1591, 0612, 3021 |
||||
#region Designer generated code |
||||
|
||||
using pb = global::Google.Protobuf; |
||||
using pbc = global::Google.Protobuf.Collections; |
||||
using pbr = global::Google.Protobuf.Reflection; |
||||
using scg = global::System.Collections.Generic; |
||||
namespace Helloworld { |
||||
|
||||
/// <summary>Holder for reflection information generated from helloworld.proto</summary> |
||||
public static partial class HelloworldReflection { |
||||
|
||||
#region Descriptor |
||||
/// <summary>File descriptor for helloworld.proto</summary> |
||||
public static pbr::FileDescriptor Descriptor { |
||||
get { return descriptor; } |
||||
} |
||||
private static pbr::FileDescriptor descriptor; |
||||
|
||||
static HelloworldReflection() { |
||||
byte[] descriptorData = global::System.Convert.FromBase64String( |
||||
string.Concat( |
||||
"ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", |
||||
"dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", |
||||
"CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", |
||||
"cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4", |
||||
"YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw", |
||||
"cm90bzM=")); |
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, |
||||
new pbr::FileDescriptor[] { }, |
||||
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { |
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null), |
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null) |
||||
})); |
||||
} |
||||
#endregion |
||||
|
||||
} |
||||
#region Messages |
||||
/// <summary> |
||||
/// The request message containing the user's name. |
||||
/// </summary> |
||||
public sealed partial class HelloRequest : pb::IMessage<HelloRequest> { |
||||
private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest()); |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } } |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public static pbr::MessageDescriptor Descriptor { |
||||
get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; } |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
pbr::MessageDescriptor pb::IMessage.Descriptor { |
||||
get { return Descriptor; } |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public HelloRequest() { |
||||
OnConstruction(); |
||||
} |
||||
|
||||
partial void OnConstruction(); |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public HelloRequest(HelloRequest other) : this() { |
||||
name_ = other.name_; |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public HelloRequest Clone() { |
||||
return new HelloRequest(this); |
||||
} |
||||
|
||||
/// <summary>Field number for the "name" field.</summary> |
||||
public const int NameFieldNumber = 1; |
||||
private string name_ = ""; |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public string Name { |
||||
get { return name_; } |
||||
set { |
||||
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); |
||||
} |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public override bool Equals(object other) { |
||||
return Equals(other as HelloRequest); |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public bool Equals(HelloRequest other) { |
||||
if (ReferenceEquals(other, null)) { |
||||
return false; |
||||
} |
||||
if (ReferenceEquals(other, this)) { |
||||
return true; |
||||
} |
||||
if (Name != other.Name) return false; |
||||
return true; |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public override int GetHashCode() { |
||||
int hash = 1; |
||||
if (Name.Length != 0) hash ^= Name.GetHashCode(); |
||||
return hash; |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public override string ToString() { |
||||
return pb::JsonFormatter.ToDiagnosticString(this); |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public void WriteTo(pb::CodedOutputStream output) { |
||||
if (Name.Length != 0) { |
||||
output.WriteRawTag(10); |
||||
output.WriteString(Name); |
||||
} |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public int CalculateSize() { |
||||
int size = 0; |
||||
if (Name.Length != 0) { |
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); |
||||
} |
||||
return size; |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public void MergeFrom(HelloRequest other) { |
||||
if (other == null) { |
||||
return; |
||||
} |
||||
if (other.Name.Length != 0) { |
||||
Name = other.Name; |
||||
} |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public void MergeFrom(pb::CodedInputStream input) { |
||||
uint tag; |
||||
while ((tag = input.ReadTag()) != 0) { |
||||
switch(tag) { |
||||
default: |
||||
input.SkipLastField(); |
||||
break; |
||||
case 10: { |
||||
Name = input.ReadString(); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary> |
||||
/// The response message containing the greetings |
||||
/// </summary> |
||||
public sealed partial class HelloReply : pb::IMessage<HelloReply> { |
||||
private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply()); |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public static pb::MessageParser<HelloReply> Parser { get { return _parser; } } |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public static pbr::MessageDescriptor Descriptor { |
||||
get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; } |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
pbr::MessageDescriptor pb::IMessage.Descriptor { |
||||
get { return Descriptor; } |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public HelloReply() { |
||||
OnConstruction(); |
||||
} |
||||
|
||||
partial void OnConstruction(); |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public HelloReply(HelloReply other) : this() { |
||||
message_ = other.message_; |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public HelloReply Clone() { |
||||
return new HelloReply(this); |
||||
} |
||||
|
||||
/// <summary>Field number for the "message" field.</summary> |
||||
public const int MessageFieldNumber = 1; |
||||
private string message_ = ""; |
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public string Message { |
||||
get { return message_; } |
||||
set { |
||||
message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); |
||||
} |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public override bool Equals(object other) { |
||||
return Equals(other as HelloReply); |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public bool Equals(HelloReply other) { |
||||
if (ReferenceEquals(other, null)) { |
||||
return false; |
||||
} |
||||
if (ReferenceEquals(other, this)) { |
||||
return true; |
||||
} |
||||
if (Message != other.Message) return false; |
||||
return true; |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public override int GetHashCode() { |
||||
int hash = 1; |
||||
if (Message.Length != 0) hash ^= Message.GetHashCode(); |
||||
return hash; |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public override string ToString() { |
||||
return pb::JsonFormatter.ToDiagnosticString(this); |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public void WriteTo(pb::CodedOutputStream output) { |
||||
if (Message.Length != 0) { |
||||
output.WriteRawTag(10); |
||||
output.WriteString(Message); |
||||
} |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public int CalculateSize() { |
||||
int size = 0; |
||||
if (Message.Length != 0) { |
||||
size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); |
||||
} |
||||
return size; |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public void MergeFrom(HelloReply other) { |
||||
if (other == null) { |
||||
return; |
||||
} |
||||
if (other.Message.Length != 0) { |
||||
Message = other.Message; |
||||
} |
||||
} |
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute] |
||||
public void MergeFrom(pb::CodedInputStream input) { |
||||
uint tag; |
||||
while ((tag = input.ReadTag()) != 0) { |
||||
switch(tag) { |
||||
default: |
||||
input.SkipLastField(); |
||||
break; |
||||
case 10: { |
||||
Message = input.ReadString(); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
#endregion |
||||
|
||||
} |
||||
|
||||
#endregion Designer generated code |
@ -0,0 +1,150 @@ |
||||
// Generated by the protocol buffer compiler. DO NOT EDIT! |
||||
// source: helloworld.proto |
||||
// Original file comments: |
||||
// Copyright 2015 gRPC authors. |
||||
// |
||||
// Licensed under the Apache License, Version 2.0 (the "License"); |
||||
// you may not use this file except in compliance with the License. |
||||
// You may obtain a copy of the License at |
||||
// |
||||
// http://www.apache.org/licenses/LICENSE-2.0 |
||||
// |
||||
// Unless required by applicable law or agreed to in writing, software |
||||
// distributed under the License is distributed on an "AS IS" BASIS, |
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
// See the License for the specific language governing permissions and |
||||
// limitations under the License. |
||||
// |
||||
#pragma warning disable 1591 |
||||
#region Designer generated code |
||||
|
||||
using System; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using grpc = global::Grpc.Core; |
||||
|
||||
namespace Helloworld { |
||||
/// <summary> |
||||
/// The greeting service definition. |
||||
/// </summary> |
||||
public static partial class Greeter |
||||
{ |
||||
static readonly string __ServiceName = "helloworld.Greeter"; |
||||
|
||||
static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); |
||||
static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); |
||||
|
||||
static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>( |
||||
grpc::MethodType.Unary, |
||||
__ServiceName, |
||||
"SayHello", |
||||
__Marshaller_HelloRequest, |
||||
__Marshaller_HelloReply); |
||||
|
||||
/// <summary>Service descriptor</summary> |
||||
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor |
||||
{ |
||||
get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; } |
||||
} |
||||
|
||||
/// <summary>Base class for server-side implementations of Greeter</summary> |
||||
public abstract partial class GreeterBase |
||||
{ |
||||
/// <summary> |
||||
/// Sends a greeting |
||||
/// </summary> |
||||
/// <param name="request">The request received from the client.</param> |
||||
/// <param name="context">The context of the server-side call handler being invoked.</param> |
||||
/// <returns>The response to send back to the client (wrapped by a task).</returns> |
||||
public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context) |
||||
{ |
||||
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); |
||||
} |
||||
|
||||
} |
||||
|
||||
/// <summary>Client for Greeter</summary> |
||||
public partial class GreeterClient : grpc::ClientBase<GreeterClient> |
||||
{ |
||||
/// <summary>Creates a new client for Greeter</summary> |
||||
/// <param name="channel">The channel to use to make remote calls.</param> |
||||
public GreeterClient(grpc::Channel channel) : base(channel) |
||||
{ |
||||
} |
||||
/// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary> |
||||
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param> |
||||
public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker) |
||||
{ |
||||
} |
||||
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary> |
||||
protected GreeterClient() : base() |
||||
{ |
||||
} |
||||
/// <summary>Protected constructor to allow creation of configured clients.</summary> |
||||
/// <param name="configuration">The client configuration.</param> |
||||
protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration) |
||||
{ |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Sends a greeting |
||||
/// </summary> |
||||
/// <param name="request">The request to send to the server.</param> |
||||
/// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param> |
||||
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param> |
||||
/// <param name="cancellationToken">An optional token for canceling the call.</param> |
||||
/// <returns>The response received from the server.</returns> |
||||
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) |
||||
{ |
||||
return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken)); |
||||
} |
||||
/// <summary> |
||||
/// Sends a greeting |
||||
/// </summary> |
||||
/// <param name="request">The request to send to the server.</param> |
||||
/// <param name="options">The options for the call.</param> |
||||
/// <returns>The response received from the server.</returns> |
||||
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options) |
||||
{ |
||||
return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request); |
||||
} |
||||
/// <summary> |
||||
/// Sends a greeting |
||||
/// </summary> |
||||
/// <param name="request">The request to send to the server.</param> |
||||
/// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param> |
||||
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param> |
||||
/// <param name="cancellationToken">An optional token for canceling the call.</param> |
||||
/// <returns>The call object.</returns> |
||||
public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) |
||||
{ |
||||
return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); |
||||
} |
||||
/// <summary> |
||||
/// Sends a greeting |
||||
/// </summary> |
||||
/// <param name="request">The request to send to the server.</param> |
||||
/// <param name="options">The options for the call.</param> |
||||
/// <returns>The call object.</returns> |
||||
public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options) |
||||
{ |
||||
return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request); |
||||
} |
||||
/// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary> |
||||
protected override GreeterClient NewInstance(ClientBaseConfiguration configuration) |
||||
{ |
||||
return new GreeterClient(configuration); |
||||
} |
||||
} |
||||
|
||||
/// <summary>Creates service definition that can be registered with a server</summary> |
||||
/// <param name="serviceImpl">An object implementing the server-side handling logic.</param> |
||||
public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl) |
||||
{ |
||||
return grpc::ServerServiceDefinition.CreateBuilder() |
||||
.AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); |
||||
} |
||||
|
||||
} |
||||
} |
||||
#endregion |
@ -0,0 +1,15 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> |
||||
<HasSharedItems>true</HasSharedItems> |
||||
<SharedGUID>{42FFF3D8-934F-4475-8E68-08DA340BF6E8}</SharedGUID> |
||||
</PropertyGroup> |
||||
<PropertyGroup Label="Configuration"> |
||||
<Import_RootNamespace>HelloworldXamarin</Import_RootNamespace> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Compile Include="$(MSBuildThisFileDirectory)Helloworld.cs" /> |
||||
<Compile Include="$(MSBuildThisFileDirectory)HelloworldGrpc.cs" /> |
||||
</ItemGroup> |
||||
</Project> |
@ -0,0 +1,11 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<ProjectGuid>{42FFF3D8-934F-4475-8E68-08DA340BF6E8}</ProjectGuid> |
||||
</PropertyGroup> |
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" /> |
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" /> |
||||
<Import Project="HelloworldXamarin.projitems" Label="Shared" /> |
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" /> |
||||
</Project> |
@ -0,0 +1,35 @@ |
||||
gRPC C# on Xamarin |
||||
======================== |
||||
|
||||
EXPERIMENTAL ONLY |
||||
------------- |
||||
Support of the Xamarin platform is currently experimental. |
||||
The example depends on experimental Grpc.Core nuget package that hasn't |
||||
been officially released and is only available via the [daily builds](https://packages.grpc.io/) |
||||
source. |
||||
|
||||
BACKGROUND |
||||
------------- |
||||
The example project supports Xamarin.Android and Xamarin.iOS |
||||
|
||||
For this sample, we've already generated the server and client stubs from [helloworld.proto][]. |
||||
|
||||
PREREQUISITES |
||||
------------- |
||||
|
||||
- The latest version Xamarin Studio or Visual Studio 2017 with Xamarin support installed. |
||||
|
||||
BUILD |
||||
------- |
||||
|
||||
- Open the `HelloworldXamarin.sln` in Visual Studio (or Xamarin Studio) |
||||
- Build the solution (Build -> Build All) |
||||
|
||||
Try it! |
||||
------- |
||||
|
||||
You can deploy the example apps directly through Xamarin Studio IDE. |
||||
Deployments can target both Android and iOS (both support physical device |
||||
deployment as well as simulator). |
||||
|
||||
[helloworld.proto]:../../protos/helloworld.proto |
@ -0,0 +1,202 @@ |
||||
{ |
||||
"images" : [ |
||||
{ |
||||
"idiom" : "iphone", |
||||
"size" : "20x20", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "iphone", |
||||
"size" : "20x20", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"idiom" : "iphone", |
||||
"size" : "29x29", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "iphone", |
||||
"size" : "29x29", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"idiom" : "iphone", |
||||
"size" : "40x40", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "iphone", |
||||
"size" : "40x40", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"idiom" : "iphone", |
||||
"size" : "60x60", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "iphone", |
||||
"size" : "60x60", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "20x20", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "20x20", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "29x29", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "29x29", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "40x40", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "40x40", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "76x76", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "76x76", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "ipad", |
||||
"size" : "83.5x83.5", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "ios-marketing", |
||||
"size" : "1024x1024", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"size" : "24x24", |
||||
"idiom" : "watch", |
||||
"scale" : "2x", |
||||
"role" : "notificationCenter", |
||||
"subtype" : "38mm" |
||||
}, |
||||
{ |
||||
"size" : "27.5x27.5", |
||||
"idiom" : "watch", |
||||
"scale" : "2x", |
||||
"role" : "notificationCenter", |
||||
"subtype" : "42mm" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "watch", |
||||
"role" : "companionSettings", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"size" : "29x29", |
||||
"idiom" : "watch", |
||||
"role" : "companionSettings", |
||||
"scale" : "3x" |
||||
}, |
||||
{ |
||||
"size" : "40x40", |
||||
"idiom" : "watch", |
||||
"scale" : "2x", |
||||
"role" : "appLauncher", |
||||
"subtype" : "38mm" |
||||
}, |
||||
{ |
||||
"size" : "44x44", |
||||
"idiom" : "watch", |
||||
"scale" : "2x", |
||||
"role" : "longLook", |
||||
"subtype" : "42mm" |
||||
}, |
||||
{ |
||||
"size" : "86x86", |
||||
"idiom" : "watch", |
||||
"scale" : "2x", |
||||
"role" : "quickLook", |
||||
"subtype" : "38mm" |
||||
}, |
||||
{ |
||||
"size" : "98x98", |
||||
"idiom" : "watch", |
||||
"scale" : "2x", |
||||
"role" : "quickLook", |
||||
"subtype" : "42mm" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "16x16", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "16x16", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "32x32", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "32x32", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "128x128", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "128x128", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "256x256", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "256x256", |
||||
"scale" : "2x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "512x512", |
||||
"scale" : "1x" |
||||
}, |
||||
{ |
||||
"idiom" : "mac", |
||||
"size" : "512x512", |
||||
"scale" : "2x" |
||||
} |
||||
], |
||||
"info" : { |
||||
"version" : 1, |
||||
"author" : "xcode" |
||||
} |
||||
} |
@ -0,0 +1,126 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<PropertyGroup> |
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform> |
||||
<ProjectGuid>{62336DF0-60D8-478F-8140-B3CB089B417E}</ProjectGuid> |
||||
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
||||
<OutputType>Exe</OutputType> |
||||
<RootNamespace>HelloworldXamarin.iOS</RootNamespace> |
||||
<AssemblyName>HelloworldXamarin.iOS</AssemblyName> |
||||
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>full</DebugType> |
||||
<Optimize>false</Optimize> |
||||
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath> |
||||
<DefineConstants>DEBUG;ENABLE_TEST_CLOUD;</DefineConstants> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
<CodesignKey>iPhone Developer</CodesignKey> |
||||
<MtouchDebug>true</MtouchDebug> |
||||
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip> |
||||
<MtouchFastDev>true</MtouchFastDev> |
||||
<IOSDebuggerPort>45216</IOSDebuggerPort> |
||||
<MtouchLink>None</MtouchLink> |
||||
<MtouchArch>x86_64</MtouchArch> |
||||
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler> |
||||
<PlatformTarget>x86</PlatformTarget> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' "> |
||||
<DebugType>pdbonly</DebugType> |
||||
<Optimize>true</Optimize> |
||||
<OutputPath>bin\iPhone\Release</OutputPath> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
<CodesignKey>iPhone Developer</CodesignKey> |
||||
<MtouchFloat32>true</MtouchFloat32> |
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> |
||||
<MtouchLink>SdkOnly</MtouchLink> |
||||
<MtouchArch>ARM64</MtouchArch> |
||||
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler> |
||||
<PlatformTarget>x86</PlatformTarget> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' "> |
||||
<DebugType>pdbonly</DebugType> |
||||
<Optimize>true</Optimize> |
||||
<OutputPath>bin\iPhoneSimulator\Release</OutputPath> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
<CodesignKey>iPhone Developer</CodesignKey> |
||||
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip> |
||||
<MtouchLink>None</MtouchLink> |
||||
<MtouchArch>x86_64</MtouchArch> |
||||
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler> |
||||
<PlatformTarget>x86</PlatformTarget> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' "> |
||||
<DebugSymbols>true</DebugSymbols> |
||||
<DebugType>full</DebugType> |
||||
<Optimize>false</Optimize> |
||||
<OutputPath>bin\iPhone\Debug</OutputPath> |
||||
<DefineConstants>DEBUG;ENABLE_TEST_CLOUD;</DefineConstants> |
||||
<ErrorReport>prompt</ErrorReport> |
||||
<WarningLevel>4</WarningLevel> |
||||
<CodesignKey>iPhone Developer</CodesignKey> |
||||
<DeviceSpecificBuild>true</DeviceSpecificBuild> |
||||
<MtouchDebug>true</MtouchDebug> |
||||
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip> |
||||
<MtouchFastDev>true</MtouchFastDev> |
||||
<MtouchFloat32>true</MtouchFloat32> |
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements> |
||||
<IOSDebuggerPort>35164</IOSDebuggerPort> |
||||
<MtouchLink>SdkOnly</MtouchLink> |
||||
<MtouchArch>ARM64</MtouchArch> |
||||
<MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler> |
||||
<PlatformTarget>x86</PlatformTarget> |
||||
</PropertyGroup> |
||||
<ItemGroup> |
||||
<Reference Include="System" /> |
||||
<Reference Include="System.Xml" /> |
||||
<Reference Include="System.Core" /> |
||||
<Reference Include="Xamarin.iOS" /> |
||||
<Reference Include="System.IO.Compression" /> |
||||
<Reference Include="System.Net.Http" /> |
||||
<Reference Include="System.Runtime.Loader"> |
||||
<HintPath>..\packages\System.Runtime.Loader.4.0.0\lib\netstandard1.5\System.Runtime.Loader.dll</HintPath> |
||||
</Reference> |
||||
<Reference Include="System.Interactive.Async"> |
||||
<HintPath>..\packages\System.Interactive.Async.3.1.1\lib\netstandard1.3\System.Interactive.Async.dll</HintPath> |
||||
</Reference> |
||||
<Reference Include="Grpc.Core"> |
||||
<HintPath>..\packages\Grpc.Core.1.15.0-dev\lib\netstandard1.5\Grpc.Core.dll</HintPath> |
||||
</Reference> |
||||
<Reference Include="Google.Protobuf"> |
||||
<HintPath>..\packages\Google.Protobuf.3.6.0\lib\netstandard1.0\Google.Protobuf.dll</HintPath> |
||||
</Reference> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json" /> |
||||
<ImageAsset Include="Assets.xcassets\Contents.json" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Folder Include="Resources\" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<InterfaceDefinition Include="LaunchScreen.storyboard" /> |
||||
<InterfaceDefinition Include="Main.storyboard" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<None Include="Info.plist" /> |
||||
<None Include="Entitlements.plist" /> |
||||
<None Include="packages.config" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Compile Include="Main.cs" /> |
||||
<Compile Include="AppDelegate.cs" /> |
||||
<Compile Include="ViewController.cs" /> |
||||
<Compile Include="ViewController.designer.cs"> |
||||
<DependentUpon>ViewController.cs</DependentUpon> |
||||
</Compile> |
||||
</ItemGroup> |
||||
<Import Project="..\HelloworldXamarin\HelloworldXamarin.projitems" Label="Shared" Condition="Exists('..\HelloworldXamarin\HelloworldXamarin.projitems')" /> |
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" /> |
||||
<Import Project="..\packages\Grpc.Core.1.15.0-dev\build\Xamarin.iOS\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.15.0-dev\build\Xamarin.iOS\Grpc.Core.targets')" /> |
||||
</Project> |
@ -0,0 +1,10 @@ |
||||
# GRPC Python setup requirements |
||||
coverage>=4.0 |
||||
cython==0.28.3 |
||||
enum34>=1.0.4 |
||||
protobuf>=3.5.0.post1 |
||||
six>=1.10 |
||||
wheel>=0.29 |
||||
futures>=2.2.0 |
||||
google-auth>=1.0.0 |
||||
oauth2client==4.1.0 |
@ -0,0 +1,59 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
#if GRPC_ARES == 1 && defined(GPR_WINDOWS) |
||||
|
||||
#include <ares.h> |
||||
#include <string.h> |
||||
#include "src/core/lib/gprpp/memory.h" |
||||
|
||||
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
/* TODO: fill in the body of GrpcPolledFdWindows to enable c-ares on Windows.
|
||||
This dummy implementation only allows grpc to compile on windows with |
||||
GRPC_ARES=1. */ |
||||
class GrpcPolledFdWindows : public GrpcPolledFd { |
||||
public: |
||||
GrpcPolledFdWindows() { abort(); } |
||||
~GrpcPolledFdWindows() { abort(); } |
||||
void RegisterForOnReadableLocked(grpc_closure* read_closure) override { |
||||
abort(); |
||||
} |
||||
void RegisterForOnWriteableLocked(grpc_closure* write_closure) override { |
||||
abort(); |
||||
} |
||||
bool IsFdStillReadableLocked() override { abort(); } |
||||
void ShutdownLocked(grpc_error* error) override { abort(); } |
||||
ares_socket_t GetWrappedAresSocketLocked() override { abort(); } |
||||
const char* GetName() override { abort(); } |
||||
}; |
||||
|
||||
GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as, |
||||
grpc_pollset_set* driver_pollset_set) { |
||||
return nullptr; |
||||
} |
||||
|
||||
void ConfigureAresChannelLocked(ares_channel* channel) { abort(); } |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif /* GRPC_ARES == 1 && defined(GPR_WINDOWS) */ |
@ -0,0 +1,29 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) |
||||
|
||||
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" |
||||
#include "src/core/lib/iomgr/socket_utils_posix.h" |
||||
|
||||
bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } |
||||
|
||||
#endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) */ |
@ -0,0 +1,29 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
#if GRPC_ARES == 1 && defined(GPR_WINDOWS) |
||||
|
||||
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" |
||||
#include "src/core/lib/iomgr/socket_windows.h" |
||||
|
||||
bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } |
||||
|
||||
#endif /* GRPC_ARES == 1 && defined(GPR_WINDOWS) */ |
@ -1,16 +1,22 @@ |
||||
This directory contains useful resources for getting gRPC C# to work on |
||||
not-yet-supported platforms. |
||||
platforms that are not yet fully supported. |
||||
|
||||
# Unity & Xamarin |
||||
gRPC C# currently doesn't support Unity or Xamarin, but some proof-of-concept |
||||
work has been done. Some of the resources are shared in this directory to |
||||
ease community work on Unity & Xamarin support. |
||||
# Xamarin |
||||
|
||||
## Crosscompiling `grpc_csharp_ext` for Android |
||||
gRPC C# now has experimental support for Xamarin. |
||||
See [HelloworldXamarin](/examples/csharp/HelloworldXamarin) for an example how to use it. |
||||
|
||||
* Install [Android NDK](https://developer.android.com/ndk/index.html) |
||||
* Run `./build_native_ext_for_android.sh` to crosscompile using cmake. |
||||
What's currently supported: |
||||
|
||||
## Crosscompiling `grpc_csharp_ext` for iOS |
||||
Xamarin.Android |
||||
- supported API level: Kitkat 4.4+ (= API level 19) |
||||
- supported ABIs: `armeabi-v7a` (vast majority of Android devices out there), |
||||
`arm64-v8a` (some newer Android devices), `x86` (for emulator) |
||||
|
||||
TBD |
||||
Xamarin.iOS |
||||
- supported architectures: arm64 (iPhone 6+) and x86_64 (iPhone simulator) |
||||
|
||||
# Unity |
||||
gRPC C# currently doesn't support Unity, but some proof-of-concept |
||||
work has been done. There is in-progress effort to provide users |
||||
with a pre-built gRPC package that can be used in their projects. |
||||
|
@ -0,0 +1,48 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
|
||||
// grpc_ipv6_loopback_available isn't currently available on UV.
|
||||
#ifndef GRPC_UV |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/log.h> |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
#ifdef GPR_WINDOWS |
||||
#include "src/core/lib/iomgr/socket_windows.h" |
||||
#else |
||||
#include "src/core/lib/iomgr/socket_utils_posix.h" |
||||
#endif |
||||
|
||||
int main(int argc, char** argv) { |
||||
grpc_test_init(argc, argv); |
||||
grpc_init(); |
||||
// This test assumes that the ipv6 loopback is available
|
||||
// in all environments in which grpc tests run in.
|
||||
GPR_ASSERT(grpc_ipv6_loopback_available()); |
||||
grpc_shutdown(); |
||||
return 0; |
||||
} |
||||
|
||||
#else |
||||
|
||||
int main(int argc, char** argv) { return 0; } |
||||
|
||||
#endif /* GRPC_UV */ |
@ -0,0 +1,29 @@ |
||||
# Adapted with modifications from tensorflow/third_party/cython.BUILD |
||||
|
||||
py_library( |
||||
name="cython_lib", |
||||
srcs=glob( |
||||
["Cython/**/*.py"], |
||||
exclude=[ |
||||
"**/Tests/*.py", |
||||
], |
||||
) + ["cython.py"], |
||||
data=glob([ |
||||
"Cython/**/*.pyx", |
||||
"Cython/Utility/*.*", |
||||
"Cython/Includes/**/*.pxd", |
||||
]), |
||||
srcs_version="PY2AND3", |
||||
visibility=["//visibility:public"], |
||||
) |
||||
|
||||
# May not be named "cython", since that conflicts with Cython/ on OSX |
||||
py_binary( |
||||
name="cython_binary", |
||||
srcs=["cython.py"], |
||||
main="cython.py", |
||||
srcs_version="PY2AND3", |
||||
visibility=["//visibility:public"], |
||||
deps=["cython_lib"], |
||||
) |
||||
|
@ -0,0 +1,36 @@ |
||||
# Adapted with modifications from tensorflow/third_party/py/ |
||||
|
||||
package(default_visibility=["//visibility:public"]) |
||||
|
||||
# To build Python C/C++ extension on Windows, we need to link to python import library pythonXY.lib |
||||
# See https://docs.python.org/3/extending/windows.html |
||||
cc_import( |
||||
name="python_lib", |
||||
interface_library=select({ |
||||
":windows": ":python_import_lib", |
||||
# A placeholder for Unix platforms which makes --no_build happy. |
||||
"//conditions:default": "not-existing.lib", |
||||
}), |
||||
system_provided=1, |
||||
) |
||||
|
||||
cc_library( |
||||
name="python_headers", |
||||
hdrs=[":python_include"], |
||||
deps=select({ |
||||
":windows": [":python_lib"], |
||||
"//conditions:default": [], |
||||
}), |
||||
includes=["python_include"], |
||||
) |
||||
|
||||
config_setting( |
||||
name="windows", |
||||
values={"cpu": "x64_windows"}, |
||||
visibility=["//visibility:public"], |
||||
) |
||||
|
||||
%{PYTHON_INCLUDE_GENRULE} |
||||
%{PYTHON_IMPORT_LIB_GENRULE} |
||||
|
||||
|
@ -0,0 +1,305 @@ |
||||
# Adapted with modifications from tensorflow/third_party/py/ |
||||
"""Repository rule for Python autoconfiguration. |
||||
|
||||
`python_configure` depends on the following environment variables: |
||||
|
||||
* `PYTHON_BIN_PATH`: location of python binary. |
||||
* `PYTHON_LIB_PATH`: Location of python libraries. |
||||
""" |
||||
|
||||
_BAZEL_SH = "BAZEL_SH" |
||||
_PYTHON_BIN_PATH = "PYTHON_BIN_PATH" |
||||
_PYTHON_LIB_PATH = "PYTHON_LIB_PATH" |
||||
_PYTHON_CONFIG_REPO = "PYTHON_CONFIG_REPO" |
||||
|
||||
|
||||
def _tpl(repository_ctx, tpl, substitutions={}, out=None): |
||||
if not out: |
||||
out = tpl |
||||
repository_ctx.template(out, Label("//third_party/py:%s.tpl" % tpl), |
||||
substitutions) |
||||
|
||||
|
||||
def _fail(msg): |
||||
"""Output failure message when auto configuration fails.""" |
||||
red = "\033[0;31m" |
||||
no_color = "\033[0m" |
||||
fail("%sPython Configuration Error:%s %s\n" % (red, no_color, msg)) |
||||
|
||||
|
||||
def _is_windows(repository_ctx): |
||||
"""Returns true if the host operating system is windows.""" |
||||
os_name = repository_ctx.os.name.lower() |
||||
return os_name.find("windows") != -1 |
||||
|
||||
|
||||
def _execute(repository_ctx, |
||||
cmdline, |
||||
error_msg=None, |
||||
error_details=None, |
||||
empty_stdout_fine=False): |
||||
"""Executes an arbitrary shell command. |
||||
|
||||
Args: |
||||
repository_ctx: the repository_ctx object |
||||
cmdline: list of strings, the command to execute |
||||
error_msg: string, a summary of the error if the command fails |
||||
error_details: string, details about the error or steps to fix it |
||||
empty_stdout_fine: bool, if True, an empty stdout result is fine, otherwise |
||||
it's an error |
||||
Return: |
||||
the result of repository_ctx.execute(cmdline) |
||||
""" |
||||
result = repository_ctx.execute(cmdline) |
||||
if result.stderr or not (empty_stdout_fine or result.stdout): |
||||
_fail("\n".join([ |
||||
error_msg.strip() if error_msg else "Repository command failed", |
||||
result.stderr.strip(), error_details if error_details else "" |
||||
])) |
||||
else: |
||||
return result |
||||
|
||||
|
||||
def _read_dir(repository_ctx, src_dir): |
||||
"""Returns a string with all files in a directory. |
||||
|
||||
Finds all files inside a directory, traversing subfolders and following |
||||
symlinks. The returned string contains the full path of all files |
||||
separated by line breaks. |
||||
""" |
||||
if _is_windows(repository_ctx): |
||||
src_dir = src_dir.replace("/", "\\") |
||||
find_result = _execute( |
||||
repository_ctx, |
||||
["cmd.exe", "/c", "dir", src_dir, "/b", "/s", "/a-d"], |
||||
empty_stdout_fine=True) |
||||
# src_files will be used in genrule.outs where the paths must |
||||
# use forward slashes. |
||||
return find_result.stdout.replace("\\", "/") |
||||
else: |
||||
find_result = _execute( |
||||
repository_ctx, ["find", src_dir, "-follow", "-type", "f"], |
||||
empty_stdout_fine=True) |
||||
return find_result.stdout |
||||
|
||||
|
||||
def _genrule(src_dir, genrule_name, command, outs): |
||||
"""Returns a string with a genrule. |
||||
|
||||
Genrule executes the given command and produces the given outputs. |
||||
""" |
||||
return ('genrule(\n' + ' name = "' + genrule_name + '",\n' + |
||||
' outs = [\n' + outs + '\n ],\n' + ' cmd = """\n' + |
||||
command + '\n """,\n' + ')\n') |
||||
|
||||
|
||||
def _normalize_path(path): |
||||
"""Returns a path with '/' and remove the trailing slash.""" |
||||
path = path.replace("\\", "/") |
||||
if path[-1] == "/": |
||||
path = path[:-1] |
||||
return path |
||||
|
||||
|
||||
def _symlink_genrule_for_dir(repository_ctx, |
||||
src_dir, |
||||
dest_dir, |
||||
genrule_name, |
||||
src_files=[], |
||||
dest_files=[]): |
||||
"""Returns a genrule to symlink(or copy if on Windows) a set of files. |
||||
|
||||
If src_dir is passed, files will be read from the given directory; otherwise |
||||
we assume files are in src_files and dest_files |
||||
""" |
||||
if src_dir != None: |
||||
src_dir = _normalize_path(src_dir) |
||||
dest_dir = _normalize_path(dest_dir) |
||||
files = '\n'.join( |
||||
sorted(_read_dir(repository_ctx, src_dir).splitlines())) |
||||
# Create a list with the src_dir stripped to use for outputs. |
||||
dest_files = files.replace(src_dir, '').splitlines() |
||||
src_files = files.splitlines() |
||||
command = [] |
||||
outs = [] |
||||
for i in range(len(dest_files)): |
||||
if dest_files[i] != "": |
||||
# If we have only one file to link we do not want to use the dest_dir, as |
||||
# $(@D) will include the full path to the file. |
||||
dest = '$(@D)/' + dest_dir + dest_files[i] if len( |
||||
dest_files) != 1 else '$(@D)/' + dest_files[i] |
||||
# On Windows, symlink is not supported, so we just copy all the files. |
||||
cmd = 'cp -f' if _is_windows(repository_ctx) else 'ln -s' |
||||
command.append(cmd + ' "%s" "%s"' % (src_files[i], dest)) |
||||
outs.append(' "' + dest_dir + dest_files[i] + '",') |
||||
return _genrule(src_dir, genrule_name, " && ".join(command), |
||||
"\n".join(outs)) |
||||
|
||||
|
||||
def _get_python_bin(repository_ctx): |
||||
"""Gets the python bin path.""" |
||||
python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH) |
||||
if python_bin != None: |
||||
return python_bin |
||||
python_bin_path = repository_ctx.which("python") |
||||
if python_bin_path != None: |
||||
return str(python_bin_path) |
||||
_fail("Cannot find python in PATH, please make sure " + |
||||
"python is installed and add its directory in PATH, or --define " + |
||||
"%s='/something/else'.\nPATH=%s" % |
||||
(_PYTHON_BIN_PATH, repository_ctx.os.environ.get("PATH", ""))) |
||||
|
||||
|
||||
def _get_bash_bin(repository_ctx): |
||||
"""Gets the bash bin path.""" |
||||
bash_bin = repository_ctx.os.environ.get(_BAZEL_SH) |
||||
if bash_bin != None: |
||||
return bash_bin |
||||
else: |
||||
bash_bin_path = repository_ctx.which("bash") |
||||
if bash_bin_path != None: |
||||
return str(bash_bin_path) |
||||
else: |
||||
_fail( |
||||
"Cannot find bash in PATH, please make sure " + |
||||
"bash is installed and add its directory in PATH, or --define " |
||||
+ "%s='/path/to/bash'.\nPATH=%s" % |
||||
(_BAZEL_SH, repository_ctx.os.environ.get("PATH", ""))) |
||||
|
||||
|
||||
def _get_python_lib(repository_ctx, python_bin): |
||||
"""Gets the python lib path.""" |
||||
python_lib = repository_ctx.os.environ.get(_PYTHON_LIB_PATH) |
||||
if python_lib != None: |
||||
return python_lib |
||||
print_lib = ( |
||||
"<<END\n" + "from __future__ import print_function\n" + |
||||
"import site\n" + "import os\n" + "\n" + "try:\n" + |
||||
" input = raw_input\n" + "except NameError:\n" + " pass\n" + "\n" + |
||||
"python_paths = []\n" + "if os.getenv('PYTHONPATH') is not None:\n" + |
||||
" python_paths = os.getenv('PYTHONPATH').split(':')\n" + "try:\n" + |
||||
" library_paths = site.getsitepackages()\n" + |
||||
"except AttributeError:\n" + |
||||
" from distutils.sysconfig import get_python_lib\n" + |
||||
" library_paths = [get_python_lib()]\n" + |
||||
"all_paths = set(python_paths + library_paths)\n" + "paths = []\n" + |
||||
"for path in all_paths:\n" + " if os.path.isdir(path):\n" + |
||||
" paths.append(path)\n" + "if len(paths) >=1:\n" + |
||||
" print(paths[0])\n" + "END") |
||||
cmd = '%s - %s' % (python_bin, print_lib) |
||||
result = repository_ctx.execute([_get_bash_bin(repository_ctx), "-c", cmd]) |
||||
return result.stdout.strip('\n') |
||||
|
||||
|
||||
def _check_python_lib(repository_ctx, python_lib): |
||||
"""Checks the python lib path.""" |
||||
cmd = 'test -d "%s" -a -x "%s"' % (python_lib, python_lib) |
||||
result = repository_ctx.execute([_get_bash_bin(repository_ctx), "-c", cmd]) |
||||
if result.return_code == 1: |
||||
_fail("Invalid python library path: %s" % python_lib) |
||||
|
||||
|
||||
def _check_python_bin(repository_ctx, python_bin): |
||||
"""Checks the python bin path.""" |
||||
cmd = '[[ -x "%s" ]] && [[ ! -d "%s" ]]' % (python_bin, python_bin) |
||||
result = repository_ctx.execute([_get_bash_bin(repository_ctx), "-c", cmd]) |
||||
if result.return_code == 1: |
||||
_fail("--define %s='%s' is not executable. Is it the python binary?" % |
||||
(_PYTHON_BIN_PATH, python_bin)) |
||||
|
||||
|
||||
def _get_python_include(repository_ctx, python_bin): |
||||
"""Gets the python include path.""" |
||||
result = _execute( |
||||
repository_ctx, [ |
||||
python_bin, "-c", 'from __future__ import print_function;' + |
||||
'from distutils import sysconfig;' + |
||||
'print(sysconfig.get_python_inc())' |
||||
], |
||||
error_msg="Problem getting python include path.", |
||||
error_details=( |
||||
"Is the Python binary path set up right? " + "(See ./configure or " |
||||
+ _PYTHON_BIN_PATH + ".) " + "Is distutils installed?")) |
||||
return result.stdout.splitlines()[0] |
||||
|
||||
|
||||
def _get_python_import_lib_name(repository_ctx, python_bin): |
||||
"""Get Python import library name (pythonXY.lib) on Windows.""" |
||||
result = _execute( |
||||
repository_ctx, [ |
||||
python_bin, "-c", |
||||
'import sys;' + 'print("python" + str(sys.version_info[0]) + ' + |
||||
' str(sys.version_info[1]) + ".lib")' |
||||
], |
||||
error_msg="Problem getting python import library.", |
||||
error_details=("Is the Python binary path set up right? " + |
||||
"(See ./configure or " + _PYTHON_BIN_PATH + ".) ")) |
||||
return result.stdout.splitlines()[0] |
||||
|
||||
|
||||
def _create_local_python_repository(repository_ctx): |
||||
"""Creates the repository containing files set up to build with Python.""" |
||||
python_bin = _get_python_bin(repository_ctx) |
||||
_check_python_bin(repository_ctx, python_bin) |
||||
python_lib = _get_python_lib(repository_ctx, python_bin) |
||||
_check_python_lib(repository_ctx, python_lib) |
||||
python_include = _get_python_include(repository_ctx, python_bin) |
||||
python_include_rule = _symlink_genrule_for_dir( |
||||
repository_ctx, python_include, 'python_include', 'python_include') |
||||
python_import_lib_genrule = "" |
||||
# To build Python C/C++ extension on Windows, we need to link to python import library pythonXY.lib |
||||
# See https://docs.python.org/3/extending/windows.html |
||||
if _is_windows(repository_ctx): |
||||
python_include = _normalize_path(python_include) |
||||
python_import_lib_name = _get_python_import_lib_name( |
||||
repository_ctx, python_bin) |
||||
python_import_lib_src = python_include.rsplit( |
||||
'/', 1)[0] + "/libs/" + python_import_lib_name |
||||
python_import_lib_genrule = _symlink_genrule_for_dir( |
||||
repository_ctx, None, '', 'python_import_lib', |
||||
[python_import_lib_src], [python_import_lib_name]) |
||||
_tpl( |
||||
repository_ctx, "BUILD", { |
||||
"%{PYTHON_INCLUDE_GENRULE}": python_include_rule, |
||||
"%{PYTHON_IMPORT_LIB_GENRULE}": python_import_lib_genrule, |
||||
}) |
||||
|
||||
|
||||
def _create_remote_python_repository(repository_ctx, remote_config_repo): |
||||
"""Creates pointers to a remotely configured repo set up to build with Python. |
||||
""" |
||||
_tpl(repository_ctx, "remote.BUILD", { |
||||
"%{REMOTE_PYTHON_REPO}": remote_config_repo, |
||||
}, "BUILD") |
||||
|
||||
|
||||
def _python_autoconf_impl(repository_ctx): |
||||
"""Implementation of the python_autoconf repository rule.""" |
||||
if _PYTHON_CONFIG_REPO in repository_ctx.os.environ: |
||||
_create_remote_python_repository( |
||||
repository_ctx, repository_ctx.os.environ[_PYTHON_CONFIG_REPO]) |
||||
else: |
||||
_create_local_python_repository(repository_ctx) |
||||
|
||||
|
||||
python_configure = repository_rule( |
||||
implementation=_python_autoconf_impl, |
||||
environ=[ |
||||
_BAZEL_SH, |
||||
_PYTHON_BIN_PATH, |
||||
_PYTHON_LIB_PATH, |
||||
_PYTHON_CONFIG_REPO, |
||||
], |
||||
) |
||||
"""Detects and configures the local Python. |
||||
|
||||
Add the following to your WORKSPACE FILE: |
||||
|
||||
```python |
||||
python_configure(name = "local_config_python") |
||||
``` |
||||
|
||||
Args: |
||||
name: A unique name for this workspace rule. |
||||
""" |
||||
|
@ -0,0 +1,10 @@ |
||||
# Adapted with modifications from tensorflow/third_party/py/ |
||||
|
||||
package(default_visibility=["//visibility:public"]) |
||||
|
||||
alias( |
||||
name="python_headers", |
||||
actual="%{REMOTE_PYTHON_REPO}:python_headers", |
||||
) |
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue