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