Example #1
0
 static string TempName(Depfile file, string fileName, string ext)
 {
     return file.TempDir + "/" + Path.GetFileNameWithoutExtension (fileName) + ext;
 }
Example #2
0
 static string ObjectName(Depfile file, string fileName)
 {
     return TempName(file, fileName, ".o");
 }
Example #3
0
        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;
        }
Example #4
0
 static string TempName(Depfile file, string fileName, string ext)
 {
     return(file.TempDir + "/" + Path.GetFileNameWithoutExtension(fileName) + ext);
 }
Example #5
0
 static string ObjectName(Depfile file, string fileName)
 {
     return(TempName(file, fileName, ".o"));
 }
Example #6
0
        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);
        }