public void LogError(string message, ShellAppConversion shellApp, params object[] parameters) { lock (sync) { MatchCollection matches = err_rgx.Matches(message); if ((matches.Count == 1) && (matches[0].Groups.Count > 4)) { GroupCollection groups = matches[0].Groups; int lineNumber = 0; int colNumber = 0; string filename = groups[1].Value; int.TryParse(groups[3].Value, out lineNumber); int.TryParse(groups[5].Value, out colNumber); if (shellApp != null && shellApp.convertpath) { filename = shellApp.ConvertWSLPathToWin(filename); } log.LogError(null, null, null, filename, lineNumber, colNumber, 0, 0, groups[6].Value); } else { log.LogError(message, parameters); } } }
public void LogLinker(string message, ShellAppConversion shellApp, params object[] parameters) { lock (sync) { string pattern = @"(.*?):(?![\\\/])(.*?)"; Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase); MatchCollection matches = rgx.Matches(message); if ((matches.Count >= 1) && (matches[0].Groups.Count > 2)) { GroupCollection groups = matches[0].Groups; string filename = groups[1].Value; if (shellApp != null && shellApp.convertpath) { message = message.Substring(message.IndexOf(filename) + filename.Length + 1); filename = shellApp.ConvertWSLPathToWin(filename); } if (!general_err.Match(message).Success&& (general_warn.Match(message).Success || general_inf.Match(message).Success)) { log.LogWarning(null, null, null, filename, 0, 0, 0, 0, message); } else { log.LogError(null, null, null, filename, 0, 0, 0, 0, message); } } else { log.LogError(message, parameters); } } }
public void LogOther(string message, ShellAppConversion shellApp, params object[] parameters) { lock (sync) { string pattern = @"(.*):(.*):(.*): (.*)"; Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase); MatchCollection matches = rgx.Matches(message); if ((matches.Count == 1) && (matches[0].Groups.Count > 4)) { GroupCollection groups = matches[0].Groups; int lineNumber = 0; int colNumber = 0; string filename = groups[2].Value; if (shellApp != null && shellApp.convertpath) { filename = shellApp.ConvertWSLPathToWin(filename); } log.LogWarning(null, null, null, filename, lineNumber, colNumber, 0, 0, groups[4].Value); } else { log.LogWarning(message, parameters); } } }
internal RunWrapper(string path, string options, ShellAppConversion shellApp) { if (!string.IsNullOrEmpty(shellApp.shellapp)) //try to find full path of it from path enviroment! { var enviromentPath = System.Environment.GetEnvironmentVariable("PATH"); if (!Utilities.isLinux()) { enviromentPath = enviromentPath + ";" + Environment.GetEnvironmentVariable("SystemRoot") + @"\sysnative"; } //Console.WriteLine(enviromentPath); var paths = enviromentPath.Split(Utilities.isLinux() ? ':' : ';'); var exePath = paths.Select(x => Path.Combine(x, shellApp.shellapp)) .Where(x => File.Exists(x)) .FirstOrDefault(); if (!String.IsNullOrEmpty(exePath)) { options = path + " " + options; path = exePath; } } this.shellApp = shellApp; realCommandLine = $"{path} {options}"; if (!String.IsNullOrEmpty(shellApp.prerunapp)) { string newfilename; if (!Utilities.isLinux()) { newfilename = Path.Combine(shellApp.tmpfolder, "GCCBuildPreRun_" + Guid.NewGuid().ToString() + ".bat"); File.WriteAllText(newfilename, $"@{shellApp.prerunapp}\r\n@{path} {options}"); } else { newfilename = Path.Combine(shellApp.tmpfolder, "GCCBuildPreRun_" + Guid.NewGuid().ToString() + ".sh"); File.WriteAllText(newfilename, $"#!/bin/bash\n{shellApp.prerunapp}\n{path} {options}"); } realCommandLine = $"{path} {options}"; path = newfilename; options = ""; } startInfo = new ProcessStartInfo(path, options); startInfo.UseShellExecute = false; startInfo.RedirectStandardError = true; //startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.StandardErrorEncoding = System.Text.Encoding.UTF8; startInfo.StandardOutputEncoding = System.Text.Encoding.UTF8; }
public void LogDecide(string message, ShellAppConversion shellApp, params object[] parameters) { MatchCollection err_matches = XBuildLogProvider.err_rgx.Matches(message); MatchCollection warn_matches = XBuildLogProvider.warn_rgx.Matches(message); if (err_matches.Count > 0) { LogError(message, shellApp, parameters); } else if (warn_matches.Count > 0) { LogWarning(message, shellApp, parameters); } else if (message.Contains("note:")) { message = message.Replace("note:", "warning:"); LogWarning(message, shellApp, parameters); } else { LogOther(message, shellApp, parameters); } }
internal RunWrapper(string path, string options, ShellAppConversion shellApp, bool useresponse) { realCommandLine = $"{path} {options}"; if (!Utilities.isLinux() && useresponse && (path.Length + options.Length) > 8100) //technically it is 8191 { var responsefilename = Path.Combine(shellApp.tmpfolder, "response_" + Guid.NewGuid().ToString() + ".rsp"); File.WriteAllText(responsefilename, $"{options}"); options = $"@{responsefilename}"; } if (!string.IsNullOrEmpty(shellApp.shellapp)) //try to find full path of it from path enviroment! { var enviromentPath = System.Environment.GetEnvironmentVariable("PATH"); if (!Utilities.isLinux()) { enviromentPath = enviromentPath + ";" + Environment.GetEnvironmentVariable("SystemRoot") + @"\sysnative"; } //Console.WriteLine(enviromentPath); var paths = enviromentPath.Split(Utilities.isLinux() ? ':' : ';'); var exePath = paths.Select(x => Path.Combine(x, shellApp.shellapp)) .Where(x => File.Exists(x)) .FirstOrDefault(); if (!String.IsNullOrEmpty(exePath)) { options = path + " " + options; path = exePath; } } this.shellApp = shellApp; /// /// if there is a prerun app. bundle that prerun and compiler\linker\archiver into one batch\bash file and then run that! /// if (!String.IsNullOrEmpty(shellApp.prerunapp)) { string newfilename; if (!Utilities.isLinux()) { newfilename = Path.Combine(shellApp.tmpfolder, "GCCBuildPreRun_" + Guid.NewGuid().ToString() + ".bat"); File.WriteAllText(newfilename, $"@{shellApp.prerunapp}\r\n@{path} {options}"); } else { newfilename = Path.Combine(shellApp.tmpfolder, "GCCBuildPreRun_" + Guid.NewGuid().ToString() + ".sh"); File.WriteAllText(newfilename, $"#!/bin/bash\n{shellApp.prerunapp}\n{path} {options}"); } path = newfilename; options = ""; } startInfo = new ProcessStartInfo(path, options); startInfo.UseShellExecute = false; startInfo.RedirectStandardError = true; //startInfo.RedirectStandardInput = true; startInfo.RedirectStandardOutput = true; startInfo.StandardErrorEncoding = System.Text.Encoding.UTF8; startInfo.StandardOutputEncoding = System.Text.Encoding.UTF8; }
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); } }
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 override bool Execute() { if (String.IsNullOrEmpty(GCCToolCompilerPath)) { GCCToolCompilerPath = ""; } if (String.IsNullOrEmpty(IntPath)) { IntPath = ""; } if (!Sources.Any()) { return(true); } GCCToolCompilerPathCombined = GCCToolCompilerPath; shellApp = new ShellAppConversion(GCCBuild_SubSystem, GCCBuild_ShellApp, GCCBuild_PreRunApp, GCCBuild_ConvertPath, GCCBuild_ConvertPath_mntFolder, IntPath); if (OS.Equals("Windows_NT") && String.IsNullOrWhiteSpace(shellApp.shellapp)) { GCCToolCompilerPathCombined = FixAppPath(GCCToolCompilerPathCombined, GCCToolCompilerExe); } else { GCCToolCompilerPathCombined = Path.Combine(GCCToolCompilerPath, GCCToolCompilerExe); } Logger.Instance = new XBuildLogProvider(Log); // TODO: maybe initialise statically // load or create tracker file string trackerFile = Path.Combine(IntPath, Path.GetFileNameWithoutExtension(ProjectFile) + ".tracker"); try { if (File.Exists(trackerFile)) { XElement rootElement = XElement.Parse(File.ReadAllText(trackerFile)); foreach (var el in rootElement.Elements()) { dependencyDict.TryAdd(el.Attribute("Object").Value, el.Value.Split(';').ToList()); } } } catch (Exception ex) { Logger.Instance.LogMessage($"Accessing .tracker file caused an exception! {ex}"); //just ignore it is ok! } var objectFiles = new List <string>(); var compilationResult = System.Threading.Tasks.Parallel.ForEach(Sources.Select(x => x), new System.Threading.Tasks.ParallelOptions { MaxDegreeOfParallelism = Parallel ? -1 : 1 }, (source, loopState) => { string objectFile; if (!Compile(source, out objectFile)) { loopState.Break(); } lock (objectFiles) { objectFiles.Add(objectFile); } }); if (dependencyDict.Count > 0) { try { XElement el = new XElement("root", dependencyDict.Select(kv => { var x = new XElement("File", String.Join(";", kv.Value)); x.Add(new XAttribute("Object", kv.Key)); return(x); })); File.WriteAllText(trackerFile, el.ToString()); } catch (Exception ex) { Logger.Instance.LogMessage($"Writing to .tracker file caused an exception! {ex}"); } } if (compilationResult.LowestBreakIteration != null) { return(false); } ObjectFiles = objectFiles.Any() ? objectFiles.Select(x => new TaskItem(Utilities.MakeRelative(x, Environment.CurrentDirectory + Path.DirectorySeparatorChar))).ToArray() : new TaskItem[0]; return(true); }
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()); }
public static String GetConvertedFlags(ITaskItem[] ItemFlags, string flag_string, ITaskItem source, Dictionary <String, String> overrides, ShellAppConversion shellApp) { if (String.IsNullOrEmpty(flag_string)) { return(""); } if (source == null) { return(flag_string); } Regex rg_FlagSet = new Regex("(\\B\\$\\w+)"); var match = rg_FlagSet.Match(flag_string); StringBuilder flagsBuilder = new StringBuilder(); int movi = 0; while (match.Success) { if (movi < match.Index) { flagsBuilder.Append(flag_string.Substring(movi, match.Index - movi)); movi += match.Index - movi; } if (overrides.ContainsKey(match.Value.Substring(1))) { flagsBuilder.Append(overrides[match.Value.Substring(1)]); } else { flagsBuilder.Append(GenericFlagsMapper(ItemFlags, source, match.Value.Substring(1), shellApp)); } movi += match.Length; match = match.NextMatch(); } if (movi < flag_string.Length) { flagsBuilder.Append(flag_string.Substring(movi, flag_string.Length - movi)); } return(flagsBuilder.ToString()); }