Example #1
0
 public override bool RunTask()
 {
     if (!string.IsNullOrEmpty(SupportedAbis))
     {
         Log.LogCodedWarning("XA0036", Properties.Resources.XA0036);
     }
     if (RuntimeIdentifiers != null && RuntimeIdentifiers.Length > 0)
     {
         SupportedAbis = string.Join(";", RuntimeIdentifiers.Select(rid => {
             var abi = AndroidRidAbiHelper.RuntimeIdentifierToAbi(rid);
             if (string.IsNullOrEmpty(abi))
             {
                 Log.LogCodedError("XA0035", Properties.Resources.XA0035, rid);
             }
             return(abi);
         }));
     }
     else if (!string.IsNullOrEmpty(RuntimeIdentifier))
     {
         SupportedAbis = AndroidRidAbiHelper.RuntimeIdentifierToAbi(RuntimeIdentifier);
         if (string.IsNullOrEmpty(SupportedAbis))
         {
             Log.LogCodedError("XA0035", Properties.Resources.XA0035, RuntimeIdentifier);
         }
     }
     else if (string.IsNullOrEmpty(SupportedAbis))
     {
         Log.LogCodedError("XA0035", Properties.Resources.XA0035, "");
     }
     return(!Log.HasLoggedErrors);
 }
Example #2
0
		private void AddAdditionalNativeLibraries (ArchiveFileList files, string [] supportedAbis)
		{
			if (AdditionalNativeLibraryReferences == null || !AdditionalNativeLibraryReferences.Any ())
				return;

			var libs = AdditionalNativeLibraryReferences
				.Select (l => new LibInfo { Path = l.ItemSpec, Abi = AndroidRidAbiHelper.GetNativeLibraryAbi (l) });

			AddNativeLibraries (files, supportedAbis, libs);
		}
Example #3
0
        public override bool RunTask()
        {
            if (InputLibraries == null || InputLibraries.Length == 0)
            {
                return(true);
            }

            var output = new List <ITaskItem> (InputLibraries.Length);

            foreach (var library in InputLibraries)
            {
                var abi = AndroidRidAbiHelper.GetNativeLibraryAbi(library);
                if (string.IsNullOrEmpty(abi))
                {
                    var packageId = library.GetMetadata("NuGetPackageId");
                    if (!string.IsNullOrEmpty(packageId))
                    {
                        Log.LogCodedWarning("XA4301", library.ItemSpec, 0, Properties.Resources.XA4301_ABI_NuGet, library.ItemSpec, packageId);
                    }
                    else
                    {
                        Log.LogCodedWarning("XA4301", library.ItemSpec, 0, Properties.Resources.XA4301_ABI, library.ItemSpec);
                    }
                    continue;
                }
                // Both libmono-android.debug.so and libmono-android.release.so are in InputLibraries.
                // Use IncludeDebugSymbols to determine which one to include.
                // We may eventually have files such as `libmono-android-checked+asan.release.so` as well.
                var fileName = Path.GetFileNameWithoutExtension(library.ItemSpec);
                if (fileName.StartsWith("libmono-android", StringComparison.Ordinal))
                {
                    if (fileName.EndsWith(".debug", StringComparison.Ordinal))
                    {
                        if (!IncludeDebugSymbols)
                        {
                            continue;
                        }
                        library.SetMetadata("ArchiveFileName", "libmonodroid.so");
                    }
                    else if (fileName.EndsWith(".release", StringComparison.Ordinal))
                    {
                        if (IncludeDebugSymbols)
                        {
                            continue;
                        }
                        library.SetMetadata("ArchiveFileName", "libmonodroid.so");
                    }
                }
                output.Add(library);
            }

            OutputLibraries = output.ToArray();

            return(!Log.HasLoggedErrors);
        }
