protected override string GenerateCommandLineCommands() { // For creating Resource.Designer.cs: // Running command: C:\Program Files (x86)\Android\android-sdk-windows\platform-tools\aapt // "package" // "-M" "C:\Users\Jonathan\AppData\Local\Temp\ryob4gaw.way\AndroidManifest.xml" // "-J" "C:\Users\Jonathan\AppData\Local\Temp\ryob4gaw.way" // "-F" "C:\Users\Jonathan\AppData\Local\Temp\ryob4gaw.way\resources.apk" // "-S" "c:\users\jonathan\documents\visual studio 2010\Projects\MonoAndroidApplication4\MonoAndroidApplication4\obj\Debug\res" // "-I" "C:\Program Files (x86)\Android\android-sdk-windows\platforms\android-8\android.jar" // "--max-res-version" "10" // For packaging: // Running command: C:\Program Files (x86)\Android\android-sdk-windows\platform-tools\aapt // "package" // "-f" // "-m" // "-M" "AndroidManifest.xml" // "-J" "src" // "--custom-package" "androidmsbuildtest.androidmsbuildtest" // "-F" "bin\packaged_resources" // "-S" "C:\Users\Jonathan\Documents\Visual Studio 2010\Projects\AndroidMSBuildTest\AndroidMSBuildTest\obj\Debug\res" // "-I" "C:\Program Files (x86)\Android\android-sdk-windows\platforms\android-8\android.jar" // "--extra-packages" "com.facebook.android:my.another.library" var cmd = new CommandLineBuilder (); cmd.AppendSwitch ("package"); if (MonoAndroidHelper.LogInternalExceptions) cmd.AppendSwitch ("-v"); if (NonConstantId) cmd.AppendSwitch ("--non-constant-id"); cmd.AppendSwitch ("-f"); cmd.AppendSwitch ("-m"); string manifestFile; string manifestDir = Path.Combine (Path.GetDirectoryName (ManifestFile), currentAbi != null ? currentAbi : "manifest"); Directory.CreateDirectory (manifestDir); manifestFile = Path.Combine (manifestDir, Path.GetFileName (ManifestFile)); ManifestDocument manifest = new ManifestDocument (ManifestFile, this.Log); if (currentAbi != null) manifest.SetAbi (currentAbi); manifest.ApplicationName = ApplicationName; manifest.Save (manifestFile); currentResourceOutputFile = currentAbi != null ? string.Format ("{0}-{1}", ResourceOutputFile, currentAbi) : ResourceOutputFile; cmd.AppendSwitchIfNotNull ("-M ", manifestFile); Directory.CreateDirectory (JavaDesignerOutputDirectory); cmd.AppendSwitchIfNotNull ("-J ", JavaDesignerOutputDirectory); if (PackageName != null) cmd.AppendSwitchIfNotNull ("--custom-package ", PackageName.ToLowerInvariant ()); if (!string.IsNullOrEmpty (currentResourceOutputFile)) cmd.AppendSwitchIfNotNull ("-F ", currentResourceOutputFile + ".bk"); // The order of -S arguments is *important*, always make sure this one comes FIRST cmd.AppendSwitchIfNotNull ("-S ", ResourceDirectory.TrimEnd ('\\')); if (AdditionalResourceDirectories != null) foreach (var resdir in AdditionalResourceDirectories) cmd.AppendSwitchIfNotNull ("-S ", resdir.ItemSpec.TrimEnd ('\\')); if (AdditionalAndroidResourcePaths != null) foreach (var dir in AdditionalAndroidResourcePaths) cmd.AppendSwitchIfNotNull ("-S ", Path.Combine (dir.ItemSpec.TrimEnd (System.IO.Path.DirectorySeparatorChar), "res")); if (LibraryProjectJars != null) foreach (var jar in LibraryProjectJars) cmd.AppendSwitchIfNotNull ("-j ", jar); cmd.AppendSwitchIfNotNull ("-I ", JavaPlatformJarPath); // Add asset directory if it exists if (!string.IsNullOrWhiteSpace (AssetDirectory) && Directory.Exists (AssetDirectory)) cmd.AppendSwitchIfNotNull ("-A ", AssetDirectory.TrimEnd ('\\')); if (!string.IsNullOrWhiteSpace (UncompressedFileExtensions)) foreach (var ext in UncompressedFileExtensions.Split (new char[] { ';', ','}, StringSplitOptions.RemoveEmptyEntries)) cmd.AppendSwitchIfNotNull ("-0 ", ext); if (!string.IsNullOrEmpty (ExtraPackages)) cmd.AppendSwitchIfNotNull ("--extra-packages ", ExtraPackages); // TODO: handle resource names if (ExplicitCrunch) cmd.AppendSwitch ("--no-crunch"); cmd.AppendSwitch ("--auto-add-overlay"); var extraArgsExpanded = ExpandString (ExtraArgs); if (extraArgsExpanded != ExtraArgs) Log.LogDebugMessage (" ExtraArgs expanded: {0}", extraArgsExpanded); if (!string.IsNullOrWhiteSpace (extraArgsExpanded)) cmd.AppendSwitch (extraArgsExpanded); if (!AndroidUseLatestPlatformSdk) cmd.AppendSwitchIfNotNull ("--max-res-version ", ApiLevel); return cmd.ToString (); }
void Run() { PackageNamingPolicy pnp; JniType.PackageNamingPolicy = Enum.TryParse (PackageNamingPolicy, out pnp) ? pnp : PackageNamingPolicyEnum.LowercaseHash; var temp = Path.Combine (Path.GetTempPath (), Path.GetRandomFileName ()); Directory.CreateDirectory (temp); // We're going to do 3 steps here instead of separate tasks so // we can share the list of JLO TypeDefinitions between them var res = new DirectoryAssemblyResolver (Log.LogWarning, loadDebugSymbols:true); var selectedWhitelistAssemblies = new List<string> (); // Put every assembly we'll need in the resolver foreach (var assembly in ResolvedAssemblies) { res.Load (Path.GetFullPath (assembly.ItemSpec)); if (MonoAndroidHelper.FrameworkAttributeLookupTargets.Any (a => Path.GetFileName (assembly.ItemSpec) == a)) selectedWhitelistAssemblies.Add (Path.GetFullPath (assembly.ItemSpec)); } // However we only want to look for JLO types in user code var assemblies = ResolvedUserAssemblies.Select (p => p.ItemSpec).ToList (); var fxAdditions = MonoAndroidHelper.GetFrameworkAssembliesToTreatAsUserAssemblies (ResolvedAssemblies) .Where (a => assemblies.All (x => Path.GetFileName (x) != Path.GetFileName (a))); assemblies = assemblies.Concat (fxAdditions).ToList (); // Step 1 - Find all the JLO types var all_java_types = JavaTypeScanner.GetJavaTypes (assemblies, res, Log.LogWarning); WriteTypeMappings (all_java_types); var java_types = all_java_types.Where (t => !JavaTypeScanner.ShouldSkipJavaCallableWrapperGeneration (t)); // Step 2 - Generate Java stub code var keep_going = Generator.CreateJavaSources ( Log, java_types, temp, UseSharedRuntime, int.Parse (AndroidSdkPlatform) <= 10, ResolvedAssemblies.Any (assembly => Path.GetFileName (assembly.ItemSpec) == "Mono.Android.Export.dll")); var temp_map_file = Path.Combine (temp, "acw-map.temp"); // We need to save a map of .NET type -> ACW type for resource file fixups var managed = new Dictionary<string, TypeDefinition> (); var java = new Dictionary<string, TypeDefinition> (); var acw_map = new StreamWriter (temp_map_file); foreach (var type in java_types) { string managedKey = type.FullName.Replace ('/', '.'); string javaKey = JniType.ToJniName (type).Replace ('/', '.'); acw_map.WriteLine ("{0};{1}", type.GetPartialAssemblyQualifiedName (), javaKey); acw_map.WriteLine ("{0};{1}", type.GetAssemblyQualifiedName (), javaKey); TypeDefinition conflict; if (managed.TryGetValue (managedKey, out conflict)) { Log.LogWarning ( "Duplicate managed type found! Mappings between managed types and Java types must be unique. " + "First Type: '{0}'; Second Type: '{1}'.", conflict.GetAssemblyQualifiedName (), type.GetAssemblyQualifiedName ()); Log.LogWarning ( "References to the type '{0}' will refer to '{1}'.", managedKey, conflict.GetAssemblyQualifiedName ()); continue; } if (java.TryGetValue (javaKey, out conflict)) { Log.LogError ( "Duplicate Java type found! Mappings between managed types and Java types must be unique. " + "First Type: '{0}'; Second Type: '{1}'", conflict.GetAssemblyQualifiedName (), type.GetAssemblyQualifiedName ()); keep_going = false; continue; } managed.Add (managedKey, type); java.Add (javaKey, type); acw_map.WriteLine ("{0};{1}", managedKey, javaKey); acw_map.WriteLine ("{0};{1}", JniType.ToCompatJniName (type).Replace ('/', '.'), javaKey); } acw_map.Close (); //The previous steps found an error, so we must abort and not generate any further output //We must do so subsequent unchanged builds fail too. if (!keep_going) { File.Delete (temp_map_file); return; } MonoAndroidHelper.CopyIfChanged (temp_map_file, AcwMapFile); try { File.Delete (temp_map_file); } catch (Exception) { } // Only overwrite files if the contents actually changed foreach (var file in Directory.GetFiles (temp, "*", SearchOption.AllDirectories)) { var dest = Path.GetFullPath (Path.Combine (OutputDirectory, "src", file.Substring (temp.Length + 1))); MonoAndroidHelper.CopyIfChanged (file, dest); } // Step 3 - Merge [Activity] and friends into AndroidManifest.xml var manifest = new ManifestDocument (ManifestTemplate, this.Log); manifest.PackageName = PackageName; manifest.ApplicationName = ApplicationName ?? PackageName; manifest.Assemblies.AddRange (assemblies); manifest.Resolver = res; manifest.SdkDir = AndroidSdkDir; manifest.SdkVersion = AndroidSdkPlatform; manifest.Debug = Debug; manifest.NeedsInternet = NeedsInternet; var additionalProviders = manifest.Merge (all_java_types, selectedWhitelistAssemblies, ApplicationJavaClass, EmbedAssemblies, BundledWearApplicationName, MergedManifestDocuments); var temp_manifest = Path.Combine (temp, "AndroidManifest.xml"); var real_manifest = Path.GetFullPath (MergedAndroidManifestOutput); manifest.Save (temp_manifest); // Only write the new manifest if it actually changed MonoAndroidHelper.CopyIfChanged (temp_manifest, real_manifest); // Create additional runtime provider java sources. string providerTemplateFile = UseSharedRuntime ? "MonoRuntimeProvider.Shared.java" : "MonoRuntimeProvider.Bundled.java"; string providerTemplate = new StreamReader (typeof (JavaCallableWrapperGenerator).Assembly.GetManifestResourceStream (providerTemplateFile)).ReadToEnd (); foreach (var provider in additionalProviders) { var temp_provider = Path.Combine (temp, provider + ".java"); File.WriteAllText (temp_provider, providerTemplate.Replace ("MonoRuntimeProvider", provider)); var real_provider_dir = Path.GetFullPath (Path.Combine (OutputDirectory, "src", "mono")); Directory.CreateDirectory (real_provider_dir); var real_provider = Path.Combine (real_provider_dir, provider + ".java"); MonoAndroidHelper.CopyIfChanged (temp_provider, real_provider); } // Create additional application java sources. Action<string,string,string,Func<string,string>> save = (resource, filename, destDir, applyTemplate) => { string temp_file = Path.Combine (temp, filename); string template = applyTemplate (new StreamReader (typeof (GenerateJavaStubs).Assembly.GetManifestResourceStream (resource)).ReadToEnd ()); File.WriteAllText (temp_file, template); Directory.CreateDirectory (destDir); var real_file = Path.Combine (destDir, filename); MonoAndroidHelper.CopyIfChanged (temp_file, real_file); }; StringWriter regCallsWriter = new StringWriter (); regCallsWriter.WriteLine ("\t\t// Application and Instrumentation ACWs must be registered first."); foreach (var type in java_types) { if (JniType.IsApplication (type) || JniType.IsInstrumentation (type)) { string javaKey = JniType.ToJniName (type).Replace ('/', '.'); regCallsWriter.WriteLine ("\t\tmono.android.Runtime.register (\"{0}\", {1}.class, {1}.__md_methods);", type.GetAssemblyQualifiedName (), javaKey); } } regCallsWriter.Close (); var real_app_dir = Path.GetFullPath (Path.Combine (OutputDirectory, "src", "mono", "android", "app")); string applicationTemplateFile = "ApplicationRegistration.java"; save (applicationTemplateFile, applicationTemplateFile, real_app_dir, template => template.Replace ("// REGISTER_APPLICATION_AND_INSTRUMENTATION_CLASSES_HERE", regCallsWriter.ToString ())); // Create NotifyTimeZoneChanges java sources. string notifyTimeZoneChangesFile = "NotifyTimeZoneChanges.java"; save (notifyTimeZoneChangesFile, notifyTimeZoneChangesFile, real_app_dir, template => template); // Delete our temp directory try { Directory.Delete (temp, true); } catch (Exception) { } }
private void BuildSnapshot(Engine.IBackup backup) { log.Debug("Building backup snapshot"); var manifest = new ManifestDocument(_job, _id); manifest.AddTag("date", XmlConvert.ToString(_now, XmlDateTimeSerializationMode.Utc)); manifest.AddTag("source", Environment.MachineName); manifest.AddTag("from", _job.JobRootPath); manifest.AddTag("fullBackup", XmlConvert.ToString(_forceFullBackup)); var jid = _job.JobUID.Value; if (_forceFullBackup) { _report.AppendLine("Note: Running a full backup"); _proxy.ClearAllFiles(jid); } backup.CreateShadowCopy(); var rootPath = backup.GetSnapshotPath(); var elements = backup.GetSnapshotElements(); _report.AppendLine(); _report.AppendLine(" * Backup process :"); _report.AppendLine(); var countNewFiles = 0L; var countChangeFiles = 0L; var countDeletedFiles = 0L; var hash = 0L; foreach (var element in elements) { var file = _proxy.FindFile(jid, element.Path); if (element.IsDirectory) { log.InfoFormat("[{0}] - Directory - Add entry", element.Path); var entry = _zipFile.AddDirectoryByName(element.Path); entry.CreationTime = element.Created; entry.AccessedTime = element.LastAccessed; entry.ModifiedTime = element.LastModified; if (file != null) _proxy.SetSeenFlags(jid, element.Path); else _proxy.AddFile( element.Path, jid, element.FileSize, element.Created.Ticks, element.LastModified.Ticks, 0, _id ); continue; } if (file == null) { log.InfoFormat("[{0}] - New file / Archive", element.Path); if (element.FileSize != 0) { var entryDoc = new SnapshotAccess(rootPath + element.Path); var entry = _zipFile.AddEntry(element.Path, entryDoc.OpenDelegate, entryDoc.CloseDelegate); entry.CreationTime = element.Created; entry.AccessedTime = element.LastAccessed; entry.ModifiedTime = element.LastModified; hash = entry.Crc; } else { hash = 0L; manifest.NotifyEmptyFile(element.Path); } _report.AppendLine("Backup new file " + element.Path); ++countNewFiles; _proxy.AddFile( element.Path, jid, element.FileSize, element.Created.Ticks, element.LastModified.Ticks, hash, _id ); continue; } if ( file.Modified == element.LastModified.Ticks && file.Created == element.Created.Ticks && file.FileSize == element.FileSize ) { log.DebugFormat("[{0}] - No change / No archive", element.Path); _proxy.SetSeenFlags(jid, element.Path); continue; } log.InfoFormat("[{0}] - File changed / Archiving", element.Path); _report.AppendLine("Backup modified file " + element.Path); ++countChangeFiles; if (element.FileSize != 0) { var entryDoc2 = new SnapshotAccess(rootPath + element.Path); var entry2 = _zipFile.AddEntry(element.Path, entryDoc2.OpenDelegate, entryDoc2.CloseDelegate); entry2.CreationTime = element.Created; entry2.AccessedTime = element.LastAccessed; entry2.ModifiedTime = element.LastModified; hash = entry2.Crc; } else { hash = 0L; manifest.NotifyEmptyFile(element.Path); } _proxy.UpdateFile( element.Path, jid, element.FileSize, element.Created.Ticks, element.LastModified.Ticks, hash, _id ); } using (var delFiles = _proxy.GetDeletedFiles(jid)) { while (delFiles.MoveNext()) { _report.AppendLine("Deleted file " + delFiles.Current.SourcePath); ++countDeletedFiles; manifest.NotifyDelFile(delFiles.Current.SourcePath, delFiles.Current.FileSize); } } _report.AppendLine(); _report.AppendLine(string.Format(" * Report: New files: {0} / Modified files: {1} / Deleted files: {2}", countNewFiles, countChangeFiles, countDeletedFiles)); _zipFile.Comment = manifest.Manifest; }