Pārlūkot izejas kodu

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

Jon Skeet 14 gadi atpakaļ
vecāks
revīzija
da4989c4ed

+ 2 - 0
build/Common.targets

@@ -27,6 +27,8 @@
   <Target Name="_GenerateSource">
   <Target Name="_GenerateSource">
     <Exec Command="$(ProtocExePath) --proto_path=$(ProtosDirectory) --descriptor_set_out=compiled.pb @(Protos->'%(RelativeDir)%(Filename)%(Extension)', ' ')" WorkingDirectory="$(BuildTempDirectory)" />
     <Exec Command="$(ProtocExePath) --proto_path=$(ProtosDirectory) --descriptor_set_out=compiled.pb @(Protos->'%(RelativeDir)%(Filename)%(Extension)', ' ')" WorkingDirectory="$(BuildTempDirectory)" />
     <Exec Command="$(ProtogenExePath) compiled.pb" 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>
 
 
   <Target Name="_CopyGeneratedSource" DependsOnTargets="_GenerateSource">
   <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_mset.proto" />
     <Protos Include="$(ProtosDirectory)\google\protobuf\unittest_no_generic_services.proto" />
     <Protos Include="$(ProtosDirectory)\google\protobuf\unittest_no_generic_services.proto" />
     <Protos Include="$(ProtosDirectory)\google\protobuf\unittest_optimize_for.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">
     <GeneratedSource Include="$(BuildTempDirectory)\CSharpOptions.cs">
       <TargetDirectory>$(SourceDirectory)\ProtocolBuffers\DescriptorProtos</TargetDirectory>
       <TargetDirectory>$(SourceDirectory)\ProtocolBuffers\DescriptorProtos</TargetDirectory>
     </GeneratedSource>
     </GeneratedSource>
@@ -64,7 +63,7 @@
       <TargetDirectory>$(SourceDirectory)\ProtocolBuffers\DescriptorProtos</TargetDirectory>
       <TargetDirectory>$(SourceDirectory)\ProtocolBuffers\DescriptorProtos</TargetDirectory>
     </GeneratedSource>
     </GeneratedSource>
         
         
-        <!-- Address book sample -->
+    <!-- Address book sample -->
     <GeneratedSource Include="$(BuildTempDirectory)\AddressBookProtos.cs">
     <GeneratedSource Include="$(BuildTempDirectory)\AddressBookProtos.cs">
       <TargetDirectory>$(SourceDirectory)\AddressBook</TargetDirectory>
       <TargetDirectory>$(SourceDirectory)\AddressBook</TargetDirectory>
     </GeneratedSource>
     </GeneratedSource>

+ 0 - 5
protos/tutorial/addressbook.proto

@@ -1,10 +1,5 @@
 package tutorial;
 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;
 option optimize_for = SPEED;
 
 
 message Person {
 message Person {

+ 8 - 15
src/AddressBook/AddressBookProtos.cs

@@ -31,16 +31,13 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     
     
     static AddressBookProtos() {
     static AddressBookProtos() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
       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) {
       pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
         descriptor = root;
         descriptor = root;
         internal__static_tutorial_Person__Descriptor = Descriptor.MessageTypes[0];
         internal__static_tutorial_Person__Descriptor = Descriptor.MessageTypes[0];
@@ -55,14 +52,10 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
         internal__static_tutorial_AddressBook__FieldAccessorTable = 
         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 pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook, global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook.Builder>(internal__static_tutorial_AddressBook__Descriptor,
                 new string[] { "Person", });
                 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,
       pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
           new pbd::FileDescriptor[] {
           new pbd::FileDescriptor[] {
-          global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, 
           }, assigner);
           }, assigner);
     }
     }
     #endregion
     #endregion

+ 40 - 12
src/ProtoGen/ProgramPreprocess.cs

@@ -14,6 +14,9 @@ namespace Google.ProtocolBuffers.ProtoGen
     /// </summary>
     /// </summary>
     public class ProgramPreprocess
     public class ProgramPreprocess
     {
     {
+        const string ProtocExecutable = "protoc.exe";
+        const string ProtocDirectoryArg = "--protoc_dir=";
+
         private static int Main(string[] args)
         private static int Main(string[] args)
         {
         {
             try
             try
@@ -38,6 +41,8 @@ namespace Google.ProtocolBuffers.ProtoGen
                 List<string> protocArgs = new List<string>();
                 List<string> protocArgs = new List<string>();
                 List<string> protoGenArgs = new List<string>();
                 List<string> protoGenArgs = new List<string>();
 
 
+                string protocFile = GuessProtocFile(args);
+
                 foreach (string arg in args)
                 foreach (string arg in args)
                 {
                 {
                     doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/?");
                     doHelp |= StringComparer.OrdinalIgnoreCase.Equals(arg, "/?");
@@ -59,7 +64,7 @@ namespace Google.ProtocolBuffers.ProtoGen
                     Console.WriteLine();
                     Console.WriteLine();
                     try
                     try
                     {
                     {
-                        RunProtoc("--help");
+                        RunProtoc(protocFile, "--help");
                     }
                     }
                     catch (Exception ex)
                     catch (Exception ex)
                     {
                     {
@@ -71,11 +76,19 @@ namespace Google.ProtocolBuffers.ProtoGen
                         "PROTOGEN.exe: The following options are used to specify defaults for code generation.");
                         "PROTOGEN.exe: The following options are used to specify defaults for code generation.");
                     Console.WriteLine();
                     Console.WriteLine();
                     Program.Main(new string[0]);
                     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;
                     return 0;
                 }
                 }
 
 
                 foreach (string arg in args)
                 foreach (string arg in args)
                 {
                 {
+                    if (arg.StartsWith(ProtocDirectoryArg))
+                    {
+                        // Handled earlier
+                        continue;
+                    }
                     if (arg.StartsWith("--"))
                     if (arg.StartsWith("--"))
                     {
                     {
                         protocArgs.Add(arg);
                         protocArgs.Add(arg);
@@ -100,7 +113,7 @@ namespace Google.ProtocolBuffers.ProtoGen
 
 
                 if (tempFile != null)
                 if (tempFile != null)
                 {
                 {
-                    result = RunProtoc(protocArgs.ToArray());
+                    result = RunProtoc(protocFile, protocArgs.ToArray());
                     if (result != 0)
                     if (result != 0)
                     {
                     {
                         return result;
                         return result;
@@ -119,29 +132,44 @@ namespace Google.ProtocolBuffers.ProtoGen
             return result;
             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...?
             // Why oh why is this not in System.IO.Path or Environment...?
             List<string> searchPath = new List<string>();
             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(Environment.CurrentDirectory);
             searchPath.Add(AppDomain.CurrentDomain.BaseDirectory);
             searchPath.Add(AppDomain.CurrentDomain.BaseDirectory);
             searchPath.AddRange((Environment.GetEnvironmentVariable("PATH") ?? String.Empty).Split(Path.PathSeparator));
             searchPath.AddRange((Environment.GetEnvironmentVariable("PATH") ?? String.Empty).Split(Path.PathSeparator));
 
 
             foreach (string path in searchPath)
             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++)
             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.Arguments = String.Join(" ", args);
             psi.RedirectStandardError = true;
             psi.RedirectStandardError = true;
             psi.RedirectStandardInput = false;
             psi.RedirectStandardInput = false;