Esempio n. 1
0
        /// <summary>
        /// Compile an assembly into a dex file.
        /// </summary>
        private static void CompileAssembly(CommandLineOptions options, NameConverter nsConverter)
        {
            // Load resource type usage info file
            var usedTypeNames = LoadResourceTypeUsageInformation(options);


            // Load assemblies
            List <AssemblyDefinition> assemblies = new List <AssemblyDefinition>();
            List <AssemblyDefinition> references = new List <AssemblyDefinition>();

            var dxJarCompiler = options.EnableDxJarCompilation
                ? new DxClassfileMethodBodyCompiler(options.OutputFolder, options.DebugInfo)
                : null;
            Action <ClassSource> jarLoaded = dxJarCompiler != null ? dxJarCompiler.PreloadJar : (Action <ClassSource>)null;

            var module      = new XModule();
            var classLoader = new AssemblyClassLoader(module.OnClassLoaded);
            var resolver    = new AssemblyResolver(options.ReferenceFolders, classLoader, module.OnAssemblyLoaded);

            // initialize compiler cache in background.
            var ccache = options.EnableCompilerCache ? new DexMethodBodyCompilerCache(options.OutputFolder, resolver.GetFileName)
                                                     : new DexMethodBodyCompilerCache();

            var readerParameters = new ReaderParameters
            {
                AssemblyResolver     = resolver,
                SymbolReaderProvider = new SafeSymbolReaderProvider(),
                ReadSymbols          = true,
                ReadingMode          = ReadingMode.Immediate
            };

            // load assemblies
            var toLoad = options.Assemblies.Select(path => new { path, target = assemblies })
                         .Concat(options.References.Select(path => new { path, target = references }))
                         // Some micro optimizations...
                         // Our startup is IO bound until we have loaded first assembly from disk.
                         // So just load from smallest to largest.
                         .Select(load => new { load.path, load.target, length = new FileInfo(resolver.ResolvePath(load.path)).Length })
                         .OrderBy(load => load.length)
                         .ToList();

            using (AssemblyCompiler.Profile("for loading assemblies"))
            {
                toLoad.AsParallel().ForAll(
                    //toLoad.ForEach(
                    load =>
                {
                    var assm = resolver.Load(load.path, readerParameters);
                    lock (load.target) load.target.Add(assm);
                });
            }

            // Load resources
            Table table;

            using (var stream = new FileStream(options.InputResources, FileMode.Open, FileAccess.Read))
            {
                table = new Table(stream);
            }

            // Create compiler
            var compiler = new AssemblyCompiler(options.CompilationMode, assemblies, references, table, nsConverter,
                                                options.DebugInfo, classLoader, resolver.GetFileName, ccache,
                                                usedTypeNames, module, options.GenerateSetNextInstructionCode);

            compiler.DxClassfileMethodBodyCompiler = dxJarCompiler;
            using (AssemblyCompiler.Profile("total compilation time", true))
                compiler.Compile();

            ccache.PrintStatistics();

            using (AssemblyCompiler.Profile("saving results"))
                compiler.Save(options.OutputFolder, options.FreeAppsKeyPath);
        }
Esempio n. 2
0
        /// <summary>
        /// Program main code
        /// </summary>
        /// <returns>true on success, false on usage due to invalid options</returns>
        internal static bool MainCode(CommandLineOptions options)
        {
            if (options.ShowHelp)
            {
                return(false);
            }

            // Detect target
            var target = Locations.SetTarget(options.Target);

            // Build APK/BAR?
            if (!string.IsNullOrEmpty(options.PackagePath))
            {
#if DEBUG
                //Debugger.Launch();
#endif

                // Build APK first
                var apkPath = options.PackagePath;
                if (target == Targets.BlackBerry)
                {
                    // Put APK in TEMP folder
                    apkPath = Path.GetTempFileName() + ".apk";
                }

                var apkBuilder = new ApkBuilder.ApkBuilder(apkPath);
                apkBuilder.MapFilePath  = Path.ChangeExtension(options.PackagePath, ".d42map");
                apkBuilder.ManifestPath = options.ManifestFile;
                apkBuilder.DexFiles.AddRange(options.DexFiles);
                apkBuilder.MapFiles.AddRange(options.MapFiles);
                if (options.Assemblies.Any())
                {
                    apkBuilder.Assemblies.AddRange(options.Assemblies);
                }
                apkBuilder.ResourcesFolder       = options.ResourcesFolder;
                apkBuilder.PfxFile               = options.PfxFile;
                apkBuilder.PfxPassword           = options.PfxPassword;
                apkBuilder.CertificateThumbprint = options.CertificateThumbprint;
                apkBuilder.FreeAppsKeyPath       = options.FreeAppsKeyPath;
                apkBuilder.PackageName           = options.PackageName;
                apkBuilder.NativeCodeLibraries.AddRange(options.NativeCodeLibs);
                apkBuilder.Build();

                if (target == Targets.BlackBerry)
                {
                    // Now build BAR
                    var barBuilder = new BarBuilder.BarBuilder(options.PackagePath);
                    barBuilder.ApkPath        = apkPath;
                    barBuilder.DebugTokenPath = options.DebugToken;
                    barBuilder.Build();
                }
            }
            else if (!string.IsNullOrEmpty(options.JarFile)) // Import jar file?
            {
                var module      = new XModule();
                var resolver    = new AssemblyResolver(options.ReferenceFolders, new AssemblyClassLoader(module.OnClassLoaded), module.OnAssemblyLoaded);
                var jarImporter = new JarImporter(options.JarFile, options.LibName, options.ImportStubsOnly, false /*true*/, options.GeneratedCodeFolder, resolver, options.ExcludedPackages, options.UseAutoExcludedPackages);
                foreach (var path in options.References)
                {
                    jarImporter.ImportAssembly(path);
                }
                jarImporter.ImportAssembliesCompleted();
                jarImporter.Import();
            }
            else if (options.WcfProxyInputAssemblies.Any()) // Generate WCF Proxy
            {
                var resolver         = new AssemblyResolver(options.ReferenceFolders, null, null);
                var readerParameters = new ReaderParameters(ReadingMode.Immediate)
                {
                    AssemblyResolver     = resolver,
                    SymbolReaderProvider = new SafeSymbolReaderProvider(),
                    ReadSymbols          = true
                };
                var assemblies = options.WcfProxyInputAssemblies.Select(x => resolver.Load(x, readerParameters)).ToList();
                var proxyTool  = new ProxyBuilderTool(assemblies, options.GeneratedProxySourcePath);
                proxyTool.Build();
            }
            else
            {
                // Create namespace converter
                var nsConverter = new NameConverter(options.PackageName, options.RootNamespace);

                // Create manifest file?
                if (options.CreateManifest)
                {
                    ManifestBuilder.CreateManifest(target, options.Assemblies.First(), options.ReferenceFolders, options.PackageName, nsConverter,
                                                   options.DebugInfo, options.AppWidgetProviders, options.TargetSdkVersion, options.OutputFolder);
                }
                else
                {
                    // Code compilation?
                    if (options.Assemblies.Any())
                    {
#if DEBUG
                        //Debugger.Launch();
#endif
                        using (AssemblyCompiler.Profile("total processing time", true))
                            CompileAssembly(options, nsConverter);
                    }
                }

                // Xml compilation
                if (options.CompileResources)
                {
                    if (!CompileResources(options))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }