Example #1
0
        public override bool Execute()
        {
            Logger.Instance = new XBuildLogProvider(Log); // TODO: maybe initialise statically; this put in constructor causes NRE

            if (!ObjectFiles.Any())
            {
                return(true);
            }

            var lfiles = new List <string>();
            var ofiles = ObjectFiles.Select(x => x.ItemSpec);

            if (String.IsNullOrEmpty(GCCToolLinkerPath))
            {
                GCCToolLinkerPath = "";
            }
            GCCToolLinkerPathCombined = GCCToolLinkerPath;

            shellApp = new ShellAppConversion(GCCBuild_SubSystem, GCCBuild_ShellApp, GCCBuild_PreRunApp,
                                              GCCBuild_ConvertPath, GCCBuild_ConvertPath_mntFolder, IntPath);

            if (OS.Equals("Windows_NT") && String.IsNullOrWhiteSpace(shellApp.shellapp))
            {
                GCCToolLinkerPathCombined = Utilities.FixAppPath(GCCToolLinkerPathCombined, GCCToolLinkerExe);
            }
            else
            {
                GCCToolLinkerPathCombined = Path.Combine(GCCToolLinkerPath, GCCToolLinkerExe);
            }

            string OutputFile_Converted = OutputFile;

            if (shellApp.convertpath)
            {
                OutputFile_Converted = shellApp.ConvertWinPathToWSL(OutputFile);
            }

            else if (!Directory.Exists(Path.GetDirectoryName(OutputFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));
            }


            // linking
            Dictionary <string, string> Flag_overrides = new Dictionary <string, string>();

            Flag_overrides.Add("OutputFile", OutputFile_Converted);

            var flags = Utilities.GetConvertedFlags(GCCToolLinker_Flags, GCCToolLinker_AllFlags, ObjectFiles[0], Flag_overrides, shellApp);

            Logger.Instance.LogCommandLine($"{GCCToolLinkerPathCombined} {flags}");

            using (var runWrapper = new RunWrapper(GCCToolLinkerPathCombined, flags, shellApp, GCCToolSupportsResponsefile))
            {
                bool result = runWrapper.RunLinker(String.IsNullOrEmpty(ObjectFiles[0].GetMetadata("SuppressStartupBanner")) || ObjectFiles[0].GetMetadata("SuppressStartupBanner").Equals("true") ? false : true);
                if (result)
                {
                    string allofiles = String.Join(",", ofiles);
                    if (allofiles.Length > 100)
                    {
                        allofiles = allofiles.Substring(0, 100) + "...";
                    }
                    Logger.Instance.LogMessage($"  ({allofiles}) => {OutputFile_Converted}");
                }

                return(result);
            }
        }
