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 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); }
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()); }