فهرست منبع

Allow protoc to be targeted by protogen explicitly.
Use that within the build for the address book sample.

Jon Skeet 14 سال پیش
والد
کامیت
da4989c4ed
5فایلهای تغییر یافته به همراه52 افزوده شده و 35 حذف شده
  1. 2 0
      build/Common.targets
  2. 2 3
      build/build.csproj
  3. 0 5
      protos/tutorial/addressbook.proto
  4. 8 15
      src/AddressBook/AddressBookProtos.cs
  5. 40 12
      src/ProtoGen/ProgramPreprocess.cs

+ 2 - 0
build/Common.targets

@@ -27,6 +27,8 @@
   <Target Name="_GenerateSource">
     <Exec Command="$(ProtocExePath) --proto_path=$(ProtosDirectory) --descriptor_set_out=compiled.pb @(Protos->'%(RelativeDir)%(Filename)%(Extension)', ' ')" WorkingDirectory="$(BuildTempDirectory)" />
     <Exec Command="$(ProtogenExePath) compiled.pb" WorkingDirectory="$(BuildTempDirectory)" />
+    <!-- Generate the AddressBookProtos.cs directly -->
+    <Exec Command="$(ProtogenExePath) --protoc_dir=$(LibDirectory) --proto_path=$(ProtosDirectory) $(ProtosDirectory)\tutorial\addressbook.proto -namespace=Google.ProtocolBuffers.Examples.AddressBook -umbrella_classname=AddressBookProtos" WorkingDirectory="$(BuildTempDirectory)" />
   </Target>
 
   <Target Name="_CopyGeneratedSource" DependsOnTargets="_GenerateSource">

+ 2 - 3
build/build.csproj

@@ -54,9 +54,8 @@
     <Protos Include="$(ProtosDirectory)\google\protobuf\unittest_mset.proto" />
     <Protos Include="$(ProtosDirectory)\google\protobuf\unittest_no_generic_services.proto" />
     <Protos Include="$(ProtosDirectory)\google\protobuf\unittest_optimize_for.proto" />
-    <Protos Include="$(ProtosDirectory)\tutorial\addressbook.proto" />
 
-        <!-- Main protos -->
+    <!-- Main protos -->
     <GeneratedSource Include="$(BuildTempDirectory)\CSharpOptions.cs">
       <TargetDirectory>$(SourceDirectory)\ProtocolBuffers\DescriptorProtos</TargetDirectory>
     </GeneratedSource>
@@ -64,7 +63,7 @@
       <TargetDirectory>$(SourceDirectory)\ProtocolBuffers\DescriptorProtos</TargetDirectory>
     </GeneratedSource>
         
-        <!-- Address book sample -->
+    <!-- Address book sample -->
     <GeneratedSource Include="$(BuildTempDirectory)\AddressBookProtos.cs">
       <TargetDirectory>$(SourceDirectory)\AddressBook</TargetDirectory>
     </GeneratedSource>

+ 0 - 5
protos/tutorial/addressbook.proto

@@ -1,10 +1,5 @@
 package tutorial;
  
-import "google/protobuf/csharp_options.proto";
-
-option (google.protobuf.csharp_file_options).namespace = "Google.ProtocolBuffers.Examples.AddressBook";
-option (google.protobuf.csharp_file_options).umbrella_classname = "AddressBookProtos";
-
 option optimize_for = SPEED;
 
 message Person {

+ 8 - 15
src/AddressBook/AddressBookProtos.cs

@@ -31,16 +31,13 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     
     static AddressBookProtos() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
-          "Chp0dXRvcmlhbC9hZGRyZXNzYm9vay5wcm90bxIIdHV0b3JpYWwaJGdvb2ds" + 
-          "ZS9wcm90b2J1Zi9jc2hhcnBfb3B0aW9ucy5wcm90byLaAQoGUGVyc29uEgwK" + 
-          "BG5hbWUYASACKAkSCgoCaWQYAiACKAUSDQoFZW1haWwYAyABKAkSKwoFcGhv" + 
-          "bmUYBCADKAsyHC50dXRvcmlhbC5QZXJzb24uUGhvbmVOdW1iZXIaTQoLUGhv" + 
-          "bmVOdW1iZXISDgoGbnVtYmVyGAEgAigJEi4KBHR5cGUYAiABKA4yGi50dXRv" + 
-          "cmlhbC5QZXJzb24uUGhvbmVUeXBlOgRIT01FIisKCVBob25lVHlwZRIKCgZN" + 
-          "T0JJTEUQABIICgRIT01FEAESCAoEV09SSxACIi8KC0FkZHJlc3NCb29rEiAK" + 
-          "BnBlcnNvbhgBIAMoCzIQLnR1dG9yaWFsLlBlcnNvbkJFSAHCPkAKK0dvb2ds" + 
-          "ZS5Qcm90b2NvbEJ1ZmZlcnMuRXhhbXBsZXMuQWRkcmVzc0Jvb2sSEUFkZHJl" + 
-          "c3NCb29rUHJvdG9z");
+          "Chp0dXRvcmlhbC9hZGRyZXNzYm9vay5wcm90bxIIdHV0b3JpYWwi2gEKBlBl" + 
+          "cnNvbhIMCgRuYW1lGAEgAigJEgoKAmlkGAIgAigFEg0KBWVtYWlsGAMgASgJ" + 
+          "EisKBXBob25lGAQgAygLMhwudHV0b3JpYWwuUGVyc29uLlBob25lTnVtYmVy" + 
+          "Gk0KC1Bob25lTnVtYmVyEg4KBm51bWJlchgBIAIoCRIuCgR0eXBlGAIgASgO" + 
+          "MhoudHV0b3JpYWwuUGVyc29uLlBob25lVHlwZToESE9NRSIrCglQaG9uZVR5" + 
+          "cGUSCgoGTU9CSUxFEAASCAoESE9NRRABEggKBFdPUksQAiIvCgtBZGRyZXNz" + 
+          "Qm9vaxIgCgZwZXJzb24YASADKAsyEC50dXRvcmlhbC5QZXJzb25CAkgB");
       pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
         descriptor = root;
         internal__static_tutorial_Person__Descriptor = Descriptor.MessageTypes[0];
