Beispiel #1
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);
            }
        }
Beispiel #2
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);
        }
Beispiel #3
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);
            }
        }
        public static String GenericFlagsMapper(ITaskItem[] ItemFlags, ITaskItem source, string ItemSpec, ShellAppConversion shellApp)
        {
            StringBuilder str = new StringBuilder();

            try
            {
                var allitems = ItemFlags.Where(x => (x.ItemSpec == ItemSpec));
                if (!allitems.Any())
                {
                    return(str.ToString());
                }
                var item = allitems.First();
                if (item.GetMetadata("MappingVariable") != null)
                {
                    var map = item.GetMetadata("MappingVariable");
                    if (String.IsNullOrEmpty(map))
                    {
                        if (!String.IsNullOrEmpty(item.GetMetadata("Flag")))
                        {
                            str.Append(item.GetMetadata("Flag"));
                            str.Append(" ");
                        }
                    }
                    else
                    {
                        var metadata = source.GetMetadata(map);
                        // check if you have flags too. if so then
                        var flag          = item.GetMetadata("flag");
                        var Flag_WSLAware = item.GetMetadata("Flag_WSLAware");
                        if (String.IsNullOrEmpty(flag))
                        {
                            if (String.IsNullOrEmpty(metadata))
                            {
                                metadata = "IsNullOrEmpty";
                            }

                            if (!String.IsNullOrEmpty(item.GetMetadata(metadata)))
                            {
                                str.Append(item.GetMetadata(metadata));
                                str.Append(" ");
                            }
                            else if (!String.IsNullOrEmpty(item.GetMetadata("OTHER")))
                            {
                                str.Append(item.GetMetadata("OTHER"));
                                str.Append(" ");
                            }
                        }
                        else
                        {
                            var match = flag_regex_array.Match(flag);
                            if (match.Success)
                            {
                                var item_sep       = match.Groups[1].Value;
                                var item_arguments = metadata.Split(new String[] { item_sep }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (var item_ar in item_arguments)
                                {
                                    string item_ar_fixed = item_ar;
                                    //a hacky fix for issue #6, gcc.exe -I "d:\" will consider \" as escaped string!
                                    if (!String.IsNullOrWhiteSpace(Flag_WSLAware) && Flag_WSLAware.ToLower().Equals("true") && item_ar_fixed.EndsWith("\\"))
                                    {
                                        item_ar_fixed = item_ar_fixed.Substring(0, item_ar_fixed.Length - 1);
                                    }

                                    if (String.IsNullOrWhiteSpace(Flag_WSLAware) || (!shellApp.convertpath) || (!String.IsNullOrWhiteSpace(Flag_WSLAware) && !Flag_WSLAware.ToLower().Equals("true")))
                                    {
                                        str.Append(flag.Replace(match.Groups[0].Value, item_ar_fixed));
                                    }
                                    else
                                    {
                                        str.Append(flag.Replace(match.Groups[0].Value, shellApp.ConvertWinPathToWSL(item_ar_fixed)));
                                    }
                                    str.Append(" ");
                                }
                            }
                            else
                            {
                                //just use flags. mistake in their props!
                                str.Append(flag);
                                str.Append(" ");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Instance.LogMessage($"You did not specified correct/enough items in GCCToolxxxx_Flags {ex}");
            }

            return(str.ToString().TrimEnd());
        }