Allow protoc to be targeted by protogen explicitly.

Use that within the build for the address book sample.
pull/288/head
Jon Skeet 14 years ago
parent 445bdcebe7
commit da4989c4ed
  1. 2
      build/Common.targets
  2. 5
      build/build.csproj
  3. 5
      protos/tutorial/addressbook.proto
  4. 23
      src/AddressBook/AddressBookProtos.cs
  5. 52
      src/ProtoGen/ProgramPreprocess.cs

@ -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">

@ -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>

@ -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 {

@ -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" + "Chp0dXRvcmlhbC9hZGRyZXNzYm9vay5wcm90bxIIdHV0b3JpYWwi2gEKBlBl" +
"ZS9wcm90b2J1Zi9jc2hhcnBfb3B0aW9ucy5wcm90byLaAQoGUGVyc29uEgwK" + "cnNvbhIMCgRuYW1lGAEgAigJEgoKAmlkGAIgAigFEg0KBWVtYWlsGAMgASgJ" +
"BG5hbWUYASACKAkSCgoCaWQYAiACKAUSDQoFZW1haWwYAyABKAkSKwoFcGhv" + "EisKBXBob25lGAQgAygLMhwudHV0b3JpYWwuUGVyc29uLlBob25lTnVtYmVy" +
"bmUYBCADKAsyHC50dXRvcmlhbC5QZXJzb24uUGhvbmVOdW1iZXIaTQoLUGhv" + "Gk0KC1Bob25lTnVtYmVyEg4KBm51bWJlchgBIAIoCRIuCgR0eXBlGAIgASgO" +
"bmVOdW1iZXISDgoGbnVtYmVyGAEgAigJEi4KBHR5cGUYAiABKA4yGi50dXRv" + "MhoudHV0b3JpYWwuUGVyc29uLlBob25lVHlwZToESE9NRSIrCglQaG9uZVR5" +
"cmlhbC5QZXJzb24uUGhvbmVUeXBlOgRIT01FIisKCVBob25lVHlwZRIKCgZN" + "cGUSCgoGTU9CSUxFEAASCAoESE9NRRABEggKBFdPUksQAiIvCgtBZGRyZXNz" +
"T0JJTEUQABIICgRIT01FEAESCAoEV09SSxACIi8KC0FkZHJlc3NCb29rEiAK" + "Qm9vaxIgCgZwZXJzb24YASADKAsyEC50dXRvcmlhbC5QZXJzb25CAkgB");
"BnBlcnNvbhgBIAMoCzIQLnR1dG9yaWFsLlBlcnNvbkJFSAHCPkAKK0dvb2ds" +
"ZS5Qcm90b2NvbEJ1ZmZlcnMuRXhhbXBsZXMuQWRkcmVzc0Jvb2sSEUFkZHJl" +
"c3NCb29rUHJvdG9z");
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(); return null;
RegisterAllExtensions(registry);
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
return registry;
}; };
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] { new pbd::FileDescriptor[] {
global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor,
}, assigner); }, assigner);
} }
#endregion #endregion

@ -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 + throw new FileNotFoundException(
" make sure it is in the PATH, cwd, or exe dir."); "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;

Loading…
Cancel
Save