bool ValidateApiLevels() { // Priority: // $(UseLatestAndroidPlatformSdk) > $(AndroidApiLevel) > $(TargetFrameworkVersion) // // If $(TargetFrameworkVersion) isn't set, and $(AndroidApiLevel) isn't // set, act as if $(UseLatestAndroidPlatformSdk) is True // // If $(UseLatestAndroidPlatformSdk) is true, we do as it says: use the // latest installed version. // // Otherwise, if $(AndroidApiLevel) is set, use it and set $(TargetFrameworkVersion). // Rationale: monodroid/samples/xbuild.make uses $(AndroidApiLevel) // to build for a specific API level. // Otherwise, if $(TargetFrameworkVersion) is set, use it and set $(AndroidApiLevel). UseLatestAndroidPlatformSdk = UseLatestAndroidPlatformSdk || (string.IsNullOrWhiteSpace(AndroidApiLevel) && string.IsNullOrWhiteSpace(TargetFrameworkVersion)); if (UseLatestAndroidPlatformSdk) { AndroidApiLevel = GetMaxInstalledApiLevel().ToString(); SupportedApiLevel = GetMaxSupportedApiLevel(AndroidApiLevel); int maxInstalled, maxSupported = 0; if (int.TryParse(AndroidApiLevel, out maxInstalled) && int.TryParse(SupportedApiLevel, out maxSupported) && maxInstalled > maxSupported) { Log.LogDebugMessage($"API Level {AndroidApiLevel} is greater than the maximum supported API level of {SupportedApiLevel}. " + "Support for this API will be added in a future release."); AndroidApiLevel = SupportedApiLevel; } TargetFrameworkVersion = GetTargetFrameworkVersionFromApiLevel(); return(TargetFrameworkVersion != null); } if (!string.IsNullOrWhiteSpace(AndroidApiLevel)) { AndroidApiLevel = AndroidApiLevel.Trim(); SupportedApiLevel = GetMaxSupportedApiLevel(AndroidApiLevel); TargetFrameworkVersion = GetTargetFrameworkVersionFromApiLevel(); return(TargetFrameworkVersion != null); } if (!string.IsNullOrWhiteSpace(TargetFrameworkVersion)) { TargetFrameworkVersion = TargetFrameworkVersion.Trim(); string apiLevel = MonoDroidSdk.GetApiLevelForFrameworkVersion(TargetFrameworkVersion); if (apiLevel == null) { Log.LogCodedError("XA0000", "Could not determine API level for $(TargetFrameworkVersion) of '{0}'.", TargetFrameworkVersion); return(false); } AndroidApiLevel = apiLevel; SupportedApiLevel = apiLevel; return(true); } Log.LogCodedError("XA0000", "Could not determine $(AndroidApiLevel) or $(TargetFrameworkVersion); SHOULD NOT BE REACHED."); return(false); }
string GetMaxSupportedApiLevel(string apiLevel) { int level = 0; if (!int.TryParse(apiLevel, NumberStyles.Integer, CultureInfo.InvariantCulture, out level)) { return(apiLevel); } if (ReferenceAssemblyPaths == null) { return(apiLevel); } foreach (string versionedDir in ReferenceAssemblyPaths) { string parent = Path.GetDirectoryName(versionedDir.TrimEnd(Path.DirectorySeparatorChar)); for (int l = level; l > 0; l--) { string tfv = MonoDroidSdk.GetFrameworkVersionForApiLevel(l.ToString()); if (tfv == null) { continue; } string dir = Path.Combine(parent, tfv); if (Directory.Exists(dir)) { return(l.ToString()); } } } return(apiLevel); }
public MonoDroidSdkSettingsWidget() { this.Build(); var path = Environment.GetEnvironmentVariable("PATH"); pathDirs = path.Split(new char[] { System.IO.Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries); string configuredAndroidSdk, configuredJavaSdk; MonoDroidSdk.GetConfiguredSdkLocations(out configuredAndroidSdk, out configuredJavaSdk, new Microsoft.Build.Utilities.TaskLoggingHelper()); androidFolderEntry.Path = configuredAndroidSdk ?? ""; javaFolderEntry.Path = configuredJavaSdk ?? ""; androidFolderEntry.PathChanged += delegate { ValidateAndroid(); OnSettingsChanged(EventArgs.Empty); }; javaFolderEntry.PathChanged += delegate { ValidateJava(); OnSettingsChanged(EventArgs.Empty); }; ValidateAndroid(); ValidateJava(); }
void ValidateAndroid() { FilePath location = androidFolderEntry.Path; if (!location.IsNullOrEmpty) { if (!MonoDroidSdk.ValidateAndroidSdkLocation(location)) { androidLocationMessage.Text = GettextCatalog.GetString("No SDK found at specified location."); androidLocationIcon.Stock = Gtk.Stock.Cancel; isAndroidPathValid = false; } else { androidLocationMessage.Text = GettextCatalog.GetString("SDK found at specified location."); androidLocationIcon.Stock = Gtk.Stock.Apply; isAndroidPathValid = true; } return; } location = MonoDroidSdk.FindAndroidSdk(pathDirs); if (location.IsNullOrEmpty) { androidLocationMessage.Text = GettextCatalog.GetString("SDK not found. Please specify location."); androidLocationIcon.Stock = Gtk.Stock.Cancel; isAndroidPathValid = false; } else { androidLocationMessage.Text = GettextCatalog.GetString("SDK found automatically."); androidLocationIcon.Stock = Gtk.Stock.Apply; isAndroidPathValid = true; } }
public static void RefreshMonoDroidSdk(string toolsPath, string binPath, string[] referenceAssemblyPaths) { MonoDroidSdk.Refresh(toolsPath, binPath, (from refPath in referenceAssemblyPaths ?? new string [0] where !string.IsNullOrEmpty(refPath) let path = refPath.TrimEnd(Path.DirectorySeparatorChar) where File.Exists(Path.Combine(path, "mscorlib.dll")) select path) .FirstOrDefault()); }
bool ValidateApiLevels() { // Priority: // $(UseLatestAndroidPlatformSdk) > $(AndroidApiLevel) > $(TargetFrameworkVersion) // // If $(TargetFrameworkVersion) isn't set, and $(AndroidApiLevel) isn't // set, act as if $(UseLatestAndroidPlatformSdk) is True // // If $(UseLatestAndroidPlatformSdk) is true, we do as it says: use the // latest installed version. // // Otherwise, if $(AndroidApiLevel) is set, use it and set $(TargetFrameworkVersion). // Rationale: monodroid/samples/xbuild.make uses $(AndroidApiLevel) // to build for a specific API level. // Otherwise, if $(TargetFrameworkVersion) is set, use it and set $(AndroidApiLevel). UseLatestAndroidPlatformSdk = UseLatestAndroidPlatformSdk || (string.IsNullOrWhiteSpace(AndroidApiLevel) && string.IsNullOrWhiteSpace(TargetFrameworkVersion)); if (UseLatestAndroidPlatformSdk) { AndroidApiLevel = GetMaxInstalledApiLevel().ToString(); SupportedApiLevel = GetMaxSupportedApiLevel(AndroidApiLevel); TargetFrameworkVersion = GetTargetFrameworkVersionFromApiLevel(); return(TargetFrameworkVersion != null); } if (!string.IsNullOrWhiteSpace(AndroidApiLevel)) { AndroidApiLevel = AndroidApiLevel.Trim(); SupportedApiLevel = GetMaxSupportedApiLevel(AndroidApiLevel); TargetFrameworkVersion = GetTargetFrameworkVersionFromApiLevel(); return(TargetFrameworkVersion != null); } if (!string.IsNullOrWhiteSpace(TargetFrameworkVersion)) { TargetFrameworkVersion = TargetFrameworkVersion.Trim(); string apiLevel = MonoDroidSdk.GetApiLevelForFrameworkVersion(TargetFrameworkVersion); if (apiLevel == null) { Log.LogCodedError("XA0000", "Could not determine API level for $(TargetFrameworkVersion) of '{0}'.", TargetFrameworkVersion); return(false); } AndroidApiLevel = apiLevel; SupportedApiLevel = apiLevel; return(true); } Log.LogCodedError("XA0000", "Could not determine $(AndroidApiLevel) or $(TargetFrameworkVersion); SHOULD NOT BE REACHED."); return(false); }
internal static void UpdateSdkLocations() { try { var oldAndroidBinDir = AndroidBinDir; MonoDroidToolsDir = MonoDroidFrameworkDir = AndroidBinDir = JavaBinDir = null; Toolbox = null; EnvironmentOverrides.Remove("PATH"); string monoDroidToolsDir, monoDroidFrameworkDir, javaPath, androidPath; MonoDroidSdk.GetPaths(out monoDroidToolsDir, out monoDroidFrameworkDir, out androidPath, out javaPath, new Microsoft.Build.Utilities.TaskLoggingHelper()); if (monoDroidToolsDir == null) { LoggingService.LogInfo("Mono for Android SDK not found, disabling Mono for Android addin"); return; } MonoDroidToolsDir = monoDroidToolsDir; MonoDroidFrameworkDir = monoDroidFrameworkDir; if (androidPath == null) { LoggingService.LogError("Android SDK not found, needed by Mono for Android addin"); return; } if (javaPath == null) { LoggingService.LogError("Java SDK not found, needed by Mono for Android addin"); return; } JavaBinDir = Path.Combine(javaPath, "bin"); AndroidBinDir = androidPath; EnvironmentOverrides ["PATH"] = AndroidBinDir + Path.PathSeparator + JavaBinDir + Path.PathSeparator + Environment.GetEnvironmentVariable("PATH"); Toolbox = new AndroidToolbox(AndroidBinDir, JavaBinDir); if (oldAndroidBinDir != AndroidBinDir) { DeviceManager.AndroidSdkChanged(); } } catch (Exception ex) { LoggingService.LogError("Error detecting Mono for Android SDK", ex); } }
string GetTargetFrameworkVersionFromApiLevel() { string targetFramework = MonoDroidSdk.GetFrameworkVersionForApiLevel(SupportedApiLevel) ?? MonoDroidSdk.GetFrameworkVersionForApiLevel(AndroidApiLevel); if (targetFramework != null) { return(targetFramework); } Log.LogCodedError("XA0000", "Could not determine $(TargetFrameworkVersion) for API level '{0}.'", AndroidApiLevel); return(null); }
string GetTargetSdkVersion(string target, XAttribute target_sdk) { string targetFrameworkVersion = MonoAndroidHelper.GetPlatformApiLevel(AndroidSdkPlatform); string targetSdkVersion = MonoAndroidHelper.GetPlatformApiLevel(target); int frameworkSdk, targetSdk; if (int.TryParse(targetFrameworkVersion, out frameworkSdk) && int.TryParse(targetSdkVersion, out targetSdk) && targetSdk < frameworkSdk) { int lineNumber = 0; int columnNumber = 0; var lineInfo = target_sdk as IXmlLineInfo; if (lineInfo != null && lineInfo.HasLineInfo()) { lineNumber = lineInfo.LineNumber; columnNumber = lineInfo.LinePosition; } Log.LogWarning( subcategory: string.Empty, warningCode: "XA4211", helpKeyword: string.Empty, file: AndroidManifest, lineNumber: lineNumber, columnNumber: columnNumber, endLineNumber: 0, endColumnNumber: 0, message: "AndroidManifest.xml //uses-sdk/@android:targetSdkVersion '{0}' is less than $(TargetFrameworkVersion) '{1}'. Using API-{2} for ACW compilation.", messageArgs: new[] { targetSdkVersion, MonoDroidSdk.GetFrameworkVersionForApiLevel(targetFrameworkVersion), MonoAndroidHelper.GetPlatformApiLevelName(targetFrameworkVersion), } ); return(targetFrameworkVersion); } return(targetSdkVersion); }
public void ApplyChanges() { MonoDroidSdk.SetConfiguredSdkLocations(androidFolderEntry.Path, javaFolderEntry.Path); MonoDroidFramework.UpdateSdkLocations(); }
public override bool Execute() { Log.LogDebugMessage("GeneratePackageManagerJava Task"); Log.LogDebugMessage(" OutputDirectory: {0}", OutputDirectory); Log.LogDebugMessage(" TargetFrameworkVersion: {0}", TargetFrameworkVersion); Log.LogDebugMessage(" Manifest: {0}", Manifest); Log.LogDebugMessage(" UseSharedRuntime: {0}", UseSharedRuntime); Log.LogDebugMessage(" MainAssembly: {0}", MainAssembly); Log.LogDebugTaskItems(" ResolvedAssemblies:", ResolvedAssemblies); Log.LogDebugTaskItems(" ResolvedUserAssemblies:", ResolvedUserAssemblies); var shared_runtime = string.Compare(UseSharedRuntime, "true", true) == 0; var doc = AndroidAppManifest.Load(Manifest); int minApiVersion = doc.MinSdkVersion == null ? 4 : (int)doc.MinSdkVersion; // We need to include any special assemblies in the Assemblies list var assemblies = ResolvedUserAssemblies.Select(p => p.ItemSpec) .Concat(MonoAndroidHelper.GetFrameworkAssembliesToTreatAsUserAssemblies(ResolvedAssemblies)) .ToList(); var mainFileName = Path.GetFileName(MainAssembly); Func <string, string, bool> fileNameEq = (a, b) => a.Equals(b, StringComparison.OrdinalIgnoreCase); assemblies = assemblies.Where(a => fileNameEq(a, mainFileName)).Concat(assemblies.Where(a => !fileNameEq(a, mainFileName))).ToList(); // Write first to a temporary file var temp = Path.GetTempFileName(); using (var pkgmgr = File.CreateText(temp)) { // Write the boilerplate from the MonoPackageManager.java resource var packageManagerResource = minApiVersion < 9 ? "MonoPackageManager.api4.java" : "MonoPackageManager.java"; using (var template = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(packageManagerResource))) { string line; while ((line = template.ReadLine()) != null) { pkgmgr.WriteLine(line); } } // Write all the user assemblies pkgmgr.WriteLine("class MonoPackageManager_Resources {"); pkgmgr.WriteLine("\tpublic static final String[] Assemblies = new String[]{"); pkgmgr.WriteLine("\t\t/* We need to ensure that \"{0}\" comes first in this list. */", mainFileName); foreach (var assembly in assemblies) { pkgmgr.WriteLine("\t\t\"" + Path.GetFileName(assembly) + "\","); } // Write the assembly dependencies pkgmgr.WriteLine("\t};"); pkgmgr.WriteLine("\tpublic static final String[] Dependencies = new String[]{"); //foreach (var assembly in assemblies.Except (args.Assemblies)) { // if (args.SharedRuntime && !Toolbox.IsInSharedRuntime (assembly)) // pkgmgr.WriteLine ("\t\t\"" + Path.GetFileName (assembly) + "\","); //} pkgmgr.WriteLine("\t};"); // Write the platform api apk we need pkgmgr.WriteLine("\tpublic static final String ApiPackageName = {0};", shared_runtime ? string.Format("\"Mono.Android.Platform.ApiLevel_{0}\"", MonoDroidSdk.GetApiLevelForFrameworkVersion(TargetFrameworkVersion)) : "null"); pkgmgr.WriteLine("}"); } // Only copy to the real location if the contents actually changed var dest = Path.GetFullPath(Path.Combine(OutputDirectory, "MonoPackageManager.java")); MonoAndroidHelper.CopyIfChanged(temp, dest); try { File.Delete(temp); } catch (Exception) { } try { File.Delete(temp); } catch (Exception) { } return(!Log.HasLoggedErrors); }