public override bool Execute() { try { var path = Path.GetFullPath(LockFile); var key = new Tuple <string, string> (nameof(WriteLockFile), path); // Use the full path as part of the key // Check if already registered, for sanity var existing = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.Build) as DeleteFileAfterBuild; if (existing == null) { if (File.Exists(path)) { Log.LogCodedWarning("XA5302", "Two processes may be building this project at once. Lock file exists at path: {0}", path); } else { Directory.CreateDirectory(Path.GetDirectoryName(path)); File.WriteAllText(path, ""); } BuildEngine4.RegisterTaskObject(key, new DeleteFileAfterBuild(path), RegisteredTaskObjectLifetime.Build, allowEarlyCollection: false); } else { Log.LogDebugMessage("Lock file was created earlier in the build."); } } catch (Exception ex) { Log.LogDebugMessage($"Exception in {nameof (WriteLockFile)}: {ex}"); } // We want to always continue return(true); }
public override bool Execute() { if (LaunchProfiles == null || UserFile == null || FlagFile == null || ProjectDirectory == null) { Log.LogWarning("MonitorActiveDocument : One or more files missing"); return(true); } if (!Directory.Exists(LaunchProfiles)) { Log.LogWarning("LaunchProfiles not created yet"); return(true); } try { if (BuildEngine4.GetRegisteredTaskObject(nameof(ActiveDocumentMonitor), RegisteredTaskObjectLifetime.AppDomain) is not ActiveDocumentMonitor monitor) { if (WindowsInterop.GetServiceProvider() is IServiceProvider services) { BuildEngine4.RegisterTaskObject(nameof(ActiveDocumentMonitor), new ActiveDocumentMonitor(LaunchProfiles, UserFile, FlagFile, ProjectDirectory, services), RegisteredTaskObjectLifetime.AppDomain, false); } } else { // NOTE: this means we only support ONE project/launchProfiles per IDE. monitor.Refresh(LaunchProfiles, UserFile, FlagFile, ProjectDirectory); } }
string GetJvmPath() { // NOTE: this doesn't need to use GetRegisteredTaskObjectAssemblyLocal() // because JavaSdkPath is the key and the value is a string. var key = new Tuple <string, string> (nameof(ResolveJdkJvmPath), JavaSdkPath); var cached = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.AppDomain) as string; if (cached != null) { Log.LogDebugMessage($"Using cached value for {nameof (JdkJvmPath)}: {cached}"); return(cached); } var minVersion = Version.Parse(MinimumSupportedJavaVersion); var maxVersion = Version.Parse(LatestSupportedJavaVersion); JdkInfo info = MonoAndroidHelper.GetJdkInfo(this.CreateTaskLogger(), JavaSdkPath, minVersion, maxVersion); if (info == null) { return(null); } var path = info.JdkJvmPath; if (string.IsNullOrEmpty(path)) { return(null); } BuildEngine4.RegisterTaskObject(key, path, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false); return(path); }
string GetJvmPath() { var key = new Tuple <string, string> (nameof(ResolveSdks), JavaSdkPath); var cached = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.AppDomain) as string; if (cached != null) { Log.LogDebugMessage($"Using cached value for {nameof (JdkJvmPath)}: {cached}"); return(cached); } Xamarin.Android.Tools.JdkInfo info = null; try { info = new Xamarin.Android.Tools.JdkInfo(JavaSdkPath); } catch { info = Xamarin.Android.Tools.JdkInfo.GetKnownSystemJdkInfos(this.CreateTaskLogger()).FirstOrDefault(); } if (info == null) { return(null); } var path = info.JdkJvmPath; if (string.IsNullOrEmpty(path)) { return(null); } BuildEngine4.RegisterTaskObject(key, path, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false); return(path); }
public override bool Execute() { if (string.IsNullOrEmpty(LaunchProfiles) || string.IsNullOrEmpty(UserFile)) { Debug.Fail("Should have gotten something to monitor"); return(true); } try { if (BuildEngine4.GetRegisteredTaskObject(nameof(ActiveDocumentMonitor), RegisteredTaskObjectLifetime.AppDomain) is not ActiveDocumentMonitor monitor) { var maxAttempts = 5; for (var i = 1; i <= maxAttempts; i++) { if (WindowsInterop.GetServiceProvider() is IServiceProvider services) { BuildEngine4.RegisterTaskObject(nameof(ActiveDocumentMonitor), new ActiveDocumentMonitor(LaunchProfiles !, UserFile !, StartupFiles.Select(x => x.ItemSpec).ToArray(), services), RegisteredTaskObjectLifetime.AppDomain, false); return(true); } else { try { BuildEngine4.Yield(); } catch (Exception e) { Debug.WriteLine(e); } // Increase the wait time to allow more time between retries Thread.Sleep(200 * i); } } Debug.Fail("Failed to get IServiceProvider to monitor for active document."); } else { // NOTE: this means we only support ONE project/launchProfiles per IDE. monitor.Refresh(LaunchProfiles !, UserFile !, StartupFiles.Select(x => x.ItemSpec).ToArray()); } }
public override bool Execute() { var key = s_cacheKeyPrefix + Text; var errorReportedSentinel = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.Build); if (errorReportedSentinel != null) { Log.LogMessage(MessageImportance.Low, Text); return(false); } BuildEngine4.RegisterTaskObject(key, new object(), RegisteredTaskObjectLifetime.Build, allowEarlyCollection: true); Log.LogError(Text); return(false); }
bool GetAapt2Version() { var sb = new StringBuilder(); var aapt2Tool = Path.Combine(Aapt2ToolPath, Aapt2); // Try to use a cached value for Aapt2Version // NOTE: this doesn't need to use GetRegisteredTaskObjectAssemblyLocal() // because the path to aapt2 is in the key and the value is a string. var key = ($"{nameof (ResolveAndroidTooling)}.{nameof (Aapt2Version)}", aapt2Tool); var cached = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.AppDomain) as string; if (!string.IsNullOrEmpty(cached)) { Log.LogDebugMessage($"Using cached value for {nameof (Aapt2Version)}: {cached}"); Aapt2Version = cached; return(true); } try { MonoAndroidHelper.RunProcess(aapt2Tool, "version", (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { sb.AppendLine(e.Data); } }, (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { sb.AppendLine(e.Data); } } ); } catch (Exception ex) { Log.LogWarningFromException(ex); return(false); } var versionInfo = sb.ToString(); var versionNumberMatch = Aapt2VersionRegex.Match(versionInfo); Log.LogDebugMessage($"`{aapt2Tool} version` returned: ```{versionInfo}```"); if (versionNumberMatch.Success && Version.TryParse(versionNumberMatch.Groups ["version"]?.Value.Replace(":", "."), out Version versionNumber)) { Aapt2Version = versionNumber.ToString(); BuildEngine4.RegisterTaskObject(key, Aapt2Version, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false); return(true); } return(false); }
protected override void ExecuteCore() { const string previewMessageKey = "Microsoft.NET.Build.Tasks.DisplayPreviewMessageKey"; object messageDisplayed = BuildEngine4.GetRegisteredTaskObject(previewMessageKey, RegisteredTaskObjectLifetime.Build); if (messageDisplayed == null) { Log.LogMessage(MessageImportance.High, Strings.UsingPreviewSdkWarning); BuildEngine4.RegisterTaskObject( previewMessageKey, new object(), RegisteredTaskObjectLifetime.Build, true); } }
protected override void ExecuteCore() { StronglyTypedInputs inputs = GetInputs(); string cacheKey = inputs.CacheKey(); ResolvedAssetsCacheEntry results; if (s_allowCacheLookup && BuildEngine4?.GetRegisteredTaskObject( cacheKey, RegisteredTaskObjectLifetime.AppDomain /* really "until process exit" */) is ResolvedAssetsCacheEntry cacheEntry) { // NOTE: It's conceivably possible that the user modified the targeting // packs between builds. Since that is extremely rare and the standard // user scenario reads the targeting pack contents over and over without // modification, we're electing not to check for file modification and // returning any cached results that we have. results = cacheEntry; } else { results = Resolve(inputs, BuildEngine4); if (s_allowCacheLookup) { BuildEngine4?.RegisterTaskObject(cacheKey, results, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: true); } } foreach (var error in results.Errors) { Log.LogError(error); } ReferencesToAdd = results.ReferencesToAdd; AnalyzersToAdd = results.AnalyzersToAdd; PlatformManifests = results.PlatformManifests; PackageConflictOverrides = results.PackageConflictOverrides; PackageConflictPreferredPackages = results.PackageConflictPreferredPackages; UsedRuntimeFrameworks = results.UsedRuntimeFrameworks; }
protected Version GetVersionFromTool(string javaExe, Regex versionRegex) { // NOTE: this doesn't need to use GetRegisteredTaskObjectAssemblyLocal() // because the path to java/javac is the key and the value is a System.Version. var javaTool = Path.Combine(JavaSdkPath, "bin", javaExe); var key = new Tuple <string, string> (nameof(ValidateJavaVersion), javaTool); var cached = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.AppDomain) as Version; if (cached != null) { Log.LogDebugMessage($"Using cached value for `{javaTool} -version`: {cached}"); JdkVersion = cached.ToString(); return(cached); } var sb = new StringBuilder(); MonoAndroidHelper.RunProcess(javaTool, "-version", (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { sb.AppendLine(e.Data); } }, (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { sb.AppendLine(e.Data); } }); var versionInfo = sb.ToString(); var versionNumberMatch = versionRegex.Match(versionInfo); Version versionNumber; if (versionNumberMatch.Success && Version.TryParse(versionNumberMatch.Groups ["version"]?.Value, out versionNumber)) { BuildEngine4.RegisterTaskObject(key, versionNumber, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false); JdkVersion = versionNumberMatch.Groups ["version"].Value; return(versionNumber); } else { Log.LogCodedWarning("XA0033", Properties.Resources.XA0033, javaExe, versionInfo); return(null); } }
Version GetVersionFromTool(string javaExe, Regex versionRegex) { var javaTool = Path.Combine(JavaSdkPath, "bin", javaExe); var key = new Tuple <string, string> (nameof(ValidateJavaVersion), javaTool); var cached = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.AppDomain) as Version; if (cached != null) { Log.LogDebugMessage($"Using cached value for `{javaTool} -version`: {cached}"); JdkVersion = cached.ToString(); return(cached); } var sb = new StringBuilder(); MonoAndroidHelper.RunProcess(javaTool, "-version", (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { sb.AppendLine(e.Data); } }, (s, e) => { if (!string.IsNullOrEmpty(e.Data)) { sb.AppendLine(e.Data); } }); var versionInfo = sb.ToString(); var versionNumberMatch = versionRegex.Match(versionInfo); Version versionNumber; if (versionNumberMatch.Success && Version.TryParse(versionNumberMatch.Groups ["version"]?.Value, out versionNumber)) { BuildEngine4.RegisterTaskObject(key, versionNumber, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false); JdkVersion = versionNumberMatch.Groups ["version"].Value; return(versionNumber); } else { Log.LogCodedWarning("XA0033", $"Failed to get the Java SDK version as it does not appear to contain a valid version number. `{javaExe} -version` returned: ```{versionInfo}```"); return(null); } }
private void ExecuteImpl() { var globalJsonPath = Path.Combine(RepositoryRoot, "global.json"); var lastWrite = File.GetLastWriteTimeUtc(globalJsonPath); var paths = Environment.GetEnvironmentVariable("PATH"); var cachedResult = (CacheEntry)BuildEngine4.GetRegisteredTaskObject(s_cacheKey, RegisteredTaskObjectLifetime.Build); if (cachedResult != null && lastWrite == cachedResult.LastWrite && paths == cachedResult.Paths) { Log.LogMessage(MessageImportance.Low, $"Reused cached value."); DotNetPath = cachedResult.Value; return; } var globalJson = File.ReadAllText(globalJsonPath); // avoid Newtonsoft.Json dependency var match = Regex.Match(globalJson, @"""dotnet""\s*:\s*""([^""]+)"""); if (!match.Success) { Log.LogError($"Unable to determine dotnet version from file '{globalJsonPath}'."); return; } var sdkVersion = match.Groups[1].Value; var fileName = (Path.DirectorySeparatorChar == '\\') ? "dotnet.exe" : "dotnet"; var dotNetDir = paths.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(p => File.Exists(Path.Combine(p, fileName))); if (dotNetDir == null || !Directory.Exists(Path.Combine(dotNetDir, "sdk", sdkVersion))) { Log.LogError($"Unable to find dotnet with SDK version '{sdkVersion}'"); return; } DotNetPath = Path.GetFullPath(Path.Combine(dotNetDir, fileName)); BuildEngine4.RegisterTaskObject(s_cacheKey, new CacheEntry(lastWrite, paths, DotNetPath), RegisteredTaskObjectLifetime.Build, allowEarlyCollection: true); }
public override bool Execute() { var logger = new Logger(Log); var sandbox = BuildEngine4.GetRegisteredTaskObject(BuildEngine.ProjectFileOfTaskNode, RegisteredTaskObjectLifetime.Build) as Sanbox; if (sandbox == null) { return(true); } try { sandbox.Client.ExecutePostBuildAdaptations(logger); } catch (Exception e) { logger.Error($"Assembly adaptation pre build execution failed. Details: {e.GetBaseException().Message}"); } return(!Log.HasLoggedErrors); }
public override bool Execute() { var logger = new Logger(Log); var sandbox = BuildEngine4.GetRegisteredTaskObject(BuildEngine.ProjectFileOfTaskNode, RegisteredTaskObjectLifetime.Build) as Sanbox; if (sandbox == null) { return(true); } CompilesToAdd = Enumerable.Empty <ITaskItem>().ToArray(); CompilesToRemove = Enumerable.Empty <ITaskItem>().ToArray(); if (!Test && Assembly.GetEntryAssembly() == null) { return(true); } try { var replacements = sandbox.Client.ReplaceCompileItems(logger); Func <CompileItemReplacement, ITaskItem> selector = r => { return(ItemsCompile.FirstOrDefault(c => string.Equals(c.GetMetadata("FullPath"), r.Source, StringComparison.InvariantCultureIgnoreCase))); }; CompilesToAdd = replacements.Select(r => new TaskItem(r.Target)).OfType <ITaskItem>().ToArray(); CompilesToRemove = replacements.Select(selector).ToArray(); } catch (Exception e) { logger.Error($"Assembly compile replacement failed. Details: {e.GetBaseException().Message}"); } return(!Log.HasLoggedErrors); }
string GetJvmPath() { // NOTE: this doesn't need to use GetRegisteredTaskObjectAssemblyLocal() // because JavaSdkPath is the key and the value is a string. var key = new Tuple <string, string> (nameof(ResolveJdkJvmPath), JavaSdkPath); var cached = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.AppDomain) as string; if (cached != null) { Log.LogDebugMessage($"Using cached value for {nameof (JdkJvmPath)}: {cached}"); return(cached); } JdkInfo info = null; try { info = new JdkInfo(JavaSdkPath); } catch { info = JdkInfo.GetKnownSystemJdkInfos(this.CreateTaskLogger()).FirstOrDefault(); } if (info == null) { return(null); } var path = info.JdkJvmPath; if (string.IsNullOrEmpty(path)) { return(null); } BuildEngine4.RegisterTaskObject(key, path, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false); return(path); }
public override bool Execute() { var logger = new Logger(Log); var sandbox = BuildEngine4.GetRegisteredTaskObject(BuildEngine.ProjectFileOfTaskNode, RegisteredTaskObjectLifetime.Build) as Sanbox; if (sandbox == null) { return(true); } try { sandbox.Dispose(); BuildEngine4.UnregisterTaskObject(BuildEngine.ProjectFileOfTaskNode, RegisteredTaskObjectLifetime.Build); } catch (Exception e) { logger.Error($"Failure cleanup task failed. Details: {e.GetBaseException().Message}"); } return(!Log.HasLoggedErrors); }
public override bool Execute() { if (LaunchProfiles == null || UserFile == null || FlagFile == null) { return(true); } try { if (BuildEngine4.GetRegisteredTaskObject(nameof(ActiveDocumentMonitor), RegisteredTaskObjectLifetime.AppDomain) is not ActiveDocumentMonitor monitor) { if (WindowsInterop.GetServiceProvider() is IServiceProvider services) { BuildEngine4.RegisterTaskObject(nameof(ActiveDocumentMonitor), new ActiveDocumentMonitor(LaunchProfiles, UserFile, FlagFile, services), RegisteredTaskObjectLifetime.AppDomain, false); } } else { // NOTE: this means we only support ONE project/launchProfiles per IDE. monitor.Refresh(LaunchProfiles, UserFile, FlagFile); } }
void AddEnvironment() { bool usesMonoAOT = false; bool usesAssemblyPreload = EnablePreloadAssembliesDefault; bool brokenExceptionTransitions = false; var environmentVariables = new Dictionary <string, string> (StringComparer.Ordinal); var systemProperties = new Dictionary <string, string> (StringComparer.Ordinal); if (!Enum.TryParse(PackageNamingPolicy, out PackageNamingPolicy pnp)) { pnp = PackageNamingPolicyEnum.LowercaseCrc64; } AotMode aotMode = AotMode.None; if (!string.IsNullOrEmpty(AndroidAotMode) && Aot.GetAndroidAotMode(AndroidAotMode, out aotMode) && aotMode != AotMode.None) { usesMonoAOT = true; } bool haveLogLevel = false; bool haveMonoDebug = false; bool havebuildId = false; bool haveHttpMessageHandler = false; bool haveTlsProvider = false; bool haveMonoGCParams = false; SequencePointsMode sequencePointsMode; if (!Aot.TryGetSequencePointsMode(AndroidSequencePointsMode, out sequencePointsMode)) { sequencePointsMode = SequencePointsMode.None; } foreach (ITaskItem env in Environments ?? new TaskItem[0]) { foreach (string line in File.ReadLines(env.ItemSpec)) { var lineToWrite = line; if (lineToWrite.StartsWith("MONO_LOG_LEVEL=", StringComparison.Ordinal)) { haveLogLevel = true; } if (lineToWrite.StartsWith("MONO_GC_PARAMS=", StringComparison.Ordinal)) { haveMonoGCParams = true; } if (lineToWrite.StartsWith("XAMARIN_BUILD_ID=", StringComparison.Ordinal)) { havebuildId = true; } if (lineToWrite.StartsWith("MONO_DEBUG=", StringComparison.Ordinal)) { haveMonoDebug = true; if (sequencePointsMode != SequencePointsMode.None && !lineToWrite.Contains("gen-compact-seq-points")) { lineToWrite = line + ",gen-compact-seq-points"; } } if (lineToWrite.StartsWith("XA_HTTP_CLIENT_HANDLER_TYPE=", StringComparison.Ordinal)) { haveHttpMessageHandler = true; } if (lineToWrite.StartsWith("XA_TLS_PROVIDER=", StringComparison.Ordinal)) { haveTlsProvider = true; } if (lineToWrite.StartsWith("mono.enable_assembly_preload=", StringComparison.Ordinal)) { int idx = lineToWrite.IndexOf('='); uint val; if (idx < lineToWrite.Length - 1 && UInt32.TryParse(lineToWrite.Substring(idx + 1), out val)) { usesAssemblyPreload = idx == 1; } continue; } if (lineToWrite.StartsWith("XA_BROKEN_EXCEPTION_TRANSITIONS=")) { brokenExceptionTransitions = true; continue; } AddEnvironmentVariableLine(lineToWrite); } } if (_Debug && !haveLogLevel) { AddEnvironmentVariable(defaultLogLevel[0], defaultLogLevel[1]); } if (sequencePointsMode != SequencePointsMode.None && !haveMonoDebug) { AddEnvironmentVariable(defaultMonoDebug[0], defaultMonoDebug[1]); } if (!havebuildId) { AddEnvironmentVariable("XAMARIN_BUILD_ID", BuildId); } if (!haveHttpMessageHandler) { if (HttpClientHandlerType == null) { AddEnvironmentVariable(defaultHttpMessageHandler[0], defaultHttpMessageHandler[1]); } else { AddEnvironmentVariable("XA_HTTP_CLIENT_HANDLER_TYPE", HttpClientHandlerType.Trim()); } } if (!haveTlsProvider) { if (TlsProvider == null) { AddEnvironmentVariable(defaultTlsProvider[0], defaultTlsProvider[1]); } else { AddEnvironmentVariable("XA_TLS_PROVIDER", TlsProvider.Trim()); } } if (!haveMonoGCParams) { if (EnableSGenConcurrent) { AddEnvironmentVariable("MONO_GC_PARAMS", "major=marksweep-conc"); } else { AddEnvironmentVariable("MONO_GC_PARAMS", "major=marksweep"); } } global::Android.Runtime.BoundExceptionType boundExceptionType; if (String.IsNullOrEmpty(BoundExceptionType) || String.Compare(BoundExceptionType, "System", StringComparison.OrdinalIgnoreCase) == 0) { boundExceptionType = global::Android.Runtime.BoundExceptionType.System; } else if (String.Compare(BoundExceptionType, "Java", StringComparison.OrdinalIgnoreCase) == 0) { boundExceptionType = global::Android.Runtime.BoundExceptionType.Java; } else { throw new InvalidOperationException($"Unsupported BoundExceptionType value '{BoundExceptionType}'"); } var appConfState = BuildEngine4.GetRegisteredTaskObject(ApplicationConfigTaskState.RegisterTaskObjectKey, RegisteredTaskObjectLifetime.Build) as ApplicationConfigTaskState; foreach (string abi in SupportedAbis) { NativeAssemblerTargetProvider asmTargetProvider = GetAssemblyTargetProvider(abi); string baseAsmFilePath = Path.Combine(EnvironmentOutputDirectory, $"environment.{abi.ToLowerInvariant ()}"); string asmFilePath = $"{baseAsmFilePath}.s"; var asmgen = new ApplicationConfigNativeAssemblyGenerator(asmTargetProvider, baseAsmFilePath, environmentVariables, systemProperties) { IsBundledApp = IsBundledApplication, UsesMonoAOT = usesMonoAOT, UsesMonoLLVM = EnableLLVM, UsesAssemblyPreload = usesAssemblyPreload, MonoAOTMode = aotMode.ToString().ToLowerInvariant(), AndroidPackageName = AndroidPackageName, BrokenExceptionTransitions = brokenExceptionTransitions, PackageNamingPolicy = pnp, BoundExceptionType = boundExceptionType, InstantRunEnabled = InstantRunEnabled, JniAddNativeMethodRegistrationAttributePresent = appConfState != null ? appConfState.JniAddNativeMethodRegistrationAttributePresent : false, }; using (var sw = MemoryStreamPool.Shared.CreateStreamWriter()) { asmgen.Write(sw); sw.Flush(); MonoAndroidHelper.CopyIfStreamChanged(sw.BaseStream, asmFilePath); } } void AddEnvironmentVariable(string name, string value) { if (Char.IsUpper(name [0]) || !Char.IsLetter(name [0])) { environmentVariables [ValidAssemblerString(name)] = ValidAssemblerString(value); } else { systemProperties [ValidAssemblerString(name)] = ValidAssemblerString(value); } } void AddEnvironmentVariableLine(string l) { string line = l?.Trim(); if (String.IsNullOrEmpty(line) || line [0] == '#') { return; } string[] nv = line.Split(new char[] { '=' }, 2); AddEnvironmentVariable(nv[0].Trim(), nv.Length < 2 ? String.Empty : nv[1].Trim()); } string ValidAssemblerString(string s) { return(s.Replace("\"", "\\\"")); } }
public override bool Execute() { if (!SemanticVersion.TryParse(SdkVersion, out var currentSdkVersion)) { Log.LogError($"Invalid version: {SdkVersion}"); return(false); } var globalJsonPath = Path.Combine(RepositoryRoot, "global.json"); DateTime lastWrite; try { lastWrite = File.GetLastWriteTimeUtc(globalJsonPath); } catch (Exception e) { Log.LogError($"Error accessing file '{globalJsonPath}': {e.Message}"); return(false); } var cachedResult = (CacheEntry)BuildEngine4.GetRegisteredTaskObject(s_cacheKey, RegisteredTaskObjectLifetime.Build); if (cachedResult != null && lastWrite == cachedResult.LastWrite) { // Error has already been reported if the current SDK version is not sufficient. if (!cachedResult.Success) { Log.LogMessage(MessageImportance.Low, $"Previous .NET Core SDK version check failed."); } return(cachedResult.Success); } bool execute() { string globalJson; try { globalJson = File.ReadAllText(globalJsonPath); } catch (Exception e) { Log.LogError($"Error reading file '{globalJsonPath}': {e.Message}"); return(false); } // avoid Newtonsoft.Json dependency var match = Regex.Match(globalJson, $@"""dotnet""\s*:\s*""([^""]+)"""); if (!match.Success) { Log.LogError($"Unable to determine dotnet version from file '{globalJsonPath}'."); return(false); } var minSdkVersionStr = match.Groups[1].Value; if (!SemanticVersion.TryParse(minSdkVersionStr, out var minSdkVersion)) { Log.LogError($"DotNet version specified in '{globalJsonPath}' is invalid: {minSdkVersionStr}."); return(false); } if (currentSdkVersion < minSdkVersion) { Log.LogError($"The .NET Core SDK version {currentSdkVersion} is below the minimum required version {minSdkVersion}. You can install newer .NET Core SDK from https://www.microsoft.com/net/download."); return(false); } return(true); } bool success = execute(); BuildEngine4.RegisterTaskObject(s_cacheKey, new CacheEntry(lastWrite, success), RegisteredTaskObjectLifetime.Build, allowEarlyCollection: true); return(success); }
private void AddAssemblies(ZipArchiveEx apk) { bool debug = _Debug; bool compress = !debug && EnableCompression; bool use_shared_runtime = String.Equals(UseSharedRuntime, "true", StringComparison.OrdinalIgnoreCase); string sourcePath; AssemblyCompression.AssemblyData compressedAssembly = null; IDictionary <string, CompressedAssemblyInfo> compressedAssembliesInfo = null; if (compress) { compressedAssembliesInfo = BuildEngine4.GetRegisteredTaskObject(CompressedAssemblyInfo.CompressedAssembliesInfoKey, RegisteredTaskObjectLifetime.Build) as IDictionary <string, CompressedAssemblyInfo>; } int count = 0; foreach (ITaskItem assembly in ResolvedUserAssemblies) { if (bool.TryParse(assembly.GetMetadata("AndroidSkipAddToPackage"), out bool value) && value) { Log.LogDebugMessage($"Skipping {assembly.ItemSpec} due to 'AndroidSkipAddToPackage' == 'true' "); continue; } if (MonoAndroidHelper.IsReferenceAssembly(assembly.ItemSpec)) { Log.LogCodedWarning("XA0107", assembly.ItemSpec, 0, Properties.Resources.XA0107, assembly.ItemSpec); } sourcePath = CompressAssembly(assembly); // Add assembly AddFileToArchiveIfNewer(apk, sourcePath, GetTargetDirectory(assembly.ItemSpec) + "/" + Path.GetFileName(assembly.ItemSpec), compressionMethod: UncompressedMethod); // Try to add config if exists var config = Path.ChangeExtension(assembly.ItemSpec, "dll.config"); AddAssemblyConfigEntry(apk, config); // Try to add symbols if Debug if (debug) { var symbols = Path.ChangeExtension(assembly.ItemSpec, "dll.mdb"); if (File.Exists(symbols)) { AddFileToArchiveIfNewer(apk, symbols, AssembliesPath + Path.GetFileName(symbols), compressionMethod: UncompressedMethod); } symbols = Path.ChangeExtension(assembly.ItemSpec, "pdb"); if (File.Exists(symbols)) { AddFileToArchiveIfNewer(apk, symbols, AssembliesPath + Path.GetFileName(symbols), compressionMethod: UncompressedMethod); } } count++; if (count == ZipArchiveEx.ZipFlushLimit) { apk.Flush(); count = 0; } } if (use_shared_runtime) { return; } count = 0; // Add framework assemblies foreach (ITaskItem assembly in ResolvedFrameworkAssemblies) { if (bool.TryParse(assembly.GetMetadata("AndroidSkipAddToPackage"), out bool value) && value) { Log.LogDebugMessage($"Skipping {assembly.ItemSpec} due to 'AndroidSkipAddToPackage' == 'true' "); continue; } if (MonoAndroidHelper.IsReferenceAssembly(assembly.ItemSpec)) { Log.LogCodedWarning("XA0107", assembly.ItemSpec, 0, Properties.Resources.XA0107, assembly.ItemSpec); } sourcePath = CompressAssembly(assembly); AddFileToArchiveIfNewer(apk, sourcePath, AssembliesPath + Path.GetFileName(assembly.ItemSpec), compressionMethod: UncompressedMethod); var config = Path.ChangeExtension(assembly.ItemSpec, "dll.config"); AddAssemblyConfigEntry(apk, config); // Try to add symbols if Debug if (debug) { var symbols = Path.ChangeExtension(assembly.ItemSpec, "dll.mdb"); if (File.Exists(symbols)) { AddFileToArchiveIfNewer(apk, symbols, AssembliesPath + Path.GetFileName(symbols), compressionMethod: UncompressedMethod); } symbols = Path.ChangeExtension(assembly.ItemSpec, "pdb"); if (File.Exists(symbols)) { AddFileToArchiveIfNewer(apk, symbols, AssembliesPath + Path.GetFileName(symbols), compressionMethod: UncompressedMethod); } } count++; if (count == ZipArchiveEx.ZipFlushLimit) { apk.Flush(); count = 0; } } void EnsureCompressedAssemblyData(string sourcePath, uint descriptorIndex) { if (compressedAssembly == null) { compressedAssembly = new AssemblyCompression.AssemblyData(sourcePath, descriptorIndex); } else { compressedAssembly.SetData(sourcePath, descriptorIndex); } } string CompressAssembly(ITaskItem assembly) { if (!compress) { return(assembly.ItemSpec); } if (bool.TryParse(assembly.GetMetadata("AndroidSkipCompression"), out bool value) && value) { Log.LogDebugMessage($"Skipping compression of {assembly.ItemSpec} due to 'AndroidSkipCompression' == 'true' "); return(assembly.ItemSpec); } if (compressedAssembliesInfo.TryGetValue(Path.GetFileName(assembly.ItemSpec), out CompressedAssemblyInfo info) && info != null) { EnsureCompressedAssemblyData(assembly.ItemSpec, info.DescriptorIndex); AssemblyCompression.CompressionResult result = AssemblyCompression.Compress(compressedAssembly); if (result != AssemblyCompression.CompressionResult.Success) { switch (result) { case AssemblyCompression.CompressionResult.EncodingFailed: Log.LogMessage($"Failed to compress {assembly.ItemSpec}"); break; case AssemblyCompression.CompressionResult.InputTooBig: Log.LogMessage($"Input assembly {assembly.ItemSpec} exceeds maximum input size"); break; default: Log.LogMessage($"Unknown error compressing {assembly.ItemSpec}"); break; } return(assembly.ItemSpec); } return(compressedAssembly.DestinationPath); } return(assembly.ItemSpec); } }
public override bool Execute() { var entry = (RegisterObject)BuildEngine4.GetRegisteredTaskObject(RegisterObject.CacheKey, RegisteredTaskObjectLifetime.Build); return(true); }
public override bool Execute() { var key = (WorkingDirectory, XASourceDirectory, SubmoduleName, GitRemoteName); var cached = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.Build) as string; if (!string.IsNullOrEmpty(cached)) { Log.LogMessage(MessageImportance.Normal, "Using cached information from earlier in the build"); CommitInfo = cached; goto outOfHere; } if (String.IsNullOrEmpty(GitPath?.Trim())) { GitPath = "git"; } bool isSubmodule = !String.IsNullOrEmpty(SubmoduleName); string submoduleInfo = isSubmodule ? $" submodule {SubmoduleName}" : String.Empty; Log.LogMessage(MessageImportance.Normal, $"Gathering GIT commit info{submoduleInfo} in directory '{WorkingDirectory}'"); var stdoutLines = new List <string> (); var stderrLines = new List <string> (); if (!RunGit("log -n 1 --pretty=%D HEAD", stdoutLines, stderrLines)) { goto outOfHere; } string gitModules = Path.Combine(XASourceDirectory, ".gitmodules"); string branchFull = stdoutLines [0].Trim(); string branch; if (branchFull.StartsWith("HEAD, ", StringComparison.Ordinal)) { Log.LogMessage(MessageImportance.Low, " Detached HEAD, branch information available"); // Detached HEAD with branch information // Sample format: // // HEAD, origin/master, origin/d16-0-p1, origin/HEAD, master // branch = branchFull.Substring(6); } else if (branchFull.StartsWith("HEAD -> ", StringComparison.Ordinal)) { Log.LogMessage(MessageImportance.Low, " Normal branch"); // Normal branch // Sample format: // // HEAD -> bundle-ndk16-fix, origin/pr/1105 // branch = branchFull.Substring(8); } else if (String.Compare("HEAD", branchFull, StringComparison.Ordinal) == 0) { Log.LogMessage(MessageImportance.Low, " Detached HEAD, no branch information"); // Detached HEAD without branch information if (isSubmodule) { if (!RunGit($"config -f {gitModules} --get \"submodule.{SubmoduleName}.branch\"", stdoutLines, stderrLines)) { goto outOfHere; } branch = stdoutLines [0]; } else { Log.LogWarning($"Unable to determine branch name from detached head state in directory {WorkingDirectory}"); branch = "unknown"; } } else { Log.LogError($"Unable to parse branch name from: {branchFull}"); branch = null; goto outOfHere; } int separator = branch.IndexOf(','); if (separator >= 0) { // We choose the first branch from the list branch = branch.Substring(0, separator).Trim(); } separator = branch.IndexOf('/'); if (separator >= 0) { branch = branch.Substring(separator + 1).Trim(); } if (branch.StartsWith("tag: ", StringComparison.Ordinal)) { branch = branch.Substring(5).Trim(); } if (String.IsNullOrEmpty(branch)) { Log.LogError($"Unsupported branch information format: '{branchFull}'"); goto outOfHere; } Log.LogMessage(MessageImportance.Low, $" Branch: {branch}"); if (!RunGit("log -n 1 --pretty=%h HEAD", stdoutLines, stderrLines)) { goto outOfHere; } string commit = stdoutLines [0].Trim(); Log.LogMessage(MessageImportance.Low, $" Commit hash: {commit}"); string url; if (isSubmodule) { if (!RunGit($"config -f {gitModules} --get \"submodule.{SubmoduleName}.url\"", stdoutLines, stderrLines)) { goto outOfHere; } url = stdoutLines [0].Trim(); } else { string remoteName = String.IsNullOrEmpty(GitRemoteName) ? "origin" : GitRemoteName; if (!RunGit($"config --local --get \"remote.{remoteName}.url\"", stdoutLines, stderrLines)) { goto outOfHere; } url = stdoutLines [0].Trim(); } Log.LogMessage(MessageImportance.Low, $" Repository URL: {url}"); string organization; string repo; bool urlParsed; if (url.StartsWith("git@", StringComparison.Ordinal)) { urlParsed = ParseGitURL(url, out organization, out repo); } else if (url.StartsWith("https://", StringComparison.Ordinal)) { urlParsed = ParseHttpsURL(url, out organization, out repo); } else if (url.StartsWith("../../", StringComparison.Ordinal)) { // Special case for monodroid (although it will most likely return the git@ URL anyway) urlParsed = ParseRelativePathURL(url, out organization, out repo); } else { Log.LogError($"Unknown URL schema in '{url}' for directory '{WorkingDirectory}'"); goto outOfHere; } Log.LogMessage(MessageImportance.Low, $" Organization: {organization}"); Log.LogMessage(MessageImportance.Low, $" Repository: {repo}"); CommitInfo = $"{organization}/{repo}/{branch}@{commit}"; BuildEngine4.RegisterTaskObject(key, CommitInfo, RegisteredTaskObjectLifetime.Build, allowEarlyCollection: false); outOfHere: return(!Log.HasLoggedErrors); }
public override bool RunTask() { if (InputAssemblies == null) { return(true); } var output = new List <ITaskItem> (InputAssemblies.Length); foreach (var assemblyItem in InputAssemblies) { if (!File.Exists(assemblyItem.ItemSpec)) { Log.LogDebugMessage($"Skipping non-existent dependency '{assemblyItem.ItemSpec}'."); continue; } using (var pe = new PEReader(File.OpenRead(assemblyItem.ItemSpec))) { var reader = pe.GetMetadataReader(); // Check in-memory cache var module = reader.GetModuleDefinition(); var key = (nameof(FilterAssemblies), reader.GetGuid(module.Mvid)); var value = BuildEngine4.GetRegisteredTaskObject(key, Lifetime); if (value is bool isMonoAndroidAssembly) { if (isMonoAndroidAssembly) { Log.LogDebugMessage($"Cached: {assemblyItem.ItemSpec}"); output.Add(assemblyItem); } continue; } // Check assembly definition var assemblyDefinition = reader.GetAssemblyDefinition(); var targetFrameworkIdentifier = GetTargetFrameworkIdentifier(assemblyDefinition, reader); if (string.Compare(targetFrameworkIdentifier, TargetFrameworkIdentifier, StringComparison.OrdinalIgnoreCase) == 0) { output.Add(assemblyItem); BuildEngine4.RegisterTaskObject(key, true, Lifetime, AllowEarlyCollection); continue; } // Fallback to looking for a Mono.Android reference if (MonoAndroidHelper.HasMonoAndroidReference(reader)) { Log.LogDebugMessage($"Mono.Android reference found: {assemblyItem.ItemSpec}"); output.Add(assemblyItem); BuildEngine4.RegisterTaskObject(key, true, Lifetime, AllowEarlyCollection); continue; } // Fallback to looking for *.jar or __Android EmbeddedResource files if (HasEmbeddedResource(reader)) { Log.LogDebugMessage($"EmbeddedResource found: {assemblyItem.ItemSpec}"); output.Add(assemblyItem); BuildEngine4.RegisterTaskObject(key, true, Lifetime, AllowEarlyCollection); continue; } // Not a MonoAndroid assembly, store false BuildEngine4.RegisterTaskObject(key, false, Lifetime, AllowEarlyCollection); } } OutputAssemblies = output.ToArray(); return(!Log.HasLoggedErrors); }