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