Example #4
0
		string GetNativeLibraryAbi (ITaskItem lib)
		{
			// If Abi is explicitly specified, simply return it.
			var lib_abi = AndroidRidAbiHelper.GetNativeLibraryAbi (lib);

			if (string.IsNullOrWhiteSpace (lib_abi)) {
				Log.LogCodedError ("XA4301", lib.ItemSpec, 0, Properties.Resources.XA4301_ABI, lib.ItemSpec);
				return null;
			}

			return lib_abi;
		}
        public override bool RunTask()
        {
            var outDirInfo = new DirectoryInfo(OutputDirectory);

            // Copy files into _NativeLibraryImportsDirectoryName (native_library_imports) dir.
            if (!outDirInfo.Exists)
            {
                outDirInfo.Create();
            }
            foreach (var lib in EmbeddedNativeLibraries)
            {
                // seealso bug #3477 to find out why we use this method.
                var abi = AndroidRidAbiHelper.GetNativeLibraryAbi(lib);
                if (abi == null)
                {
                    Log.LogWarning(
                        subcategory:      string.Empty,
                        warningCode:      "XA4300",
                        helpKeyword:      string.Empty,
                        file:             lib.ItemSpec,
                        lineNumber:       0,
                        columnNumber:     0,
                        endLineNumber:    0,
                        endColumnNumber:  0,
                        message:          Properties.Resources.XA4300,
                        messageArgs:      new [] {
                        lib.ItemSpec,
                    }
                        );
                    continue;
                }
                if (!outDirInfo.GetDirectories(abi).Any())
                {
                    outDirInfo.CreateSubdirectory(abi);
                }
                Files.CopyIfChanged(lib.ItemSpec, Path.Combine(OutputDirectory, abi, Path.GetFileName(lib.ItemSpec)));
            }

            var outpath = Path.Combine(outDirInfo.Parent.FullName, "__AndroidNativeLibraries__.zip");

            if (Files.ArchiveZip(outpath, f => {
                using (var zip = new ZipArchiveEx(f)) {
                    zip.AddDirectory(OutputDirectory, "native_library_imports");
                }
            }))
            {
                Log.LogDebugMessage("Saving contents to " + outpath);
            }

            return(!Log.HasLoggedErrors);
        }
        public override bool RunTask()
        {
            if (SourceFiles.Length != DestinationFiles.Length)
            {
                throw new ArgumentException("source and destination count mismatch");
            }
            if (SourceFiles == null || SourceFiles.Length == 0)
            {
                return(true);
            }

            for (int i = 0; i < SourceFiles.Length; i++)
            {
                source      = SourceFiles [i];
                destination = DestinationFiles [i];

                var abi = AndroidRidAbiHelper.GetNativeLibraryAbi(source);
                if (string.IsNullOrEmpty(abi))
                {
                    var packageId = source.GetMetadata("NuGetPackageId");
                    if (!string.IsNullOrEmpty(packageId))
                    {
                        Log.LogCodedWarning("XA4301", source.ItemSpec, 0, Properties.Resources.XA4301_ABI_NuGet, source.ItemSpec, packageId);
                    }
                    else
                    {
                        Log.LogCodedWarning("XA4301", source.ItemSpec, 0, Properties.Resources.XA4301_ABI, source.ItemSpec);
                    }
                    continue;
                }

                triple = GetNdkTripleFromAbi(abi);
                Directory.CreateDirectory(Path.GetDirectoryName(destination.ItemSpec));

                // This runs the tool
                base.RunTask();

                // Stop early on failure
                if (Log.HasLoggedErrors)
                {
                    return(false);
                }
            }

            return(!Log.HasLoggedErrors);
        }
        /// <summary>
        /// Sets %(DestinationSubDirectory) and %(DestinationSubPath) based on %(RuntimeIdentifier)
        /// </summary>
        void SetDestinationSubDirectory(ITaskItem assembly, string fileName, ITaskItem symbol)
        {
            var rid = assembly.GetMetadata("RuntimeIdentifier");
            var abi = AndroidRidAbiHelper.RuntimeIdentifierToAbi(rid);

            if (!string.IsNullOrEmpty(abi))
            {
                string destination = Path.Combine(assembly.GetMetadata("DestinationSubDirectory"), abi);
                assembly.SetMetadata("DestinationSubDirectory", destination + Path.DirectorySeparatorChar);
                assembly.SetMetadata("DestinationSubPath", Path.Combine(destination, fileName));
                if (symbol != null)
                {
                    destination = Path.Combine(symbol.GetMetadata("DestinationSubDirectory"), abi);
                    symbol.SetMetadata("DestinationSubDirectory", destination + Path.DirectorySeparatorChar);
                    symbol.SetMetadata("DestinationSubPath", Path.Combine(destination, Path.GetFileName(symbol.ItemSpec)));
                }
            }
            else
            {
                Log.LogDebugMessage($"Android ABI not found for: {assembly.ItemSpec}");
                assembly.SetDestinationSubPath();
                symbol?.SetDestinationSubPath();
            }
        }
