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

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

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

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

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

Loading…
Cancel
Save