예제 #1
0
        public override bool RunTask()
        {
            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.GetRegisteredTaskObjectAssemblyLocal <DeleteFileAfterBuild> (key, RegisteredTaskObjectLifetime.Build);
                if (existing == null)
                {
                    if (File.Exists(path))
                    {
                        Log.LogCodedWarning("XA5302", Properties.Resources.XA5302, path);
                    }
                    else
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(path));
                        File.WriteAllText(path, "");
                    }

                    BuildEngine4.RegisterTaskObjectAssemblyLocal(key, new DeleteFileAfterBuild(path), RegisteredTaskObjectLifetime.Build);
                }
                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);
        }
예제 #2
0
        void WriteTypeMappings(List <TypeDefinition> types, TypeDefinitionCache cache)
        {
            var tmg = new TypeMapGenerator((string message) => Log.LogDebugMessage(message), SupportedAbis);

            if (!tmg.Generate(Debug, SkipJniAddNativeMethodRegistrationAttributeScan, types, cache, TypemapOutputDirectory, GenerateNativeAssembly, out ApplicationConfigTaskState appConfState))
            {
                throw new XamarinAndroidException(4308, Properties.Resources.XA4308);
            }
            GeneratedBinaryTypeMaps = tmg.GeneratedBinaryTypeMaps.ToArray();
            BuildEngine4.RegisterTaskObjectAssemblyLocal(ApplicationConfigTaskState.RegisterTaskObjectKey, appConfState, RegisteredTaskObjectLifetime.Build);
        }
        string FindMono()
        {
            string mono = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal <string> (MonoKey, Lifetime);

            if (!string.IsNullOrEmpty(mono))
            {
                Log.LogDebugMessage($"Found cached mono via {nameof (BuildEngine4.RegisterTaskObject)}");
                return(mono);
            }

            var env = Environment.GetEnvironmentVariable("PATH");

            if (string.IsNullOrEmpty(env))
            {
                foreach (var path in env.Split(Path.PathSeparator))
                {
                    if (File.Exists(mono = Path.Combine(path, "mono")))
                    {
                        Log.LogDebugMessage("Found mono in $PATH");
                        BuildEngine4.RegisterTaskObjectAssemblyLocal(MonoKey, mono, Lifetime);
                        return(mono);
                    }
                }
            }

            foreach (var path in KnownMonoPaths)
            {
                if (File.Exists(mono = path))
                {
                    Log.LogDebugMessage($"Found mono in {nameof (KnownMonoPaths)}");
                    BuildEngine4.RegisterTaskObjectAssemblyLocal(MonoKey, mono, Lifetime);
                    return(mono);
                }
            }

            // Last resort
            BuildEngine4.RegisterTaskObjectAssemblyLocal(MonoKey, mono = "mono", Lifetime);
            return(mono);
        }
예제 #4
0
        public override bool RunTask()
        {
            if (InputAssemblies == null)
            {
                return(true);
            }

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

            foreach (var assemblyItem in InputAssemblies)
            {
                // Skip .NET 6.0 <FrameworkReference/> assemblies
                var frameworkReferenceName = assemblyItem.GetMetadata("FrameworkReferenceName") ?? "";
                if (frameworkReferenceName == "Microsoft.Android")
                {
                    continue;                     // No need to process Mono.Android.dll or Java.Interop.dll
                }
                if (frameworkReferenceName.StartsWith("Microsoft.NETCore.", StringComparison.OrdinalIgnoreCase))
                {
                    continue;                     // No need to process BCL assemblies
                }
                if (!File.Exists(assemblyItem.ItemSpec))
                {
                    Log.LogDebugMessage($"Skipping non-existent dependency '{assemblyItem.ItemSpec}'.");
                    continue;
                }
                if (string.Equals(assemblyItem.GetMetadata("TargetPlatformIdentifier"), "android", StringComparison.OrdinalIgnoreCase))
                {
                    output.Add(assemblyItem);
                    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.GetRegisteredTaskObjectAssemblyLocal(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();
                    if (IsAndroidAssembly(assemblyDefinition, reader))
                    {
                        output.Add(assemblyItem);
                        BuildEngine4.RegisterTaskObjectAssemblyLocal(key, value: true, Lifetime);
                        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.RegisterTaskObjectAssemblyLocal(key, value: true, Lifetime);
                        continue;
                    }
                    // Fallback to looking for *.jar or __Android EmbeddedResource files
                    if (HasEmbeddedResource(reader))
                    {
                        Log.LogDebugMessage($"EmbeddedResource found: {assemblyItem.ItemSpec}");
                        output.Add(assemblyItem);
                        BuildEngine4.RegisterTaskObjectAssemblyLocal(key, value: true, Lifetime);
                        continue;
                    }
                    // Not a MonoAndroid assembly, store false
                    BuildEngine4.RegisterTaskObjectAssemblyLocal(key, value: false, Lifetime);
                }
            }
            OutputAssemblies = output.ToArray();

            return(!Log.HasLoggedErrors);
        }
        void GenerateCompressedAssemblySources()
        {
            if (Debug || !EnableCompression)
            {
                Generate(null);
                return;
            }

            var assemblies = new SortedDictionary <string, CompressedAssemblyInfo> (StringComparer.Ordinal);

            foreach (ITaskItem assembly in ResolvedAssemblies)
            {
                if (bool.TryParse(assembly.GetMetadata("AndroidSkipAddToPackage"), out bool value) && value)
                {
                    continue;
                }

                if (assemblies.ContainsKey(assembly.ItemSpec))
                {
                    continue;
                }

                var fi = new FileInfo(assembly.ItemSpec);
                if (!fi.Exists)
                {
                    Log.LogError($"Assembly {assembly.ItemSpec} does not exist");
                    continue;
                }

                assemblies.Add(CompressedAssemblyInfo.GetDictionaryKey(assembly),
                               new CompressedAssemblyInfo(checked ((uint)fi.Length)));
            }

            uint index = 0;

            foreach (var kvp in assemblies)
            {
                kvp.Value.DescriptorIndex = index++;
            }

            string key = CompressedAssemblyInfo.GetKey(ProjectFullPath);

            Log.LogDebugMessage($"Storing compression assemblies info with key '{key}'");
            BuildEngine4.RegisterTaskObjectAssemblyLocal(key, assemblies, RegisteredTaskObjectLifetime.Build);
            Generate(assemblies);

            void Generate(IDictionary <string, CompressedAssemblyInfo> dict)
            {
                foreach (string abi in SupportedAbis)
                {
                    NativeAssemblerTargetProvider asmTargetProvider = GeneratePackageManagerJava.GetAssemblyTargetProvider(abi);
                    string baseAsmFilePath = Path.Combine(EnvironmentOutputDirectory, $"compressed_assemblies.{abi.ToLowerInvariant ()}");
                    string asmFilePath     = $"{baseAsmFilePath}.s";
                    var    asmgen          = new CompressedAssembliesNativeAssemblyGenerator(dict, asmTargetProvider, baseAsmFilePath);

                    using (var sw = MemoryStreamPool.Shared.CreateStreamWriter()) {
                        asmgen.Write(sw);
                        sw.Flush();
                        if (MonoAndroidHelper.CopyIfStreamChanged(sw.BaseStream, asmFilePath))
                        {
                            Log.LogDebugMessage($"File {asmFilePath} was regenerated");
                        }
                    }
                }
            }
        }