Example #2
0
        public override bool Execute()
        {
            if (String.IsNullOrEmpty(GCCBuild_ShellApp))
            {
                GCCBuild_ConvertPath = false;
            }
            if (!GCCBuild_ConvertPath)
            {
                GCCBuild_ShellApp = null;
            }
            if (!ObjectFiles.Any())
            {
                return(true);
            }



            Logger.Instance = new XBuildLogProvider(Log); // TODO: maybe initialise statically; this put in constructor causes NRE

            if (!ObjectFiles.Any())
            {
                return(true);
            }

            var lfiles = new List <string>();
            var ofiles = ObjectFiles.Select(x => x.ItemSpec);

            if (String.IsNullOrEmpty(GCCToolArchiverPath))
            {
                GCCToolArchiverPath = "";
            }

            string GCCToolArchiverCombined = GCCToolArchiverPath;

            ShellAppConversion shellApp = new ShellAppConversion(GCCBuild_SubSystem, GCCBuild_ShellApp, GCCBuild_PreRunApp,
                                                                 GCCBuild_ConvertPath, GCCBuild_ConvertPath_mntFolder, IntPath);

            if (OS.Equals("Windows_NT") && String.IsNullOrWhiteSpace(shellApp.shellapp))
            {
                GCCToolArchiverCombined = Utilities.FixAppPath(GCCToolArchiverCombined, GCCToolArchiverExe);
            }
            else
            {
                GCCToolArchiverCombined = Path.Combine(GCCToolArchiverPath, GCCToolArchiverExe);
            }

            string OutputFile_Converted = OutputFile;

            if (shellApp.convertpath)
            {
                OutputFile_Converted = shellApp.ConvertWinPathToWSL(OutputFile);
            }
            else if (!Directory.Exists(Path.GetDirectoryName(OutputFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));
            }


            // archiving - librerian
            Dictionary <string, string> Flag_overrides = new Dictionary <string, string>();

            Flag_overrides.Add("OutputFile", OutputFile_Converted);

            bool needRearchive = true;

            if (File.Exists(OutputFile))
            {
                needRearchive = false;
                FileInfo libInfo = fileinfoDict.GetOrAdd(OutputFile, (x) => new FileInfo(x));
                foreach (var obj in ObjectFiles.Select(x => x.ItemSpec).Concat(new string[] { ProjectFile }))
                {
                    string depfile = obj;

                    if (shellApp.convertpath)
                    {
                        depfile = shellApp.ConvertWSLPathToWin(obj);//here convert back to Windows path
                    }
                    FileInfo fi = fileinfoDict.GetOrAdd(depfile, (x) => new FileInfo(x));
                    if (fi.Exists == false || fi.Attributes == FileAttributes.Directory || fi.Attributes == FileAttributes.Device)
                    {
                        continue;
                    }
                    if (fi.LastWriteTime > libInfo.LastWriteTime)
                    {
                        needRearchive = true;
                        break;
                    }
                }
            }

            var flags = Utilities.GetConvertedFlags(GCCToolArchiver_Flags, GCCToolArchiver_AllFlags, ObjectFiles[0], Flag_overrides, shellApp);

            using (var runWrapper = new RunWrapper(GCCToolArchiverCombined, flags, shellApp, GCCToolSupportsResponsefile))
            {
                bool result = true;
                if (needRearchive)
                {
                    TryDeleteFile(OutputFile);
                    Logger.Instance.LogCommandLine($"{GCCToolArchiverCombined} {flags}");
                    result = runWrapper.RunArchiver(String.IsNullOrEmpty(ObjectFiles[0].GetMetadata("SuppressStartupBanner")) || ObjectFiles[0].GetMetadata("SuppressStartupBanner").Equals("true") ? false : true);
                }


                if (result)
                {
                    string allofiles = String.Join(",", ofiles);
                    if (allofiles.Length > 100)
                    {
                        allofiles = allofiles.Substring(0, 100) + "...";
                    }
                    if (needRearchive)
                    {
                        Logger.Instance.LogMessage($"  ({allofiles}) => {OutputFile_Converted}");
                    }
                    else
                    {
                        Logger.Instance.LogMessage($"  ({allofiles}) => {OutputFile_Converted} (not archive - already up to date)");
                    }
                }

                return(result);
            }
        }
