[Xamarin.Android.Build.Tasks] Use libZipSharp to build the .apk (#89)

Commit 4ec06ac9 *broke* generation of `.apk` files when migrating
from `Ionic.Zip.dll` to `System.IO.Compression` because this:

	apk.AddFile (assembly.ItemSpec, "assemblies", compressionLevel: CompressionLevel.NoCompression);

doesn't work the way we thought/hoped it would.

Specifically, we require that assemblies be *stored*, uncompressed,
within the `.apk`, as we **mmap**(2) the `.apk` and hand off the
memory addresses of the loaded assemblies to mono for execution.

`CompressionLevel.NoCompression`, despite saying "no compression",
does *not* mean "store". It means "add the file 'normally', but tell
`DeflateStream` to use 'no compression'."

The result is that the zip entry doesn't say it's stored:

	$ unzip -lv bin/Debug/*-Signed.apk | grep assemblies/
		 64512  Defl:N    64512  67%  06-16-16 10:38  6d65706b  assemblies/Scratch.DebugRelease.dll

Which in turn means that the resulting `.apk` is *unusable*.

The fix? `System.IO.Compression` can't be used for this, and
`Ionic.Zip.dll` had other problems (why we tried to use
`System.IO.Compression` in the first place!), so instead we'll
use [libZip][0] and [LibZipSharp][1] to handle `.apk` files.
libzip is a well-maintained OSS library for manipulating zip files,
and LibZipSharp is a C# wrapper around libzip.

Add libzip and LibZipSharp to the build system so that they're
available on required paltforms, and update the `BuildApk` and
related tasks to use LibZipSharp instead of System.IO.Compression.
This allows assemblies to be properly stored in the `.apk`,
allowing apps to execute as intended.

	$ unzip -lv bin/Debug/*-Signed.apk | grep assembl
		 64512  Stored    64512   0%  06-29-16 08:31  6d65706b  assemblies/Scratch.DebugRelease.dll

[0]: http://www.nih.at/libzip/
[1]: https://github.com/grendello/LibZipSharp/
This commit is contained in:
Dean Ellis 2016-06-29 13:33:38 +01:00 коммит произвёл Jonathan Pryor
Родитель 762deb947a
Коммит f3d62b6168
21 изменённых файлов: 189 добавлений и 181 удалений

8
.gitmodules поставляемый
Просмотреть файл

@ -17,3 +17,11 @@
path = external/opentk
url = https://github.com/mono/opentk.git
branch = master
[submodule "external/libzip"]
path = external/libzip
url = https://github.com/nih-at/libzip.git
branch = master
[submodule "external/LibZipSharp"]
path = external/LibZipSharp
url = https://github.com/grendello/LibZipSharp.git
branch = master

Просмотреть файл

@ -28,6 +28,8 @@
<JavaInteropSourceDirectory Condition=" '$(JavaInteropSourceDirectory)' == '' ">$(MSBuildThisFileDirectory)external\Java.Interop</JavaInteropSourceDirectory>
<MonoSourceDirectory>$(MSBuildThisFileDirectory)external\mono</MonoSourceDirectory>
<OpenTKSourceDirectory>$(MSBuildThisFileDirectory)external\opentk</OpenTKSourceDirectory>
<LibZipSourceDirectory Condition=" '$(LibZipSourceDirectory)' == '' ">$(MSBuildThisFileDirectory)external\libzip</LibZipSourceDirectory>
<LibZipSharpSourceDirectory Condition=" '$(LibZipSharpSourceDirectory)' == '' ">$(MSBuildThisFileDirectory)external\LibZipSharp</LibZipSharpSourceDirectory>
<SqliteSourceDirectory Condition=" '$(SqliteSourceDirectory)' == '' ">$(MSBuildThisFileDirectory)external\sqlite</SqliteSourceDirectory>
<XamarinAndroidSourcePath>$(MSBuildThisFileDirectory)</XamarinAndroidSourcePath>
<AllSupported32BitTargetAndroidAbis>armeabi;armeabi-v7a;x86</AllSupported32BitTargetAndroidAbis>
@ -40,6 +42,8 @@
<MonoSourceFullPath>$([System.IO.Path]::GetFullPath ('$(MonoSourceDirectory)'))</MonoSourceFullPath>
<SqliteSourceFullPath>$([System.IO.Path]::GetFullPath ('$(SqliteSourceDirectory)'))</SqliteSourceFullPath>
<OpenTKSourceFullPath>$([System.IO.Path]::GetFullPath ('$(OpenTKSourceDirectory)'))</OpenTKSourceFullPath>
<LibZipSourceFullPath>$([System.IO.Path]::GetFullPath ('$(LibZipSourceDirectory)'))</LibZipSourceFullPath>
<LibZipSharpSourceFullPath>$([System.IO.Path]::GetFullPath ('$(LibZipSharpSourceDirectory)'))</LibZipSharpSourceFullPath>
</PropertyGroup>
<!--
"Fixup" $(AndroidSupportedHostJitAbis) so that Condition attributes elsewhere

Просмотреть файл

@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Tools.Boots
EndProject
Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "mono-runtimes", "build-tools\mono-runtimes\mono-runtimes.mdproj", "{C03E6CF1-7460-4CDC-A4AB-292BBC0F61F2}"
EndProject
Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "libzip", "build-tools\libzip\libzip.mdproj", "{900A0F71-BAAD-417A-8D1A-8D330297CDD0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "jnienv-gen", "build-tools\jnienv-gen\jnienv-gen.csproj", "{AFB8F6D1-6EA9-42C3-950B-98F34C669AD2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "api-merge", "build-tools\api-merge\api-merge.csproj", "{3FC3E78B-F7D4-42EA-BBE8-4535DF42BFF8}"
@ -79,6 +81,8 @@ Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "sqlite-xamarin", "src\sqlit
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK", "src\OpenTK-1.0\OpenTK.csproj", "{5EB9E888-E357-417E-9F39-DDEC195CE47F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libZipSharp", "external\LibZipSharp\libZipSharp.csproj", "{E248B2CA-303B-4645-ADDC-9D4459D550FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AnyCPU = Debug|AnyCPU
@ -358,6 +362,22 @@ Global
{5EB9E888-E357-417E-9F39-DDEC195CE47F}.XAIntegrationDebug|AnyCPU.Build.0 = Debug|Any CPU
{5EB9E888-E357-417E-9F39-DDEC195CE47F}.XAIntegrationRelease|AnyCPU.ActiveCfg = Debug|Any CPU
{5EB9E888-E357-417E-9F39-DDEC195CE47F}.XAIntegrationRelease|AnyCPU.Build.0 = Debug|Any CPU
{900A0F71-BAAD-417A-8D1A-8D330297CDD0}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
{900A0F71-BAAD-417A-8D1A-8D330297CDD0}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{900A0F71-BAAD-417A-8D1A-8D330297CDD0}.Release|AnyCPU.ActiveCfg = Debug|Any CPU
{900A0F71-BAAD-417A-8D1A-8D330297CDD0}.Release|AnyCPU.Build.0 = Debug|Any CPU
{900A0F71-BAAD-417A-8D1A-8D330297CDD0}.XAIntegrationDebug|Any CPU.ActiveCfg = Debug|Any CPU
{900A0F71-BAAD-417A-8D1A-8D330297CDD0}.XAIntegrationDebug|Any CPU.Build.0 = Debug|Any CPU
{900A0F71-BAAD-417A-8D1A-8D330297CDD0}.XAIntegrationRelease|Any CPU.ActiveCfg = Debug|Any CPU
{900A0F71-BAAD-417A-8D1A-8D330297CDD0}.XAIntegrationRelease|Any CPU.Build.0 = Debug|Any CPU
{E248B2CA-303B-4645-ADDC-9D4459D550FD}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
{E248B2CA-303B-4645-ADDC-9D4459D550FD}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{E248B2CA-303B-4645-ADDC-9D4459D550FD}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{E248B2CA-303B-4645-ADDC-9D4459D550FD}.Release|AnyCPU.Build.0 = Release|Any CPU
{E248B2CA-303B-4645-ADDC-9D4459D550FD}.XAIntegrationDebug|Any CPU.ActiveCfg = Debug|Any CPU
{E248B2CA-303B-4645-ADDC-9D4459D550FD}.XAIntegrationDebug|Any CPU.Build.0 = Debug|Any CPU
{E248B2CA-303B-4645-ADDC-9D4459D550FD}.XAIntegrationRelease|Any CPU.ActiveCfg = Debug|Any CPU
{E248B2CA-303B-4645-ADDC-9D4459D550FD}.XAIntegrationRelease|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
@ -395,6 +415,8 @@ Global
{26781D3A-FF20-4F55-9824-C8A06AA9E484} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
{B8F799C5-D7CE-4E09-9CE6-BAA4173E7EC8} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
{5EB9E888-E357-417E-9F39-DDEC195CE47F} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
{900A0F71-BAAD-417A-8D1A-8D330297CDD0} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
{E248B2CA-303B-4645-ADDC-9D4459D550FD} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0

Просмотреть файл

@ -122,9 +122,9 @@
DependsOnTargets="_SetMxeToolchainMakefileTimeToLastCommitTimestamp"
Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:'))"
Inputs="..\..\external\mxe\Makefile"
Outputs="$(AndroidMxeFullPath)\bin\i686-w64-mingw32.static-gcc">
Outputs="$(AndroidMxeFullPath)\bin\i686-w64-mingw32.static-gcc;$(AndroidMxeFullPath)\bin\i686-w64-mingw32.static-cmake">
<Exec
Command="make $(MAKEFLAGS) MXE_TARGETS=&quot;i686-w64-mingw32.static&quot; gcc PREFIX=&quot;$(AndroidMxeFullPath)&quot;"
Command="make $(MAKEFLAGS) MXE_TARGETS=&quot;i686-w64-mingw32.static&quot; gcc cmake zlib PREFIX=&quot;$(AndroidMxeFullPath)&quot;"
WorkingDirectory="..\..\external\mxe"
/>
</Target>
@ -132,9 +132,9 @@
DependsOnTargets="_SetMxeToolchainMakefileTimeToLastCommitTimestamp"
Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:'))"
Inputs="..\..\external\mxe\Makefile"
Outputs="$(AndroidMxeFullPath)\bin\x86_64-w64-mingw32.static-gcc">
Outputs="$(AndroidMxeFullPath)\bin\x86_64-w64-mingw32.static-gcc;$(AndroidMxeFullPath)\bin\x86_64-w64-mingw32.static-cmake">
<Exec
Command="make $(MAKEFLAGS) MXE_TARGETS=&quot;x86_64-w64-mingw32.static&quot; gcc PREFIX=&quot;$(AndroidMxeFullPath)&quot;"
Command="make $(MAKEFLAGS) MXE_TARGETS=&quot;x86_64-w64-mingw32.static&quot; gcc cmake zlib PREFIX=&quot;$(AndroidMxeFullPath)&quot;"
WorkingDirectory="..\..\external\mxe"
/>
</Target>

Просмотреть файл

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ItemType>GenericProject</ItemType>
<ProjectGuid>{900A0F71-BAAD-417A-8D1A-8D330297CDD0}</ProjectGuid>
</PropertyGroup>
<Import Project="..\..\Configuration.props" />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\..\bin\$(Configuration)</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>..\..\bin\$(Configuration)</OutputPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<BuildDependsOn>
ResolveReferences;
_Configure;
_Make
</BuildDependsOn>
</PropertyGroup>
<Import Project="libzip.targets" />
<ItemGroup>
<ProjectReference Include="..\android-toolchain\android-toolchain.mdproj">
<Project>{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA}</Project>
<Name>android-toolchain</Name>
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<_LibZipTarget Include="host-mxe-Win64" Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:'))">
<CMake>$(AndroidMxeFullPath)\bin\x86_64-w64-mingw32.static-cmake</CMake>
<CMakeFlags></CMakeFlags>
<OutputLibrary>libzip.dll</OutputLibrary>
<OutputLibraryPath>lib/libzip.dll</OutputLibraryPath>
</_LibZipTarget>
<_LibZipTarget Include="host-Darwin" Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':Darwin:'))">
<CMake>cmake</CMake>
<CMakeFlags>-DCMAKE_OSX_ARCHITECTURES=&quot;i386;x86_64&quot;</CMakeFlags>
<OutputLibrary>libzip.3.0.dylib</OutputLibrary>
<OutputLibraryPath>lib/libzip.3.0.dylib</OutputLibraryPath>
</_LibZipTarget>
<_LibZipTarget Include="host-Linux" Condition="$(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':Linux:'))">
<CMake>cmake</CMake>
<CMakeFlags></CMakeFlags>
<OutputLibrary>libzip.so</OutputLibrary>
<OutputLibraryPath>libzip.so</OutputLibraryPath>
</_LibZipTarget>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_SourceTopDir>..\..</_SourceTopDir>
</PropertyGroup>
<UsingTask AssemblyFile="$(_SourceTopDir)\bin\Build$(Configuration)\Xamarin.Android.Tools.BootstrapTasks.dll" TaskName="Xamarin.Android.Tools.BootstrapTasks.GetNugetPackageBasePath" />
<Import Project="libzip.props" />
<Import Project="libzip.projitems" />
<Target Name="_SetCMakeListsTxtTimeToLastCommitTimestamp">
<Exec
Command="touch -m -t `git log -1 --format=%25cd --date=format-local:%25Y%25m%25d%25H%25M.%25S` CMakeLists.txt"
WorkingDirectory="$(LibZipSourceFullPath)"
/>
</Target>
<Target Name="_Configure"
DependsOnTargets="_SetCMakeListsTxtTimeToLastCommitTimestamp"
Inputs="$(LibZipSourceFullPath\CMakeLists.txt"
Outputs="$(IntermediateOutputPath)\%(_LibZipTarget.Identity)\Makefile">
<MakeDir Directories="@(_LibZipTarget->'$(IntermediateOutputPath)\%(Identity)')" />
<Exec
Command="%(_LibZipTarget.CMake) %(_LibZipTarget.CMakeFlags) $(LibZipSourceFullPath)"
WorkingDirectory="@(_LibZipTarget->'$(IntermediateOutputPath)\%(Identity)')"
/>
</Target>
<Target Name="_Make"
Inputs="$(IntermediateOutputPath)\%(_LibZipTarget.Identity)\Makefile"
Outputs="$(IntermediateOutputPath)\%(_LibZipTarget.Identity)\%(_LibZipTarget.OutputLibraryPath)">
<Exec
Command="make"
WorkingDirectory="$(IntermediateOutputPath)\%(_LibZipTarget.Identity)"
/>
<Copy SourceFiles="@(_LibZipTarget->'$(IntermediateOutputPath)\%(Identity)\%(_LibZipTarget.OutputLibraryPath)')"
DestinationFiles="@(_LibZipTarget->'$(OutputPath)\lib\xbuild\Xamarin\Android\%(_LibZipTarget.OutputLibrary)')"/>
</Target>
</Project>

1
external/LibZipSharp поставляемый Submodule

@ -0,0 +1 @@
Subproject commit 16c468310c2fefc8d8e2dfb5aff1e00cf024d5d2

1
external/libzip поставляемый Submodule

@ -0,0 +1 @@
Subproject commit 1d8b1ac4d20b8ef8d3f5d496dabebaa0ff9019ff

Просмотреть файл

@ -8,8 +8,6 @@ using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.IO.Compression;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
@ -18,6 +16,7 @@ using Java.Interop.Tools.Cecil;
using ArchiveFileList = System.Collections.Generic.List<System.Tuple<string, string>>;
using Mono.Cecil;
using Xamarin.Android.Build.Utilities;
using Xamarin.Tools.Zip;
namespace Xamarin.Android.Tasks
{
@ -111,12 +110,12 @@ namespace Xamarin.Android.Tasks
ArchiveFileList files = new ArchiveFileList ();
if (apkInputPath != null)
File.Copy (apkInputPath, apkOutputPath + "new", overwrite: true);
using (var apk = ZipFile.Open (apkOutputPath + "new", apkInputPath != null ? ZipArchiveMode.Update : ZipArchiveMode.Create)) {
using (var apk = ZipArchive.Open (apkOutputPath + "new", apkInputPath != null ? FileMode.Open : FileMode.Create )) {
apk.AddEntry ("NOTICE",
Assembly.GetExecutingAssembly ().GetManifestResourceStream ("NOTICE.txt"));
// Add classes.dx
apk.AddFiles (DalvikClasses, string.Empty);
apk.AddFiles (DalvikClasses);
if (EmbedAssemblies && !BundleAssemblies)
AddAssemblies (apk);
@ -128,7 +127,7 @@ namespace Xamarin.Android.Tasks
AddNativeLibrariesFromAssemblies (apk, supportedAbis);
foreach (ITaskItem typemap in TypeMappings) {
apk.AddFile (typemap.ItemSpec, directoryPathInZip: "", compressionLevel: CompressionLevel.NoCompression);
apk.AddFile (typemap.ItemSpec, compressionMethod: CompressionMethod.Store);
}
foreach (var file in files) {
@ -138,7 +137,7 @@ namespace Xamarin.Android.Tasks
Log.LogWarning (null, "XA4301", null, file.Item1, 0, 0, 0, 0, "Apk already contains the item {0}; ignoring.", item);
continue;
}
apk.AddFile (file.Item1, file.Item2);
apk.AddFile (file.Item1, item);
}
if (_Debug)
AddGdbservers (apk, files, supportedAbis, debugServer);
@ -156,23 +155,22 @@ namespace Xamarin.Android.Tasks
jarFilePaths = MonoAndroidHelper.DistinctFilesByContent (jarFilePaths);
foreach (var jarFile in jarFilePaths) {
using (var jar = new ZipArchive (File.Open (jarFile, FileMode.Open), ZipArchiveMode.Read)) {
foreach (var jarItem in jar.Entries.Where (ze => !ze.IsDirectory () && !ze.FullName.StartsWith ("META-INF") && !ze.FullName.EndsWith (".class") && !ze.FullName.EndsWith (".java") && !ze.FullName.EndsWith ("MANIFEST.MF"))) {
byte[] data;
using (var d = new System.IO.MemoryStream ())
using (var i = jarItem.Open ()) {
i.CopyTo (d);
using (var jar = ZipArchive.Open (File.Open (jarFile, FileMode.Open))) {
foreach (var jarItem in jar.Where (ze => !ze.IsDirectory && !ze.FullName.StartsWith ("META-INF") && !ze.FullName.EndsWith (".class") && !ze.FullName.EndsWith (".java") && !ze.FullName.EndsWith ("MANIFEST.MF"))) {
byte [] data;
using (var d = new System.IO.MemoryStream ()) {
jarItem.Extract (d);
data = d.ToArray ();
}
if (apk.Entries.Any (e => e.FullName == jarItem.FullName))
if (apk.Any (e => e.FullName == jarItem.FullName))
Log.LogMessage ("Warning: failed to add jar entry {0} from {1}: the same file already exists in the apk", jarItem.FullName, Path.GetFileName (jarFile));
else
apk.AddEntry (jarItem.FullName, data);
apk.AddEntry (data, jarItem.FullName);
}
}
}
if (StubApplicationDataFile != null && File.Exists (StubApplicationDataFile))
AddZipEntry (apk, StubApplicationDataFile, string.Empty);
apk.AddFile (StubApplicationDataFile, Path.GetFileName (StubApplicationDataFile));
}
MonoAndroidHelper.CopyIfZipChanged (apkOutputPath + "new", apkOutputPath);
File.Delete (apkOutputPath + "new");
@ -244,11 +242,6 @@ namespace Xamarin.Android.Tasks
return !Log.HasLoggedErrors;
}
void AddZipEntry (ZipArchive apk, string file, string path)
{
apk.AddFile (file, path);
}
private void AddAssemblies (ZipArchive apk)
{
bool debug = _Debug;
@ -256,7 +249,7 @@ namespace Xamarin.Android.Tasks
foreach (ITaskItem assembly in ResolvedUserAssemblies) {
// Add assembly
apk.AddFile (assembly.ItemSpec, GetTargetDirectory (assembly.ItemSpec), compressionLevel: CompressionLevel.NoCompression);
apk.AddFile (assembly.ItemSpec, GetTargetDirectory (assembly.ItemSpec), compressionMethod: CompressionMethod.Store);
// Try to add config if exists
var config = Path.ChangeExtension (assembly.ItemSpec, "dll.config");
@ -267,7 +260,7 @@ namespace Xamarin.Android.Tasks
var symbols = Path.ChangeExtension (assembly.ItemSpec, "dll.mdb");
if (File.Exists (symbols))
apk.AddFile (symbols, "assemblies", compressionLevel: CompressionLevel.NoCompression);
apk.AddFile (symbols, "assemblies", compressionMethod: CompressionMethod.Store);
}
}
@ -276,7 +269,7 @@ namespace Xamarin.Android.Tasks
// Add framework assemblies
foreach (ITaskItem assembly in ResolvedFrameworkAssemblies) {
apk.AddFile (assembly.ItemSpec, "assemblies", compressionLevel: CompressionLevel.NoCompression);
apk.AddFile (assembly.ItemSpec, "assemblies", compressionMethod: CompressionMethod.Store);
var config = Path.ChangeExtension (assembly.ItemSpec, "dll.config");
AddAssemblyConfigEntry (apk, config);
// Try to add symbols if Debug
@ -284,7 +277,7 @@ namespace Xamarin.Android.Tasks
var symbols = Path.ChangeExtension (assembly.ItemSpec, "dll.mdb");
if (File.Exists (symbols))
apk.AddFile (symbols, "assemblies", compressionLevel: CompressionLevel.NoCompression);
apk.AddFile (symbols, "assemblies", compressionMethod: CompressionMethod.Store);
}
}
}
@ -299,7 +292,7 @@ namespace Xamarin.Android.Tasks
source.CopyTo (dest);
dest.WriteByte (0);
dest.Position = 0;
apk.AddEntry ("assemblies/" + Path.GetFileName (configFile), dest, compressionLevel: CompressionLevel.NoCompression);
apk.AddEntry ("assemblies/" + Path.GetFileName (configFile), dest, compressionMethod: CompressionMethod.Store);
}
}
@ -462,18 +455,19 @@ namespace Xamarin.Android.Tasks
continue;
var data = ressozip.GetResourceData ();
using (var ms = new MemoryStream (data)) {
using (var zip = new ZipArchive (ms, ZipArchiveMode.Read)) {
foreach (var e in zip.Entries.Where (x => abis.Any (a => x.FullName.Contains (a)))) {
if (e.IsDirectory ())
using (var zip = ZipArchive.Open (ms)) {
foreach (var e in zip.Where (x => abis.Any (a => x.FullName.Contains (a)))) {
if (e.IsDirectory)
continue;
var key = e.FullName.Replace ("native_library_imports", "lib");
if (apk.ContainsEntry (key)) {
if (apk.Any(k => k.FullName == key)) {
Log.LogCodedWarning ("4301", "Apk already contains the item {0}; ignoring.", key);
continue;
}
using (var s = new MemoryStream ()) {
e.Extract (s);
apk.AddEntry (key, s.ToArray ());
s.Position = 0;
apk.AddEntry (s.ToArray (),key);
}
}
}

Просмотреть файл

@ -8,7 +8,7 @@ using System.Xml.Linq;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.Text.RegularExpressions;
using System.IO.Compression;
using Xamarin.Tools.Zip;
using Xamarin.Android.Tools;
@ -79,7 +79,8 @@ namespace Xamarin.Android.Tasks
string tmpname = Path.Combine (Path.GetTempPath (), "monodroid_import_" + Guid.NewGuid ().ToString ());
try {
Directory.CreateDirectory (tmpname);
ZipFile.ExtractToDirectory (p, tmpname, new System.Text.UTF8Encoding (false));
var archive = ZipArchive.Open (p, FileMode.Open);
archive.ExtractAll (tmpname);
if (!CopyLibraryContent (tmpname, p.EndsWith (".aar", StringComparison.OrdinalIgnoreCase)))
return false;
@ -91,7 +92,7 @@ namespace Xamarin.Android.Tasks
// Archive them in a zip.
using (var stream = new MemoryStream ()) {
using (var zip = new ZipArchive (stream, ZipArchiveMode.Create, true, new System.Text.UTF8Encoding (false))) {
using (var zip = ZipArchive.Create (stream)) {
zip.AddDirectory (OutputDirectory, outDirInfo.Name);
}
stream.Position = 0;

Просмотреть файл

@ -8,7 +8,7 @@ using System.Xml.Linq;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.Text.RegularExpressions;
using System.IO.Compression;
using Xamarin.Tools.Zip;
using Xamarin.Android.Tools;
@ -106,7 +106,8 @@ namespace Xamarin.Android.Tasks
// Archive them in a zip.
using (var stream = new MemoryStream ()) {
using (var zip = new ZipArchive (stream, ZipArchiveMode.Create, true, new System.Text.UTF8Encoding (false))) {
using (var zip = ZipArchive.Create (stream)) {
Log.LogDebugMessage ($" {OutputDirectory} {outDirInfo.Name} ");
zip.AddDirectory (OutputDirectory, outDirInfo.Name);
}
stream.Position = 0;

Просмотреть файл

@ -8,7 +8,7 @@ using System.Xml.Linq;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.Text.RegularExpressions;
using System.IO.Compression;
using Xamarin.Tools.Zip;
using Xamarin.Android.Tools;
@ -64,7 +64,7 @@ namespace Xamarin.Android.Tasks
// Archive native libraries in a zip.
using (var stream = new MemoryStream ()) {
using (var zip = new ZipArchive (stream, ZipArchiveMode.Create, true, new System.Text.UTF8Encoding (false))) {
using (var zip = ZipArchive.Create (stream)) {
zip.AddDirectory (OutputDirectory, outDirInfo.Name);
}
stream.Position = 0;

Просмотреть файл

@ -162,7 +162,7 @@ namespace Xamarin.Android.Tasks {
LogMessage ("Extracting {0} to {1}", file, contentDir);
using (var zip = MonoAndroidHelper.ReadZipFile (file)) {
int extracted = 0;
var o = Math.Max(1, (zip.Entries.Count / 10));
var o = Math.Max(1, (zip.EntryCount / 10));
Files.ExtractAll (zip, contentDir, (progress, total) => {
if ((progress % o) != 0 || extracted == progress || progress == 0)
return;

Просмотреть файл

@ -13,6 +13,7 @@ using Microsoft.Build.Framework;
using System.Text.RegularExpressions;
using Xamarin.Android.Build.Utilities;
using System.IO.Compression;
using Xamarin.Tools.Zip;
namespace Xamarin.Android.Tasks
{
@ -123,7 +124,7 @@ namespace Xamarin.Android.Tasks
if (File.Exists (ProguardJarInput))
File.Delete (ProguardJarInput);
using (var zip = ZipFile.Open (ProguardJarInput, ZipArchiveMode.Create, new System.Text.UTF8Encoding (false))) {
using (var zip = ZipArchive.Open (ProguardJarInput, FileMode.Create)) {
foreach (var file in Directory.GetFiles (classesFullPath, "*", SearchOption.AllDirectories))
zip.AddFile (file, Path.GetDirectoryName (file.Substring (classesFullPath.Length)));
}

Просмотреть файл

@ -2,7 +2,7 @@ using System;
using System.IO;
using System.Security.Cryptography;
using System.IO.Compression;
using Xamarin.Tools.Zip;
#if MSBUILD
using Microsoft.Build.Utilities;
using Xamarin.Android.Tasks;
@ -157,9 +157,9 @@ namespace Xamarin.Android.Tools {
string hashes = String.Empty;
try {
using (var zip = new ZipArchive (stream, ZipArchiveMode.Read)) {
foreach (var item in zip.Entries) {
hashes += String.Format ("{0}{1}", item.FullName, item.Hash());
using (var zip = ZipArchive.Open (stream)) {
foreach (var item in zip) {
hashes += String.Format ("{0}{1}", item.FullName, item.CRC);
}
}
} catch {
@ -178,8 +178,8 @@ namespace Xamarin.Android.Tools {
return File.ReadAllText (filename + ".hash");
using (var zip = ReadZipFile (filename)) {
foreach (var item in zip.Entries) {
hashes += String.Format ("{0}{1}", item.FullName, item.Hash());
foreach (var item in zip) {
hashes += String.Format ("{0}{1}", item.FullName, item.CRC);
}
}
} catch {
@ -190,26 +190,26 @@ namespace Xamarin.Android.Tools {
public static ZipArchive ReadZipFile (string filename)
{
return ZipFile.Open (filename, ZipArchiveMode.Read, new System.Text.UTF8Encoding (false));
return ZipArchive.Open (filename, FileMode.Open);
}
public static void ExtractAll(ZipArchive zip, string destination, Action<int, int> progressCallback = null)
{
int i = 0;
int total = zip.Entries.Count;
foreach (var entry in zip.Entries) {
int total = (int)zip.EntryCount;
foreach (var entry in zip) {
if (entry.FullName.Contains ("/__MACOSX/") ||
entry.FullName.EndsWith ("/__MACOSX", StringComparison.OrdinalIgnoreCase) ||
entry.FullName.EndsWith ("/.DS_Store", StringComparison.OrdinalIgnoreCase))
continue;
if (entry.IsDirectory ()) {
if (entry.IsDirectory) {
Directory.CreateDirectory (Path.Combine (destination, entry.FullName));
continue;
}
if (progressCallback != null)
progressCallback (i++, total);
Directory.CreateDirectory (Path.Combine (destination, Path.GetDirectoryName (entry.FullName)));
entry.ExtractToFile (Path.Combine (destination, entry.FullName), overwrite: true);
entry.Extract (destination, entry.FullName);
}
}

Просмотреть файл

@ -7,8 +7,7 @@ using System.IO;
using System.Security.Cryptography;
using Mono.Security.Cryptography;
using Xamarin.Android.Build.Utilities;
using System.IO.Compression;
using Xamarin.Tools.Zip;
#if MSBUILD
using Microsoft.Build.Framework;

Просмотреть файл

@ -1,116 +0,0 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Security.Cryptography;
namespace Xamarin.Android.Tasks
{
static class ZipArchiveExtensions
{
public static void AddEntry (this ZipArchive archive, string entryName, Stream data,
CompressionLevel compressionLevel = CompressionLevel.Optimal )
{
ZipArchiveEntry entry = archive.CreateEntry(entryName, compressionLevel: compressionLevel);
using (StreamWriter writer = new StreamWriter(entry.Open()))
{
data.CopyTo (writer.BaseStream);
writer.Flush ();
}
}
public static void AddEntry (this ZipArchive archive, string entryName, byte[] data,
CompressionLevel compressionLevel = CompressionLevel.Optimal)
{
ZipArchiveEntry entry = archive.CreateEntry (entryName, compressionLevel: compressionLevel);
using (StreamWriter writer = new StreamWriter (entry.Open ())) {
writer.BaseStream.Write (data, 0, data.Length);
writer.Flush ();
}
}
public static void AddEntry (this ZipArchive archive, string entryName, string s, Encoding encoding,
CompressionLevel compressionLevel = CompressionLevel.Optimal)
{
ZipArchiveEntry entry = archive.CreateEntry (entryName, compressionLevel: compressionLevel);
using (StreamWriter writer = new StreamWriter (entry.Open ())) {
var data = encoding.GetBytes (s);
writer.BaseStream.Write (data, 0, data.Length);
writer.Flush ();
}
}
internal static string ArchiveNameForFile (string filename, string directoryPathInZip)
{
string pathName;
if (string.IsNullOrEmpty (directoryPathInZip)) {
pathName = Path.GetFileName (filename);
}
else {
pathName = Path.Combine (directoryPathInZip, Path.GetFileName (filename));
}
return pathName.Replace ("\\", "/");
}
public static ZipArchiveEntry AddFile (this ZipArchive archive, string fileName, string directoryPathInZip = null, CompressionLevel compressionLevel = CompressionLevel.Optimal )
{
ZipArchiveEntry entry = archive.CreateEntry(ArchiveNameForFile(fileName, directoryPathInZip), compressionLevel: compressionLevel);
using (StreamWriter writer = new StreamWriter(entry.Open()))
{
var data = File.ReadAllBytes (fileName);
writer.BaseStream.Write (data, 0, data.Length);
}
return entry;
}
public static void AddFiles (this ZipArchive archive, IEnumerable<string> fileNames, string directoryPathInZip)
{
foreach (var file in fileNames) {
AddFile (archive, file, directoryPathInZip);
}
}
public static bool ContainsEntry (this ZipArchive archive, string entryName)
{
return archive.Entries.Any (x => string.Compare (x.FullName, entryName, StringComparison.OrdinalIgnoreCase) == 0);
}
public static bool IsDirectory (this ZipArchiveEntry entry)
{
return entry.FullName.EndsWith ("/", StringComparison.OrdinalIgnoreCase);
}
public static void Extract (this ZipArchiveEntry entry, Stream stream)
{
entry.Open ().CopyTo (stream);
}
public static void Extract (this ZipArchiveEntry entry, string destination)
{
entry.ExtractToFile (destination, overwrite: true);
}
public static void AddDirectory (this ZipArchive archive, string folder, string folderInArchive)
{
string root = folderInArchive;
foreach(var fileName in Directory.GetFiles (folder)) {
archive.AddFile (fileName, root);
}
foreach (var dir in Directory.GetDirectories (folder)) {
var internalDir = dir.Replace ("./", string.Empty).Replace (folder, string.Empty);
archive.AddDirectory (dir, folderInArchive + internalDir);
}
}
public static string Hash (this ZipArchiveEntry entry)
{
using (var stream = entry.Open ())
using (var sha1 = SHA1.Create ()) {
return Convert.ToBase64String (sha1.ComputeHash (stream));
}
}
}
}

Просмотреть файл

@ -34,15 +34,13 @@
</PropertyGroup>
<PropertyGroup>
<DefineConstants Condition="'$(__XA_NO_PREVIEW_L_SUPPORT__)' != ''">$(DefineConstants);XA_NO_PREVIEW_L_SUPPORT</DefineConstants>
<AndroidGeneratedClassDirectory Condition=" '$(AndroidGeneratedClassDirectory)' == '' " >..\..\src\Mono.Android\obj\$(Configuration)\android-$(AndroidApiLevel)</AndroidGeneratedClassDirectory>
<AndroidGeneratedClassDirectory Condition=" '$(AndroidGeneratedClassDirectory)' == '' ">..\..\src\Mono.Android\obj\$(Configuration)\android-$(AndroidApiLevel)</AndroidGeneratedClassDirectory>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Build.Framework" />
<Reference Include="Microsoft.Build.Utilities.v4.0" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
<Reference Include="Mono.Cecil">
@ -63,8 +61,6 @@
<Reference Include="FSharp.Compiler.CodeDom">
<HintPath>..\..\packages\FSharp.Compiler.CodeDom.1.0.0.1\lib\net40\FSharp.Compiler.CodeDom.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.IO.Compression" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)Profile.g.cs" />
@ -117,7 +113,6 @@
<Compile Include="Utilities\JavaResourceParser.cs" />
<Compile Include="Utilities\ManifestDocumentElement.cs" />
<Compile Include="Utilities\ManifestDocument.cs" />
<Compile Include="Utilities\ZipArchiveExtensions.cs" />
<Compile Include="Mono.Android\MetaDataAttribute.Partial.cs" />
<Compile Include="Utilities\MonoAndroidHelper.cs" />
<None Include="Linker\MonoDroid.Tuner\PreserveCode.cs" />
@ -640,6 +635,10 @@
<Name>class-parse</Name>
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(LibZipSharpSourceFullPath)\libZipSharp.csproj">
<Project>{E248B2CA-303B-4645-ADDC-9D4459D550FD}</Project>
<Name>libZipSharp</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="pdb2mdb\" />

Просмотреть файл

@ -31,8 +31,6 @@
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
@ -58,4 +56,4 @@
<ItemGroup>
<Folder Include="Sdks\" />
</ItemGroup>
</Project>
</Project>