Example #8
0
        public override bool RunTask()
        {
            if (!Directory.Exists(TargetDirectory))
            {
                Log.LogDebugMessage("Target directory was not found");
                return(true);
            }

            var manifestDocuments = new List <ITaskItem> ();
            var nativeLibraries   = new List <ITaskItem> ();
            var jarFiles          = new List <ITaskItem> ();

            foreach (var file in Directory.EnumerateFiles(TargetDirectory, "*", SearchOption.AllDirectories))
            {
                if (file.EndsWith(".so", StringComparison.OrdinalIgnoreCase))
                {
                    if (AndroidRidAbiHelper.GetNativeLibraryAbi(file) != null)
                    {
                        nativeLibraries.Add(new TaskItem(file));
                    }
                }
                else if (file.EndsWith(".jar", StringComparison.OrdinalIgnoreCase))
                {
                    jarFiles.Add(new TaskItem(file));
                }
                else if (file.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
                {
                    if (Path.GetFileName(file) == "AndroidManifest.xml")
                    {
                        // there could be ./AndroidManifest.xml and bin/AndroidManifest.xml, which will be the same. So, ignore "bin" ones.
                        var directory = Path.GetFileName(Path.GetDirectoryName(file));
                        if (IgnoredManifestDirectories.Contains(directory))
                        {
                            continue;
                        }
                        manifestDocuments.Add(new TaskItem(file));
                    }
                }
            }

            ManifestDocuments = manifestDocuments.ToArray();
            NativeLibraries   = nativeLibraries.ToArray();
            Jars = jarFiles.ToArray();

            if (!string.IsNullOrEmpty(CacheFile))
            {
                var document = new XDocument(
                    new XDeclaration("1.0", "UTF-8", null),
                    new XElement("Paths",
                                 new XElement("ManifestDocuments", ManifestDocuments.Select(e => new XElement("ManifestDocument", e.ItemSpec))),
                                 new XElement("NativeLibraries", NativeLibraries.Select(e => new XElement("NativeLibrary", e.ItemSpec))),
                                 new XElement("Jars", Jars.Select(e => new XElement("Jar", e.ItemSpec)))
                                 ));
                document.SaveIfChanged(CacheFile);
            }

            Log.LogDebugTaskItems("  NativeLibraries: ", NativeLibraries);
            Log.LogDebugTaskItems("  Jars: ", Jars);
            Log.LogDebugTaskItems("  ManifestDocuments: ", ManifestDocuments);

            return(true);
        }
Example #9
0
        public override bool RunTask()
        {
            Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));

            using (var stream = File.Create(OutputFile))
                using (var aar = ZipArchive.Open(stream)) {
                    var existingEntries = new HashSet <string> (StringComparer.Ordinal);
                    foreach (var entry in aar)
                    {
                        Log.LogDebugMessage("Existing entry: " + entry.FullName);
                        existingEntries.Add(entry.FullName);
                    }
                    if (AndroidAssets != null)
                    {
                        foreach (var asset in AndroidAssets)
                        {
                            // See: https://github.com/xamarin/xamarin-android/commit/665cb59205f8ac565b6acbda740624844bc1cbd9
                            if (Directory.Exists(asset.ItemSpec))
                            {
                                Log.LogDebugMessage($"Skipping item, is a directory: {asset.ItemSpec}");
                                continue;
                            }
                            var relative    = MonoAndroidHelper.GetRelativePathForAndroidAsset(AssetDirectory, asset);
                            var archivePath = "assets/" + relative.Replace('\\', '/');
                            aar.AddStream(File.OpenRead(asset.ItemSpec), archivePath);
                            existingEntries.Remove(archivePath);
                        }
                    }
                    if (AndroidResources != null)
                    {
                        var nameCaseMap = new StringBuilder();
                        foreach (var resource in AndroidResources)
                        {
                            // See: https://github.com/xamarin/xamarin-android/commit/665cb59205f8ac565b6acbda740624844bc1cbd9
                            if (Directory.Exists(resource.ItemSpec))
                            {
                                Log.LogDebugMessage($"Skipping item, is a directory: {resource.ItemSpec}");
                                continue;
                            }
                            var directory    = Path.GetDirectoryName(resource.ItemSpec);
                            var resourcePath = Path.GetFileName(directory) + "/" + Path.GetFileName(resource.ItemSpec);
                            var archivePath  = "res/" + resourcePath;
                            aar.AddStream(File.OpenRead(resource.ItemSpec), archivePath);
                            existingEntries.Remove(archivePath);

                            nameCaseMap.Append(resource.GetMetadata("LogicalName").Replace('\\', '/'));
                            nameCaseMap.Append(';');
                            nameCaseMap.AppendLine(resourcePath);
                        }
                        if (nameCaseMap.Length > 0)
                        {
                            var archivePath = ".net/__res_name_case_map.txt";
                            aar.AddEntry(archivePath, nameCaseMap.ToString(), Files.UTF8withoutBOM);
                            existingEntries.Remove(archivePath);
                        }
                    }
                    if (AndroidEnvironment != null)
                    {
                        foreach (var env in AndroidEnvironment)
                        {
                            var archivePath = $".net/env/{GetHashedFileName (env)}.env";
                            aar.AddStream(File.OpenRead(env.ItemSpec), archivePath);
                            existingEntries.Remove(archivePath);
                        }
                    }
                    if (JarFiles != null)
                    {
                        foreach (var jar in JarFiles)
                        {
                            var archivePath = $"libs/{GetHashedFileName (jar)}.jar";
                            aar.AddStream(File.OpenRead(jar.ItemSpec), archivePath);
                            existingEntries.Remove(archivePath);
                        }
                    }
                    if (NativeLibraries != null)
                    {
                        foreach (var lib in NativeLibraries)
                        {
                            var abi = AndroidRidAbiHelper.GetNativeLibraryAbi(lib);
                            if (string.IsNullOrWhiteSpace(abi))
                            {
                                Log.LogCodedError("XA4301", lib.ItemSpec, 0, Properties.Resources.XA4301_ABI, lib.ItemSpec);
                                continue;
                            }
                            var archivePath = "jni/" + abi + "/" + Path.GetFileName(lib.ItemSpec);
                            aar.AddStream(File.OpenRead(lib.ItemSpec), archivePath);
                            existingEntries.Remove(archivePath);
                        }
                    }
                    foreach (var entry in existingEntries)
                    {
                        Log.LogDebugMessage($"Removing {entry} as it is not longer required.");
                        aar.DeleteEntry(entry);
                    }
                }

            // Delete the archive on failure
            if (Log.HasLoggedErrors && File.Exists(OutputFile))
            {
                File.Delete(OutputFile);
            }

            return(!Log.HasLoggedErrors);
        }