static string TempName(Depfile file, string fileName, string ext) { return file.TempDir + "/" + Path.GetFileNameWithoutExtension (fileName) + ext; }
static string ObjectName(Depfile file, string fileName) { return TempName(file, fileName, ".o"); }
public static int Main(string[] args) { switch (args.Length) { case 2: dstfile = args [1]; goto case 1; case 1: // Copy depfile to project folder srcfile = args [0]; break; } string[] deps = File.ReadAllLines (srcfile); string appendix = ""; Depfile depfile = new Depfile (); Type type = depfile.GetType (); bool parsingAppendix = false; foreach (var line in deps) { if (parsingAppendix) { appendix += line + "\n"; continue; } string dep = line.Trim (); if (dep.StartsWith ("#")) { continue; } if (dep.Length == 0) { continue; } if (dep == "--") { parsingAppendix = true; continue; } string key = null; string value = null; if (line.Contains ("=")) { key = line.Substring (0, line.IndexOf ("=")).Trim (); value = line.Substring (line.IndexOf ("=") + 1).Trim (); } else { key = line; } PropertyInfo prop = type.GetProperty (key); if (prop == null) { Console.WriteLine ("{0} is not recognized.", key); continue; } if (value == null) { // Flags if (prop.PropertyType == typeof(bool)) { prop.SetValue (depfile, true); } else { Console.WriteLine ("Invalid flag: {0}", key); } } else { if (prop.PropertyType == typeof(string)) { prop.SetValue (depfile, value); } else if (prop.PropertyType == typeof(IList<string>)) { IList<string> list = prop.GetValue (depfile) as IList<string>; foreach (var item in value.Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries)) { list.Add (item); } } else if (prop.PropertyType == typeof(bool)) { prop.SetValue (depfile, value == "true"); } else { Console.WriteLine ("Invalid property: {0}", key); } } } // Process file list foreach(string file in depfile.SourceDir.SelectMany(x => GetFiles(x, "*.c;*.cpp;*.asm;*.S;*.l;*.y", SearchOption.AllDirectories))) { depfile.Files.Add (file); } List<string> articfacts = new List<string> (); Dictionary<string, string> movedIncludeFolder = new Dictionary<string, string> (); // First, gather all lex/yacc files var lexfiles = depfile.Files.Where (x => x.EndsWith (".l")).ToArray(); var yaccfiles = depfile.Files.Where (x => x.EndsWith (".y")).ToArray(); // Then generate the fititng output file names foreach (var file in lexfiles) { var name = TempName (depfile, file, depfile.LexUseCpp ? ".yy.cpp" : ".yy.c"); depfile.Files.Add(name); articfacts.Add (name); movedIncludeFolder.Add (name, Path.GetDirectoryName (file)); } foreach (var file in yaccfiles) { var name = TempName (depfile, file, depfile.YaccUseCpp ? ".tab.cpp" : ".tab.c"); depfile.Files.Add(name); articfacts.Add (name); movedIncludeFolder.Add (name, Path.GetDirectoryName (file)); } // Last gather rest of the files var objs = depfile.Files.Where(x => !(x.EndsWith(".y") || x.EndsWith(".l"))).Select (x => ObjectName(depfile, x)).Concat(depfile.AdditionalObjects); var asfiles = depfile.Files.Where (x => x.EndsWith (".S") || x.EndsWith (".asm")); var cfiles = depfile.Files.Where (x => x.EndsWith (".c")); var cppfiles = depfile.Files.Where (x => x.EndsWith (".cpp")); articfacts.AddRange (objs); using (var writer = new StreamWriter (File.Open(dstfile, FileMode.Create, FileAccess.Write), Encoding.UTF8)) { writer.WriteLine ("# Makefile generated by makedep."); writer.WriteLine (); writer.WriteLine ("# Tools"); writer.WriteLine ("RM = rm"); writer.WriteLine ("AS = {0}", depfile.AS ?? "gcc"); writer.WriteLine ("CC = {0}", depfile.CC ?? "gcc"); writer.WriteLine ("CXX = {0}", depfile.CXX ?? "g++"); writer.WriteLine ("LD = {0}", depfile.LD ?? "gcc"); writer.WriteLine ("LEX = {0}", depfile.LEX ?? "lex"); writer.WriteLine ("YACC = {0}", depfile.YACC ?? "yacc"); writer.WriteLine (); writer.WriteLine ("# File Lists"); writer.WriteLine ("SRCS_AS = {0}", string.Join (" ", asfiles)); writer.WriteLine ("SRCS_CC = {0}", string.Join (" ", cfiles)); writer.WriteLine ("SRCS_CXX = {0}", string.Join (" ", cppfiles)); writer.WriteLine ("OBJS = {0}", string.Join (" ", objs)); writer.WriteLine (); writer.WriteLine ("# Flags"); writer.WriteLine ("FLAGS = {0}", depfile.FLAGS); writer.WriteLine ("ASFLAGS = {0}", depfile.ASFLAGS); writer.WriteLine ("CCFLAGS = {0}", depfile.CCFLAGS); writer.WriteLine ("CXXFLAGS = {0}", depfile.CXXFLAGS); writer.WriteLine ("LDFLAGS = {0}", depfile.LDFLAGS); writer.WriteLine (); writer.WriteLine ("# Targets"); writer.WriteLine ("all: {0}", depfile.Artifact); writer.WriteLine (); writer.WriteLine (".PHONY: clean"); writer.WriteLine ("clean:"); writer.WriteLine ("\t$(RM) {0}", string.Join (" ", articfacts)); writer.WriteLine (); // Creating linker call { var objects = new List<string> (); foreach (var file in objs.Concat(depfile.ExternalObjects)) { if (file.Contains("|")) { var t = file.Split ('|'); objects.AddRange(Directory.GetFiles (t [0], t [1])); } else { objects.Add (file); } } writer.WriteLine ("{0}: {1}", depfile.Artifact, string.Join (" ", objects)); writer.WriteLine ("\t$(LD) $(FLAGS) $(LDFLAGS) -o $@ {1}", depfile.Artifact, string.Join (" ", objects)); writer.WriteLine (); } // Create c section foreach (var file in cfiles) { string obj = ObjectName (depfile, file); string specialCommands = ""; if (movedIncludeFolder.ContainsKey (file)) { specialCommands = "-iquote" + movedIncludeFolder [file]; } specialCommands += "-iquoteobj "; string dependencies = obj + ": " +file + "\n"; if(File.Exists(file)) { Process proc = Process.Start (new ProcessStartInfo ("gcc", specialCommands + " -std=c11 -MM -Iinclude " + file) { UseShellExecute = false, RedirectStandardOutput = true, }); proc.WaitForExit (); if (proc.ExitCode != 0) { return proc.ExitCode; } dependencies = proc.StandardOutput.ReadToEnd (); dependencies = dependencies.Replace (Path.GetFileNameWithoutExtension(file) + ".o", obj); } // Write target with dependencies writer.WriteLine("# {0}", file); writer.Write (dependencies); // Has a newline already writer.WriteLine ("\t$(CC) {2} $(FLAGS) $(CCFLAGS) -o $@ -c {1}", depfile.Artifact, file, specialCommands); writer.WriteLine (); } // Create c++ section foreach (var file in cppfiles) { string obj = ObjectName (depfile, file); string specialCommands = ""; if (movedIncludeFolder.ContainsKey (file)) { specialCommands = "-iquote" + movedIncludeFolder [file] + " "; } specialCommands += "-iquoteobj "; string dependencies = obj + ": " + file + "\n"; if(File.Exists(file)) { Process proc = Process.Start (new ProcessStartInfo ("g++", specialCommands + " -std=c++11 -MM -Iinclude " + file) { UseShellExecute = false, RedirectStandardOutput = true, }); proc.WaitForExit (); if (proc.ExitCode != 0) { return proc.ExitCode; } dependencies = proc.StandardOutput.ReadToEnd (); dependencies = dependencies.Replace (Path.GetFileNameWithoutExtension(file) + ".o", obj); } // Write target with dependencies writer.WriteLine("# {0}", file); writer.Write (dependencies); // Has a newline already writer.WriteLine ("\t$(CXX) {2} $(FLAGS) $(CXXFLAGS) -o $@ -c {1}", depfile.Artifact, file, specialCommands); writer.WriteLine (); } // Create assembler section foreach (var file in asfiles) { string obj = ObjectName (depfile, file); // Write target with dependencies writer.WriteLine("# {0}", file); writer.WriteLine ("{0}: {1}", obj, file); // Has a newline already writer.WriteLine ("\t$(AS) $(FLAGS) $(ASFLAGS) -o $@ -c {1}", depfile.Artifact, file); writer.WriteLine (); } foreach (var file in lexfiles) { string cfile = TempName (depfile, file, depfile.LexUseCpp ? ".yy.cpp" : ".yy.c"); writer.WriteLine ("{0}: {1}", cfile, file); writer.WriteLine ("\t$(LEX) --header-file={0} -o {1} -d {2}", file + ".h", cfile, file); writer.WriteLine (); } foreach (var file in yaccfiles) { string cfile = TempName (depfile, file, depfile.YaccUseCpp ? ".tab.cpp" : ".tab.c"); writer.WriteLine ("{0}: {1}", cfile, file); writer.WriteLine ("\t$(YACC) -o {0} -d {1}", cfile, file); writer.WriteLine (); } if (appendix.Length > 0) { writer.WriteLine ("# Custom Targets"); writer.Write (appendix); } } return 0; }
static string TempName(Depfile file, string fileName, string ext) { return(file.TempDir + "/" + Path.GetFileNameWithoutExtension(fileName) + ext); }
static string ObjectName(Depfile file, string fileName) { return(TempName(file, fileName, ".o")); }
public static int Main(string[] args) { switch (args.Length) { case 2: dstfile = args [1]; goto case 1; case 1: // Copy depfile to project folder srcfile = args [0]; break; } string[] deps = File.ReadAllLines(srcfile); string appendix = ""; Depfile depfile = new Depfile(); Type type = depfile.GetType(); bool parsingAppendix = false; foreach (var line in deps) { if (parsingAppendix) { appendix += line + "\n"; continue; } string dep = line.Trim(); if (dep.StartsWith("#")) { continue; } if (dep.Length == 0) { continue; } if (dep == "--") { parsingAppendix = true; continue; } string key = null; string value = null; if (line.Contains("=")) { key = line.Substring(0, line.IndexOf("=")).Trim(); value = line.Substring(line.IndexOf("=") + 1).Trim(); } else { key = line; } PropertyInfo prop = type.GetProperty(key); if (prop == null) { Console.WriteLine("{0} is not recognized.", key); continue; } if (value == null) { // Flags if (prop.PropertyType == typeof(bool)) { prop.SetValue(depfile, true); } else { Console.WriteLine("Invalid flag: {0}", key); } } else { if (prop.PropertyType == typeof(string)) { prop.SetValue(depfile, value); } else if (prop.PropertyType == typeof(IList <string>)) { IList <string> list = prop.GetValue(depfile) as IList <string>; foreach (var item in value.Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries)) { list.Add(item); } } else if (prop.PropertyType == typeof(bool)) { prop.SetValue(depfile, value == "true"); } else { Console.WriteLine("Invalid property: {0}", key); } } } // Process file list foreach (string file in depfile.SourceDir.SelectMany(x => GetFiles(x, "*.c;*.cpp;*.asm;*.S;*.l;*.y", SearchOption.AllDirectories))) { depfile.Files.Add(file); } List <string> articfacts = new List <string> (); Dictionary <string, string> movedIncludeFolder = new Dictionary <string, string> (); // First, gather all lex/yacc files var lexfiles = depfile.Files.Where(x => x.EndsWith(".l")).ToArray(); var yaccfiles = depfile.Files.Where(x => x.EndsWith(".y")).ToArray(); // Then generate the fititng output file names foreach (var file in lexfiles) { var name = TempName(depfile, file, depfile.LexUseCpp ? ".yy.cpp" : ".yy.c"); depfile.Files.Add(name); articfacts.Add(name); movedIncludeFolder.Add(name, Path.GetDirectoryName(file)); } foreach (var file in yaccfiles) { var name = TempName(depfile, file, depfile.YaccUseCpp ? ".tab.cpp" : ".tab.c"); depfile.Files.Add(name); articfacts.Add(name); movedIncludeFolder.Add(name, Path.GetDirectoryName(file)); } // Last gather rest of the files var objs = depfile.Files.Where(x => !(x.EndsWith(".y") || x.EndsWith(".l"))).Select(x => ObjectName(depfile, x)).Concat(depfile.AdditionalObjects); var asfiles = depfile.Files.Where(x => x.EndsWith(".S") || x.EndsWith(".asm")); var cfiles = depfile.Files.Where(x => x.EndsWith(".c")); var cppfiles = depfile.Files.Where(x => x.EndsWith(".cpp")); articfacts.AddRange(objs); using (var writer = new StreamWriter(File.Open(dstfile, FileMode.Create, FileAccess.Write), Encoding.UTF8)) { writer.WriteLine("# Makefile generated by makedep."); writer.WriteLine(); writer.WriteLine("# Tools"); writer.WriteLine("RM = rm"); writer.WriteLine("AS = {0}", depfile.AS ?? "gcc"); writer.WriteLine("CC = {0}", depfile.CC ?? "gcc"); writer.WriteLine("CXX = {0}", depfile.CXX ?? "g++"); writer.WriteLine("LD = {0}", depfile.LD ?? "gcc"); writer.WriteLine("LEX = {0}", depfile.LEX ?? "lex"); writer.WriteLine("YACC = {0}", depfile.YACC ?? "yacc"); writer.WriteLine(); writer.WriteLine("# File Lists"); writer.WriteLine("SRCS_AS = {0}", string.Join(" ", asfiles)); writer.WriteLine("SRCS_CC = {0}", string.Join(" ", cfiles)); writer.WriteLine("SRCS_CXX = {0}", string.Join(" ", cppfiles)); writer.WriteLine("OBJS = {0}", string.Join(" ", objs)); writer.WriteLine(); writer.WriteLine("# Flags"); writer.WriteLine("FLAGS = {0}", depfile.FLAGS); writer.WriteLine("ASFLAGS = {0}", depfile.ASFLAGS); writer.WriteLine("CCFLAGS = {0}", depfile.CCFLAGS); writer.WriteLine("CXXFLAGS = {0}", depfile.CXXFLAGS); writer.WriteLine("LDFLAGS = {0}", depfile.LDFLAGS); writer.WriteLine(); writer.WriteLine("# Targets"); writer.WriteLine("all: {0}", depfile.Artifact); writer.WriteLine(); writer.WriteLine(".PHONY: clean"); writer.WriteLine("clean:"); writer.WriteLine("\t$(RM) {0}", string.Join(" ", articfacts)); writer.WriteLine(); // Creating linker call { var objects = new List <string> (); foreach (var file in objs.Concat(depfile.ExternalObjects)) { if (file.Contains("|")) { var t = file.Split('|'); objects.AddRange(Directory.GetFiles(t [0], t [1])); } else { objects.Add(file); } } writer.WriteLine("{0}: {1}", depfile.Artifact, string.Join(" ", objects)); writer.WriteLine("\t$(LD) $(FLAGS) $(LDFLAGS) -o $@ {1}", depfile.Artifact, string.Join(" ", objects)); writer.WriteLine(); } // Create c section foreach (var file in cfiles) { string obj = ObjectName(depfile, file); string specialCommands = ""; if (movedIncludeFolder.ContainsKey(file)) { specialCommands = "-iquote" + movedIncludeFolder [file]; } specialCommands += "-iquoteobj "; string dependencies = obj + ": " + file + "\n"; if (File.Exists(file)) { Process proc = Process.Start(new ProcessStartInfo("gcc", specialCommands + " -std=c11 -MM -Iinclude " + file) { UseShellExecute = false, RedirectStandardOutput = true, }); proc.WaitForExit(); if (proc.ExitCode != 0) { return(proc.ExitCode); } dependencies = proc.StandardOutput.ReadToEnd(); dependencies = dependencies.Replace(Path.GetFileNameWithoutExtension(file) + ".o", obj); } // Write target with dependencies writer.WriteLine("# {0}", file); writer.Write(dependencies); // Has a newline already writer.WriteLine("\t$(CC) {2} $(FLAGS) $(CCFLAGS) -o $@ -c {1}", depfile.Artifact, file, specialCommands); writer.WriteLine(); } // Create c++ section foreach (var file in cppfiles) { string obj = ObjectName(depfile, file); string specialCommands = ""; if (movedIncludeFolder.ContainsKey(file)) { specialCommands = "-iquote" + movedIncludeFolder [file] + " "; } specialCommands += "-iquoteobj "; string dependencies = obj + ": " + file + "\n"; if (File.Exists(file)) { Process proc = Process.Start(new ProcessStartInfo("g++", specialCommands + " -std=c++11 -MM -Iinclude " + file) { UseShellExecute = false, RedirectStandardOutput = true, }); proc.WaitForExit(); if (proc.ExitCode != 0) { return(proc.ExitCode); } dependencies = proc.StandardOutput.ReadToEnd(); dependencies = dependencies.Replace(Path.GetFileNameWithoutExtension(file) + ".o", obj); } // Write target with dependencies writer.WriteLine("# {0}", file); writer.Write(dependencies); // Has a newline already writer.WriteLine("\t$(CXX) {2} $(FLAGS) $(CXXFLAGS) -o $@ -c {1}", depfile.Artifact, file, specialCommands); writer.WriteLine(); } // Create assembler section foreach (var file in asfiles) { string obj = ObjectName(depfile, file); // Write target with dependencies writer.WriteLine("# {0}", file); writer.WriteLine("{0}: {1}", obj, file); // Has a newline already writer.WriteLine("\t$(AS) $(FLAGS) $(ASFLAGS) -o $@ -c {1}", depfile.Artifact, file); writer.WriteLine(); } foreach (var file in lexfiles) { string cfile = TempName(depfile, file, depfile.LexUseCpp ? ".yy.cpp" : ".yy.c"); writer.WriteLine("{0}: {1}", cfile, file); writer.WriteLine("\t$(LEX) --header-file={0} -o {1} -d {2}", file + ".h", cfile, file); writer.WriteLine(); } foreach (var file in yaccfiles) { string cfile = TempName(depfile, file, depfile.YaccUseCpp ? ".tab.cpp" : ".tab.c"); writer.WriteLine("{0}: {1}", cfile, file); writer.WriteLine("\t$(YACC) -o {0} -d {1}", cfile, file); writer.WriteLine(); } if (appendix.Length > 0) { writer.WriteLine("# Custom Targets"); writer.Write(appendix); } } return(0); }