@@ -55,14 +52,10 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
         internal__static_tutorial_AddressBook__FieldAccessorTable = 
             new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook, global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook.Builder>(internal__static_tutorial_AddressBook__Descriptor,
                 new string[] { "Person", });
-        pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
-        RegisterAllExtensions(registry);
-        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
-        return registry;
+        return null;
       };
       pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
           new pbd::FileDescriptor[] {
-          global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, 
           }, assigner);
     }
     #endregion

+ 40 - 12
src/ProtoGen/ProgramPreprocess.cs

@@ -14,6 +14,9 @@ namespace Google.ProtocolBuffers.ProtoGen
     /// </summary>
     public class ProgramPreprocess
     {
+        const string ProtocExecutable = "protoc.exe";
+        const string ProtocDirectoryArg = "--protoc_dir=";
+
         private static int Main(string[] args)
         {
             try
@@ -38,6 +41,8 @@ namespace Google.ProtocolBuffers.ProtoGen
                 List<string> protocArgs = new List<string>();
                 List<string> protoGenArgs = new List<string>();
 
+                string protocFile = GuessProtocFile(args);
+
                 foreach (string arg in args)
                 {
                     doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/?");
@@ -59,7 +64,7 @@ namespace Google.ProtocolBuffers.ProtoGen
                     Console.WriteLine();
                     try
                     {
-                        RunProtoc("--help");
+                        RunProtoc(protocFile, "--help");
                     }
                     catch (Exception ex)
                     {
@@ -71,11 +76,19 @@ namespace Google.ProtocolBuffers.ProtoGen
                         "PROTOGEN.exe: The following options are used to specify defaults for code generation.");
                     Console.WriteLine();
                     Program.Main(new string[0]);
+                    Console.WriteLine();
+                    Console.WriteLine("The following option enables PROTOGEN.exe to find PROTOC.exe");
+                    Console.WriteLine("{0}<directory containing protoc.exe>", ProtocDirectoryArg);
                     return 0;
                 }
 
                 foreach (string arg in args)
                 {
+                    if (arg.StartsWith(ProtocDirectoryArg))
+                    {
+                        // Handled earlier
+                        continue;
+                    }
                     if (arg.StartsWith("--"))
                     {
                         protocArgs.Add(arg);
@@ -100,7 +113,7 @@ namespace Google.ProtocolBuffers.ProtoGen
 
                 if (tempFile != null)
                 {
-                    result = RunProtoc(protocArgs.ToArray());
+                    result = RunProtoc(protocFile, protocArgs.ToArray());
                     if (result != 0)
                     {
                         return result;
@@ -119,29 +132,44 @@ namespace Google.ProtocolBuffers.ProtoGen
             return result;
         }
 
-        private static int RunProtoc(params string[] args)
+        /// <summary>
+        /// Tries to work out where protoc is based on command line arguments, the current
+        /// directory, the directory containing protogen, and the path.
+        /// </summary>
+        /// <returns>The path to protoc.exe, or null if it can't be found.</returns>
+        private static string GuessProtocFile(params string[] args)
         {
-            const string protoc = "protoc.exe";
-            string exePath = protoc;
-
             // Why oh why is this not in System.IO.Path or Environment...?
             List<string> searchPath = new List<string>();
+            foreach (string arg in args)
+            {
+                if (arg.StartsWith("--protoc_dir="))
+                {
+                    searchPath.Add(arg.Substring(ProtocDirectoryArg.Length));
+                }
+            }
             searchPath.Add(Environment.CurrentDirectory);
             searchPath.Add(AppDomain.CurrentDomain.BaseDirectory);
             searchPath.AddRange((Environment.GetEnvironmentVariable("PATH") ?? String.Empty).Split(Path.PathSeparator));
 
             foreach (string path in searchPath)
             {
-                if (File.Exists(exePath = Path.Combine(path, protoc)))
+                string exeFile = Path.Combine(path, ProtocExecutable); 
+                if (File.Exists(exeFile))
                 {
-                    break;
+                    return exeFile;
                 }
             }
+            return null;
+        }
 
-            if (!File.Exists(exePath))
+        private static int RunProtoc(string exeFile, params string[] args)
+        {
+            if (exeFile == null)
             {
-                throw new FileNotFoundException("Unable to locate " + protoc +
-                                                " make sure it is in the PATH, cwd, or exe dir.");
+                throw new FileNotFoundException(
+                    "Unable to locate " + ProtocExecutable +
+                    " make sure it is in the PATH, cwd, or exe dir, or use --protoc_dir=...");
             }
 
             for (int i = 0; i < args.Length; i++)
@@ -152,7 +180,7 @@ namespace Google.ProtocolBuffers.ProtoGen
                 }
             }
 
-            ProcessStartInfo psi = new ProcessStartInfo(exePath);
+            ProcessStartInfo psi = new ProcessStartInfo(exeFile);
             psi.Arguments = String.Join(" ", args);
             psi.RedirectStandardError = true;
             psi.RedirectStandardInput = false;