Example #3
0
        public bool Compile(ITaskItem source, out string objectFile)
        {
            //Console.WriteLine($"  {source.ItemSpec}");
            Logger.Instance.LogMessage($"  {source.ItemSpec}");
            if (!String.IsNullOrEmpty(source.GetMetadata("ObjectFileName")))
            { //ObjectFileName is actually a folder name which is usaully $(IntDir) or $(IntDir)/%(RelativeDir)/
                if (IsPathDirectory(source.GetMetadata("ObjectFileName")))
                {
                    objectFile = Path.Combine(source.GetMetadata("ObjectFileName"), Path.GetFileNameWithoutExtension(source.ItemSpec) + ".o");
                }
                else
                {
                    objectFile = source.GetMetadata("ObjectFileName");
                }
            }
            else
            {
                objectFile = Path.GetFileNameWithoutExtension(source.ItemSpec) + ".o";
            }

            string sourceFile       = source.ItemSpec;
            string projectfile_name = ProjectFile;

            string objectFile_converted       = objectFile;
            string sourceFile_converted       = sourceFile;
            string projectfile_name_converted = projectfile_name;

            if (shellApp.convertpath)
            {
                objectFile_converted       = shellApp.ConvertWinPathToWSL(objectFile);
                sourceFile_converted       = shellApp.ConvertWinPathToWSL(sourceFile);
                projectfile_name_converted = shellApp.ConvertWinPathToWSL(projectfile_name);
            }
            else
            {
                //here just shotens path it will help with huge projects
                objectFile_converted = Utilities.MakeRelative(Path.GetFullPath(objectFile), Environment.CurrentDirectory + Path.DirectorySeparatorChar);
            }

            Dictionary <string, string> Flag_overrides = new Dictionary <string, string>();

            Flag_overrides.Add("SourceFile", sourceFile_converted);
            Flag_overrides.Add("OutputFile", objectFile_converted);

            var flags     = GetConvertedFlags(GCCToolCompiler_Flags, GCCToolCompiler_AllFlags, source, Flag_overrides, shellApp);
            var flags_dep = GetConvertedFlags(GCCToolCompiler_Flags, GCCToolCompiler_AllFlagsDependency, source, Flag_overrides, shellApp);

            // let's get all dependencies
            string gccOutput;

            if (Path.GetDirectoryName(objectFile) != "")
            {
                Directory.CreateDirectory(Path.GetDirectoryName(objectFile));
            }

            // This part is to get all dependencies and so know what files to recompile!
            bool needRecompile = true;

            if (!String.IsNullOrEmpty(flags_dep))
            {
                try
                {
                    FileInfo             sourceInfo = fileinfoDict.GetOrAdd(sourceFile, (x) => new FileInfo(x));
                    IEnumerable <string> dependencies;

                    if (dependencyDict.ContainsKey(objectFile) && File.Exists(objectFile) && sourceInfo.LastWriteTime < fileinfoDict.GetOrAdd(objectFile, (x) => new FileInfo(x)).LastWriteTime)
                    {
                        // You dont need to run dependency extraction!
                        // you still need to go through all dependency chains and check files!
                        dependencies = dependencyDict[objectFile];
                    }
                    else
                    {
                        using (var runWrapper = new RunWrapper(GCCToolCompilerPathCombined, flags_dep, shellApp, GCCToolSupportsResponsefile))
                            // run dependency extraction if there is an object file there....if not obviously you have to recompile!
                            if (!runWrapper.RunCompilerAndGetOutput(out gccOutput,
                                                                    String.IsNullOrEmpty(source.GetMetadata("SuppressStartupBanner")) || source.GetMetadata("SuppressStartupBanner").Equals("true") ? false : true
                                                                    ))
                            {
                                if (gccOutput == "FATAL")
                                {
                                    return(false);
                                }
                                //Logger.Instance.LogDecide(gccOutput, shellApp);
                                ///return false;
                            }
                        dependencies = ParseGccMmOutput(gccOutput).Union(new[] { sourceFile, ProjectFile });
                        dependencyDict.AddOrUpdate(objectFile, dependencies.ToList(), (x, y) => dependencies.ToList());
                    }

                    //if there is no object file then offcourse you need to recompile! no need to get into dependency checking
                    if (File.Exists(objectFile))
                    {
                        needRecompile = false;
                        FileInfo objInfo = fileinfoDict.GetOrAdd(objectFile, (x) => new FileInfo(x));

                        foreach (var dep in dependencies)
                        {
                            string depfile = dep;

                            if (shellApp.convertpath)
                            {
                                depfile = shellApp.ConvertWSLPathToWin(dep);//here use original! convert back to windows
                            }
                            FileInfo fi = fileinfoDict.GetOrAdd(depfile, (x) => new FileInfo(x));
                            if (fi.Exists == false || fi.Attributes == FileAttributes.Directory || fi.Attributes == FileAttributes.Device)
                            {
                                continue;
                            }
                            if (fi.LastWriteTime > objInfo.LastWriteTime)
                            {
                                needRecompile = true;
                                break;
                            }
                        }
                    }
                }
                catch
                {
                    needRecompile = true;
                    Logger.Instance.LogError("Internal error while trying to get dependencies from gcc", null);
                }
            }

            bool runCompileResult = false;

            if (needRecompile)
            {
                using (var runWrapper = new RunWrapper(GCCToolCompilerPathCombined, flags, shellApp, GCCToolSupportsResponsefile))
                    runCompileResult = runWrapper.RunCompiler(String.IsNullOrEmpty(source.GetMetadata("SuppressStartupBanner")) || source.GetMetadata("SuppressStartupBanner").Equals("true") ? false : true);
                if (runCompileResult)
                {
                    Logger.Instance.LogMessage($"  {source.ItemSpec} => {objectFile_converted}");
                }
            }
            else
            {
                Logger.Instance.LogMessage($"  {source.ItemSpec} => {objectFile_converted} (not compiled - already up to date)");
                runCompileResult = true;
            }

            return(runCompileResult);
        }