Пример #1
0
        /// <summary>
        /// Configures the project to prepare for building the specified scenes in an instant app.
        /// </summary>
        public static void ConfigureProject(string[] scenesInBuild)
        {
            AndroidSdk.ApplyEditorPrefsWorkaround();

            var requiredPolicies = PlayInstantSettingPolicy.GetRequiredPolicies();

            foreach (var policy in requiredPolicies)
            {
                var policyChangeCompleted = policy.ChangeState();
                if (!policyChangeCompleted)
                {
                    throw new Exception(string.Format("Failed to change policy: {0}", policy.Name));
                }
            }

            SetTargetArchitectures();

            var manifestUpdater = AndroidManifestHelper.GetAndroidManifestUpdater();
            var errorMessage    = manifestUpdater.SwitchToInstant(null);

            if (errorMessage != null)
            {
                throw new Exception(string.Format("Error updating AndroidManifest.xml: {0}", errorMessage));
            }

            PlayInstantBuildConfiguration.AddScriptingDefineSymbol(
                PlaySignatureVerifier.SkipVerifyGooglePlayServicesScriptingDefineSymbol);
            PlayInstantBuildConfiguration.SaveConfiguration("", scenesInBuild, "");
            PlayInstantBuildConfiguration.SetInstantBuildType();
        }
        void CompileJava(IEnumerable <string> files)
        {
            if (Options.Compilation.Platform == TargetPlatform.Android)
            {
                if (!initXamarinAndroidTools)
                {
                    AndroidLogger.Info     += AndroidLogger_Info;
                    AndroidLogger.Error    += AndroidLogger_Error;
                    initXamarinAndroidTools = true;
                }

                AndroidSdk.Refresh();
            }

            var executableSuffix = Platform.IsWindows ? ".exe" : string.Empty;
            var javac            = $"{Path.Combine(GetJavaSdkPath(), "bin", "javac" + executableSuffix)}";

            var args = new List <string> {
                string.Join(" ", files.Select(file => Path.GetFullPath(file)))
            };

            if (Options.Compilation.DebugMode)
            {
                args.Add("-g");
            }

            var invocation = string.Join(" ", args);

            Invoke(javac, invocation);
        }
Пример #3
0
        /// <summary>
        /// Emulates Unity's File -> Build And Run menu option.
        /// </summary>
        private static void EmulateUnityBuildAndRun()
        {
            var androidSdk         = new AndroidSdk();
            var androidSdkPlatform = new AndroidSdkPlatform(androidSdk);
            var androidBuildTools  = new AndroidBuildTools(androidSdk);
            var javaUtils          = new JavaUtils();
            var apkSigner          = new ApkSigner(androidBuildTools, javaUtils);
            var androidBuilder     = new AndroidBuilder(androidSdkPlatform, apkSigner);
            var buildToolLogger    = new BuildToolLogger();

            if (!androidBuilder.Initialize(buildToolLogger))
            {
                return;
            }

            if (EditorUserBuildSettings.androidBuildSystem == AndroidBuildSystem.Gradle)
            {
                EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
            }

            var artifactName       = AndroidAppBundle.IsNativeBuildEnabled() ? "temp.aab" : "temp.apk";
            var artifactPath       = Path.Combine(Path.GetTempPath(), artifactName);
            var buildPlayerOptions = AndroidBuildHelper.CreateBuildPlayerOptions(artifactPath);

            buildPlayerOptions.options |= BuildOptions.AutoRunPlayer;
            androidBuilder.Build(buildPlayerOptions);
        }
Пример #4
0
        static XamarinAndroid()
        {
            AndroidLogger.Info    += AndroidLogger_Info;
            AndroidLogger.Warning += AndroidLogger_Warning;
            AndroidLogger.Error   += AndroidLogger_Error;

            AndroidSdk.Refresh();
        }
        private static AppBundleRunner CreateAppBundleRunner()
        {
            var androidSdk = new AndroidSdk();
            var javaUtils  = new JavaUtils();
            var adb        = new AndroidDebugBridge(androidSdk);
            var bundletool = new BundletoolHelper(javaUtils);

            return(new AppBundleRunner(adb, bundletool));
        }
Пример #6
0
        void RefreshAndroidSdk()
        {
            if (Options.Compilation.Platform == TargetPlatform.Android)
            {
                if (!initXamarinAndroidTools)
                {
                    AndroidLogger.Info     += AndroidLogger_Info;
                    AndroidLogger.Error    += AndroidLogger_Error;
                    initXamarinAndroidTools = true;
                }

                AndroidSdk.Refresh();
            }
        }
Пример #7
0
        private static AppBundleBuilder CreateAppBundleBuilder(string workingDirectoryPath)
        {
            var androidSdk         = new AndroidSdk();
            var javaUtils          = new JavaUtils();
            var androidSdkPlatform = new AndroidSdkPlatform(androidSdk);
            var androidBuildTools  = new AndroidBuildTools(androidSdk);
            var jarSigner          = new JarSigner(javaUtils);

            return(new AppBundleBuilder(
                       new AndroidAssetPackagingTool(androidBuildTools, androidSdkPlatform),
                       new AndroidBuilder(androidSdkPlatform),
                       new BundletoolHelper(javaUtils),
                       jarSigner,
                       workingDirectoryPath,
                       new ZipUtils(javaUtils)));
        }
Пример #8
0
        /// <summary>
        /// Emulates Unity's File -> Build And Run menu option.
        /// </summary>
        private static void EmulateUnityBuildAndRun()
        {
            var androidSdk         = new AndroidSdk();
            var androidSdkPlatform = new AndroidSdkPlatform(androidSdk);
            var androidBuilder     = new AndroidBuilder(androidSdkPlatform);
            var buildToolLogger    = new BuildToolLogger();

            if (!androidBuilder.Initialize(buildToolLogger))
            {
                return;
            }

            var artifactName       = EditorUserBuildSettings.buildAppBundle ? "temp.aab" : "temp.apk";
            var artifactPath       = Path.Combine(Path.GetTempPath(), artifactName);
            var buildPlayerOptions = AndroidBuildHelper.CreateBuildPlayerOptions(artifactPath);

            buildPlayerOptions.options |= BuildOptions.AutoRunPlayer;
            androidBuilder.Build(buildPlayerOptions);
        }
        /// <summary>
        /// Builds an APK to a temporary location, then installs and runs it using ia.jar
        /// </summary>
        private static void BuildAndRunApk(BuildToolLogger buildToolLogger)
        {
            var androidSdk             = new AndroidSdk();
            var androidSdkPlatform     = new AndroidSdkPlatform(androidSdk);
            var androidBuildTools      = new AndroidBuildTools(androidSdk);
            var javaUtils              = new JavaUtils();
            var apkSigner              = new ApkSigner(androidBuildTools, javaUtils);
            var androidBuilder         = new AndroidBuilder(androidSdkPlatform, apkSigner);
            var playInstantBuildHelper = new PlayInstantBuildHelper(isInstantRequired: true);

            if (!androidBuilder.Initialize(buildToolLogger) ||
                !playInstantBuildHelper.Initialize(buildToolLogger) ||
                !javaUtils.Initialize(buildToolLogger))
            {
                return;
            }

            var jarPath = IaJarPath;

            if (jarPath == null)
            {
                buildToolLogger.DisplayErrorDialog("Build and Run failed to locate ia.jar file");
                return;
            }

            AndroidAppBundle.DisableNativeBuild();

            var apkPath = Path.Combine(Path.GetTempPath(), "temp.apk");

            Debug.LogFormat("Build and Run package location: {0}", apkPath);

            var buildPlayerOptions = AndroidBuildHelper.CreateBuildPlayerOptions(apkPath);

            if (!androidBuilder.BuildAndSign(buildPlayerOptions))
            {
                // Do not log here. The method we called was responsible for logging.
                return;
            }

            InstallInstantApp(jarPath, apkPath, androidSdk, javaUtils);
        }
        private static void InstallInstantApp(string jarPath, string artifactPath, AndroidSdk androidSdk,
                                              JavaUtils javaUtils)
        {
            var window = PostBuildCommandLineDialog.CreateDialog("Install and run app");

            window.modal              = false;
            window.summaryText        = "Installing app on device";
            window.bodyText           = "Built successfully.\n\n";
            window.autoScrollToBottom = true;
            window.CommandLineParams  = new CommandLineParameters
            {
                FileName  = javaUtils.JavaBinaryPath,
                Arguments = string.Format(
                    "-jar {0} run {1}",
                    CommandLine.QuotePath(jarPath),
                    CommandLine.QuotePath(artifactPath))
            };
            window.CommandLineParams.AddEnvironmentVariable(
                AndroidSdk.AndroidHomeEnvironmentVariableKey, androidSdk.RootPath);
            window.Show();
        }
        private static string GetInstantAppJarPath(AndroidSdk androidSdk, BuildToolLogger buildToolLogger)
        {
            var jarPath = Path.Combine(androidSdk.RootPath, InstantAppsJarPath);

            if (File.Exists(jarPath))
            {
                return(jarPath);
            }

            Debug.LogErrorFormat("Build and Run failed to locate ia.jar file at: {0}", jarPath);
            var message =
                string.Format(
                    "Failed to locate version 1.2 or later of the {0}.\n\nClick \"OK\" to install the {0}.",
                    InstantAppsSdkDisplayName);

            if (buildToolLogger.DisplayActionableErrorDialog(message))
            {
                AndroidSdkPackageInstaller.InstallPackage(InstantAppsSdkPackageName, InstantAppsSdkDisplayName);
            }

            return(null);
        }
Пример #12
0
        /// <summary>
        /// Runs the cmake tool.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="platform">The output platform.</param>
        /// <param name="architecture">The output architecture.</param>
        /// <param name="customArgs">The custom arguments for the CMake.</param>
        /// <param name="envVars">Custom environment variables to pass to the child process.</param>
        public static void RunCmake(string path, TargetPlatform platform, TargetArchitecture architecture, string customArgs = null, Dictionary <string, string> envVars = null)
        {
            string cmdLine;

            switch (platform)
            {
            case TargetPlatform.Windows:
            case TargetPlatform.XboxOne:
            case TargetPlatform.XboxScarlett:
            case TargetPlatform.UWP:
            {
                string arch;
                switch (architecture)
                {
                case TargetArchitecture.x86:
                    arch = string.Empty;
                    break;

                case TargetArchitecture.x64:
                    arch = " Win64";
                    break;

                case TargetArchitecture.ARM:
                    arch = " ARM";
                    break;

                case TargetArchitecture.ARM64:
                    arch = " ARM64";
                    break;

                default: throw new InvalidArchitectureException(architecture);
                }
                cmdLine = string.Format("CMakeLists.txt -G \"Visual Studio 14 2015{0}\"", arch);
                break;
            }

            case TargetPlatform.Linux:
            case TargetPlatform.PS4:
            {
                cmdLine = "CMakeLists.txt";
                break;
            }

            case TargetPlatform.Switch:
            {
                cmdLine = string.Format("-DCMAKE_TOOLCHAIN_FILE=\"{1}\\Source\\Platforms\\Switch\\Data\\Switch.cmake\" -G \"NMake Makefiles\" -DCMAKE_MAKE_PROGRAM=\"{0}..\\..\\VC\\bin\\nmake.exe\"", Environment.GetEnvironmentVariable("VS140COMNTOOLS"), Globals.EngineRoot);
                break;
            }

            case TargetPlatform.Android:
            {
                var ndk      = AndroidNdk.Instance.RootPath;
                var abi      = AndroidToolchain.GetAbiName(architecture);
                var hostName = AndroidSdk.GetHostName();
                cmdLine = string.Format("-DCMAKE_TOOLCHAIN_FILE=\"{0}/build/cmake/android.toolchain.cmake\" -DANDROID_NDK=\"{0}\" -DANDROID_STL=c++_shared -DANDROID_ABI={1} -DANDROID_PLATFORM=android-{2} -G \"MinGW Makefiles\" -DCMAKE_MAKE_PROGRAM=\"{0}/prebuilt/{3}/bin/make.exe\"", ndk, abi, Configuration.AndroidPlatformApi, hostName);
                break;
            }

            default: throw new InvalidPlatformException(platform);
            }

            if (customArgs != null)
            {
                cmdLine += " " + customArgs;
            }

            Utilities.Run("cmake", cmdLine, null, path, Utilities.RunOptions.None, envVars);
        }
Пример #13
0
        public override bool Execute()
        {
            Log.LogDebugMessage("JarToXml Task");
            Log.LogDebugMessage("  JavaOptions: {0}", JavaOptions);
            Log.LogDebugMessage("  JavaMaximumHeapSize: {0}", JavaMaximumHeapSize);
            Log.LogDebugMessage("  AndroidSdkDirectory: {0}", AndroidSdkDirectory);
            Log.LogDebugMessage("  AndroidApiLevel: {0}", AndroidApiLevel);
            Log.LogDebugMessage("  MonoAndroidToolsDirectory: {0}", MonoAndroidToolsDirectory);
            Log.LogDebugMessage("  JavaSdkDirectory: {0}", JavaSdkDirectory);
            Log.LogDebugMessage("  OutputFile: {0}", OutputFile);
            Log.LogDebugMessage("  DroidDocPaths: {0}", DroidDocPaths);
            Log.LogDebugMessage("  JavaDocPaths: {0}", JavaDocPaths);
            Log.LogDebugMessage("  Java7DocPaths: {0}", Java7DocPaths);
            Log.LogDebugMessage("  Java8DocPaths: {0}", Java8DocPaths);
            Log.LogDebugTaskItems("  JavaDocs: {0}", JavaDocs);
            Log.LogDebugTaskItems("  LibraryProjectJars:", LibraryProjectJars);
            Log.LogDebugTaskItems("  SourceJars:", SourceJars);
            Log.LogDebugTaskItems("  ReferenceJars:", ReferenceJars);

            if (SourceJars == null || SourceJars.Count() == 0)
            {
                Log.LogError("At least one Java library is required for binding, this must be either 'EmbeddedJar', 'InputJar' (for jar), 'LibraryProjectZip' (for aar or zip) or 'LibraryProjectProperties' (project.properties) build action.");
                return(false);
            }

            // Ensure that the user has the platform they are targeting installed
            var jarpath = Path.Combine(AndroidSdk.GetPlatformDirectoryFromApiLevel(AndroidApiLevel, MonoAndroidHelper.SupportedVersions), "android.jar");

            if (!File.Exists(jarpath))
            {
                Log.LogError("Could not find android.jar for API Level {0}.  This means the Android SDK platform for API Level {0} is not installed.  Either install it in the Android SDK Manager, or change your Android Bindings project to target an API version that is installed. ({1} missing.)", AndroidApiLevel, jarpath);
                return(false);
            }

            // Ensure that all requested jars exist
            foreach (var jar in SourceJars)
            {
                if (!File.Exists(jar.ItemSpec))
                {
                    Log.LogError("Specified source jar not found: {0}", jar.ItemSpec);
                }
            }

            if (ReferenceJars != null)
            {
                foreach (var jar in ReferenceJars)
                {
                    if (!File.Exists(jar.ItemSpec))
                    {
                        Log.LogError("Specified reference jar not found: {0}", jar.ItemSpec);
                    }
                }
            }

            if (Log.HasLoggedErrors)
            {
                return(false);
            }

            // Ensure our output directory exists
            Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));

            return(base.Execute());
        }
Пример #14
0
        /// <summary>
        /// Generates a Package.proj file for MSBuild to invoke
        /// - Generates Resource.designer.dll for rewiring resource values from the final Java project
        /// - Links .NET assemblies and places output into /android/assets/assemblies
        /// - Extracts assets and resources from Android library projects into /obj/
        /// - Copies assets and resources into AAR
        /// - Invokes aapt to generate R.txt
        /// - One day I would like to get rid of the temp files, but I could not get the MSBuild APIs to work in-process
        /// </summary>
        public static string GeneratePackageProject(List <IKVM.Reflection.Assembly> assemblies, string outputDirectory, string assembliesDirectory)
        {
            var mainAssembly = assemblies[0].Location;

            outputDirectory     = Path.GetFullPath(outputDirectory);
            assembliesDirectory = Path.GetFullPath(assembliesDirectory);

            var androidDir   = Path.Combine(outputDirectory, "android");
            var assetsDir    = Path.Combine(androidDir, "assets");
            var resourceDir  = Path.Combine(androidDir, "res");
            var manifestPath = Path.Combine(androidDir, "AndroidManifest.xml");
            var packageName  = Generators.JavaGenerator.GetNativeLibPackageName(mainAssembly);
            var project      = CreateProject();
            var target       = project.AddTarget("Build");

            //Generate Resource.designer.dll
            var resourceDesigner = new ResourceDesignerGenerator
            {
                Assemblies      = assemblies,
                MainAssembly    = mainAssembly,
                OutputDirectory = outputDirectory,
                PackageName     = packageName,
            };

            resourceDesigner.Generate();

            if (!resourceDesigner.WriteAssembly())
            {
                //Let's generate CS if this failed
                string resourcePath = resourceDesigner.WriteSource();
                throw new Exception($"Resource.designer.dll compilation failed! See {resourcePath} for details.");
            }

            //ResolveAssemblies Task
            ResolveAssemblies(target, mainAssembly);

            //LinkAssemblies Task
            var linkAssemblies = target.AddTask("LinkAssemblies");

            linkAssemblies.SetParameter("UseSharedRuntime", "False");
            linkAssemblies.SetParameter("LinkMode", LinkMode);
            linkAssemblies.SetParameter("LinkDescriptions", "@(LinkDescription)");
            linkAssemblies.SetParameter("DumpDependencies", "True");
            linkAssemblies.SetParameter("ResolvedAssemblies", "@(ResolvedAssemblies);" + Path.Combine(outputDirectory, "Resource.designer.dll"));
            linkAssemblies.SetParameter("MainAssembly", mainAssembly);
            linkAssemblies.SetParameter("OutputDirectory", assembliesDirectory);

            //Aapt Task to generate R.txt
            var aapt = target.AddTask("Aapt");

            aapt.SetParameter("ImportsDirectory", outputDirectory);
            aapt.SetParameter("OutputImportDirectory", outputDirectory);
            aapt.SetParameter("ManifestFiles", manifestPath);
            aapt.SetParameter("ApplicationName", packageName);
            aapt.SetParameter("JavaPlatformJarPath", Path.Combine(XamarinAndroid.PlatformDirectory, "android.jar"));
            aapt.SetParameter("JavaDesignerOutputDirectory", outputDirectory);
            aapt.SetParameter("AssetDirectory", assetsDir);
            aapt.SetParameter("ResourceDirectory", resourceDir);
            aapt.SetParameter("ToolPath", AndroidSdk.GetBuildToolsPaths().First());
            aapt.SetParameter("ToolExe", "aapt");
            aapt.SetParameter("ApiLevel", XamarinAndroid.TargetSdkVersion);
            aapt.SetParameter("ExtraArgs", "--output-text-symbols " + androidDir);

            //There is an extra /manifest/AndroidManifest.xml file created
            var removeDir = target.AddTask("RemoveDir");

            removeDir.SetParameter("Directories", Path.Combine(androidDir, "manifest"));

            //NOTE: might avoid the temp file later
            var projectFile = Path.Combine(outputDirectory, "Package.proj");

            project.Save(projectFile);
            return(projectFile);
        }
Пример #15
0
        public bool RunTask()
        {
            Log.LogDebugMessage("ResolveSdksTask:");
            Log.LogDebugMessage("  AndroidApiLevel: {0}", AndroidApiLevel);
            Log.LogDebugMessage("  AndroidSdkBuildToolsVersion: {0}", AndroidSdkBuildToolsVersion);
            Log.LogDebugMessage($"  {nameof (AndroidSdkPath)}: {AndroidSdkPath}");
            Log.LogDebugMessage($"  {nameof (AndroidNdkPath)}: {AndroidNdkPath}");
            Log.LogDebugTaskItems("  ReferenceAssemblyPaths: ", ReferenceAssemblyPaths);
            Log.LogDebugMessage("  TargetFrameworkVersion: {0}", TargetFrameworkVersion);
            Log.LogDebugMessage("  UseLatestAndroidPlatformSdk: {0}", UseLatestAndroidPlatformSdk);
            Log.LogDebugMessage("  SequencePointsMode: {0}", SequencePointsMode);
            Log.LogDebugMessage("  LintToolPath: {0}", LintToolPath);

            // OS X:    $prefix/lib/xamarin.android/xbuild/Xamarin/Android
            // Windows: %ProgramFiles(x86)%\MSBuild\Xamarin\Android
            if (string.IsNullOrEmpty(MonoAndroidToolsPath))
            {
                MonoAndroidToolsPath = Path.GetDirectoryName(typeof(ResolveSdks).Assembly.Location);
            }
            MonoAndroidBinPath = MonoAndroidHelper.GetOSBinPath() + Path.DirectorySeparatorChar;

            MonoAndroidHelper.RefreshMonoDroidSdk(MonoAndroidToolsPath, null, ReferenceAssemblyPaths);
            MonoAndroidHelper.RefreshAndroidSdk(AndroidSdkPath, AndroidNdkPath, JavaSdkPath);

            this.AndroidNdkPath = AndroidSdk.AndroidNdkPath;
            this.AndroidSdkPath = AndroidSdk.AndroidSdkPath;
            this.JavaSdkPath    = AndroidSdk.JavaSdkPath;

            if (string.IsNullOrEmpty(AndroidSdkPath))
            {
                Log.LogCodedError("XA5205", "The Android SDK Directory could not be found. Please set via /p:AndroidSdkDirectory.");
                return(false);
            }

            string toolsZipAlignPath = Path.Combine(AndroidSdkPath, "tools", ZipAlign);
            bool   findZipAlign      = (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath)) && !File.Exists(toolsZipAlignPath);

            var lintPaths = new string [] {
                LintToolPath ?? string.Empty,
                Path.Combine(AndroidSdkPath, "tools"),
                Path.Combine(AndroidSdkPath, "tools", "bin"),
            };

            LintToolPath = null;
            foreach (var path in lintPaths)
            {
                if (File.Exists(Path.Combine(path, Lint)))
                {
                    LintToolPath = path;
                    break;
                }
            }

            foreach (var dir in AndroidSdk.GetBuildToolsPaths(AndroidSdkBuildToolsVersion))
            {
                Log.LogDebugMessage("Trying build-tools path: {0}", dir);
                if (dir == null || !Directory.Exists(dir))
                {
                    continue;
                }

                var toolsPaths = new string[] {
                    Path.Combine(dir),
                    Path.Combine(dir, "bin"),
                };

                string aapt = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, Aapt)));
                if (string.IsNullOrEmpty(aapt))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", Aapt,
                                        string.Join(";", toolsPaths.Select(x => Path.Combine(x, Aapt))));
                    continue;
                }
                AndroidSdkBuildToolsPath    = Path.GetFullPath(dir);
                AndroidSdkBuildToolsBinPath = Path.GetFullPath(aapt);

                string zipalign = toolsPaths.FirstOrDefault(x => File.Exists(Path.Combine(x, ZipAlign)));
                if (findZipAlign && string.IsNullOrEmpty(zipalign))
                {
                    Log.LogDebugMessage("Could not find `{0}`; tried: {1}", ZipAlign,
                                        string.Join(";", toolsPaths.Select(x => Path.Combine(x, ZipAlign))));
                    continue;
                }
                else
                {
                    break;
                }
            }

            if (string.IsNullOrEmpty(AndroidSdkBuildToolsPath))
            {
                Log.LogCodedError("XA5205",
                                  string.Format(
                                      "Cannot find `{0}`. Please install the Android SDK Build-tools package with the `{1}{2}tools{2}{3}` program.",
                                      Aapt, AndroidSdkPath, Path.DirectorySeparatorChar, Android));
                return(false);
            }

            if (string.IsNullOrEmpty(ZipAlignPath) || !Directory.Exists(ZipAlignPath))
            {
                ZipAlignPath = new[] {
                    Path.Combine(AndroidSdkBuildToolsPath),
                    Path.Combine(AndroidSdkBuildToolsBinPath),
                    Path.Combine(AndroidSdkPath, "tools"),
                }
                .Where(p => File.Exists(Path.Combine(p, ZipAlign)))
                .FirstOrDefault();
            }
            if (string.IsNullOrEmpty(ZipAlignPath))
            {
                Log.LogCodedError("XA5205",
                                  string.Format(
                                      "Cannot find `{0}`. Please install the Android SDK Build-tools package with the `{1}{2}tools{2}{3}` program.",
                                      ZipAlign, AndroidSdkPath, Path.DirectorySeparatorChar, Android));
                return(false);
            }

            if (!ValidateApiLevels())
            {
                return(false);
            }

            string frameworksPath = Path.GetDirectoryName(MonoDroidSdk.FrameworkPath);

            if (!Directory.Exists(Path.Combine(frameworksPath, TargetFrameworkVersion)))
            {
                Log.LogError(
                    subcategory:      string.Empty,
                    errorCode:        "XA0001",
                    helpKeyword:      string.Empty,
                    file:             ProjectFilePath,
                    lineNumber:       0,
                    columnNumber:     0,
                    endLineNumber:    0,
                    endColumnNumber:  0,
                    message:          "Unsupported or invalid $(TargetFrameworkVersion) value of '{0}'. Please update your Project Options.",
                    messageArgs:      new[] {
                    TargetFrameworkVersion,
                }
                    );
                return(false);
            }

            SequencePointsMode mode;

            if (!Aot.TryGetSequencePointsMode(SequencePointsMode ?? "None", out mode))
            {
                Log.LogCodedError("XA0104", "Invalid Sequence Point mode: {0}", SequencePointsMode);
            }
            AndroidSequencePointsMode = mode.ToString();

            MonoAndroidHelper.TargetFrameworkDirectories = ReferenceAssemblyPaths;

            AndroidApiLevelName = MonoAndroidHelper.GetPlatformApiLevelName(AndroidApiLevel);

            Log.LogDebugMessage("ResolveSdksTask Outputs:");
            Log.LogDebugMessage("  AndroidApiLevel: {0}", AndroidApiLevel);
            Log.LogDebugMessage("  AndroidApiLevelName: {0}", AndroidApiLevelName);
            Log.LogDebugMessage("  AndroidNdkPath: {0}", AndroidNdkPath);
            Log.LogDebugMessage("  AndroidSdkBuildToolsPath: {0}", AndroidSdkBuildToolsPath);
            Log.LogDebugMessage("  AndroidSdkBuildToolsBinPath: {0}", AndroidSdkBuildToolsBinPath);
            Log.LogDebugMessage("  AndroidSdkPath: {0}", AndroidSdkPath);
            Log.LogDebugMessage("  JavaSdkPath: {0}", JavaSdkPath);
            Log.LogDebugMessage("  MonoAndroidBinPath: {0}", MonoAndroidBinPath);
            Log.LogDebugMessage("  MonoAndroidToolsPath: {0}", MonoAndroidToolsPath);
            Log.LogDebugMessage("  TargetFrameworkVersion: {0}", TargetFrameworkVersion);
            Log.LogDebugMessage("  ZipAlignPath: {0}", ZipAlignPath);
            Log.LogDebugMessage("  SupportedApiLevel: {0}", SupportedApiLevel);
            Log.LogDebugMessage("  AndroidSequencePointMode: {0}", AndroidSequencePointsMode);
            Log.LogDebugMessage("  LintToolPath: {0}", LintToolPath);

            if (!string.IsNullOrEmpty(CacheFile))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(CacheFile));

                var document = new XDocument(
                    new XDeclaration("1.0", "UTF-8", null),
                    new XElement("Sdk",
                                 new XElement("AndroidApiLevel", AndroidApiLevel),
                                 new XElement("AndroidApiLevelName", AndroidApiLevelName),
                                 new XElement("AndroidNdkPath", AndroidNdkPath),
                                 new XElement("AndroidSdkBuildToolsPath", AndroidSdkBuildToolsPath),
                                 new XElement("AndroidSdkBuildToolsBinPath", AndroidSdkBuildToolsBinPath),
                                 new XElement("AndroidSdkPath", AndroidSdkPath),
                                 new XElement("JavaSdkPath", JavaSdkPath),
                                 new XElement("MonoAndroidBinPath", MonoAndroidBinPath),
                                 new XElement("MonoAndroidToolsPath", MonoAndroidToolsPath),
                                 new XElement("ReferenceAssemblyPaths",
                                              (ReferenceAssemblyPaths ?? new string [0])
                                              .Select(e => new XElement("ReferenceAssemblyPath", e))),
                                 new XElement("TargetFrameworkVersion", TargetFrameworkVersion),
                                 new XElement("ZipAlignPath", ZipAlignPath),
                                 new XElement("MonoAndroidIncludePath", MonoAndroidIncludePath),
                                 new XElement("SupportedApiLevel", SupportedApiLevel),
                                 new XElement("AndroidSequencePointsMode", AndroidSequencePointsMode.ToString()),
                                 new XElement("LintToolPath", LintToolPath)
                                 ));
                document.Save(CacheFile);
            }

            //note: this task does not error out if it doesn't find all things. that's the job of the targets
            return(!Log.HasLoggedErrors);
        }
Пример #16
0
        protected override string GenerateCommandLineCommands()
        {
            var cmd = new CommandLineBuilder();

            // Add the JavaOptions if they are not null
            // These could be any of the additional options
            if (!string.IsNullOrEmpty(JavaOptions))
            {
                cmd.AppendSwitch(JavaOptions);
            }

            // Add the specific -XmxN to override the default heap size for the JVM
            // N can be in the form of Nm or NGB (e.g 100m or 1GB )
            cmd.AppendSwitchIfNotNull("-Xmx", JavaMaximumHeapSize);

            // See https://bugzilla.xamarin.com/show_bug.cgi?id=21096
            cmd.AppendSwitch("-XX:-UseSplitVerifier");

            // Arguments sent to java.exe
            cmd.AppendSwitchIfNotNull("-jar ", Path.Combine(MonoAndroidToolsDirectory, "jar2xml.jar"));

            foreach (var jar in SourceJars)
            {
                cmd.AppendSwitchIfNotNull("--jar=", Path.GetFullPath(jar.ItemSpec));
            }

            var libraryProjectJars = MonoAndroidHelper.ExpandFiles(LibraryProjectJars);

            foreach (var jar in libraryProjectJars)
            {
                if (MonoAndroidHelper.IsEmbeddedReferenceJar(jar))
                {
                    cmd.AppendSwitchIfNotNull("--ref=", Path.GetFullPath(jar));
                }
                else
                {
                    cmd.AppendSwitchIfNotNull("--jar=", Path.GetFullPath(jar));
                }
            }

            // Arguments sent to jar2xml
            var jarpath = Path.Combine(AndroidSdk.GetPlatformDirectoryFromApiLevel(AndroidApiLevel, MonoAndroidHelper.SupportedVersions), "android.jar");

            cmd.AppendSwitchIfNotNull("--ref=", Path.GetFullPath(jarpath));

            cmd.AppendSwitchIfNotNull("--out=", Path.GetFullPath(OutputFile));

            if (ReferenceJars != null)
            {
                foreach (var jar in ReferenceJars)
                {
                    cmd.AppendSwitchIfNotNull("--ref=", Path.GetFullPath(jar.ItemSpec));
                }
            }

            if (DroidDocPaths != null)
            {
                foreach (var path in DroidDocPaths.Split(';'))
                {
                    cmd.AppendSwitchIfNotNull("--droiddocpath=", Path.GetFullPath(path));
                }
            }

            if (JavaDocPaths != null)
            {
                foreach (var path in JavaDocPaths.Split(';'))
                {
                    cmd.AppendSwitchIfNotNull("--javadocpath=", Path.GetFullPath(path));
                }
            }

            if (Java7DocPaths != null)
            {
                foreach (var path in Java7DocPaths.Split(';'))
                {
                    cmd.AppendSwitchIfNotNull("--java7docpath=", Path.GetFullPath(path));
                }
            }

            if (Java8DocPaths != null)
            {
                foreach (var path in Java8DocPaths.Split(';'))
                {
                    cmd.AppendSwitchIfNotNull("--java8docpath=", Path.GetFullPath(path));
                }
            }

            if (JavaDocs != null)
            {
                foreach (var doc in JavaDocs)
                {
                    var opt = GetJavadocOption(doc.ItemSpec);
                    if (opt != null)
                    {
                        cmd.AppendSwitchIfNotNull(opt, Path.GetFullPath(Path.GetDirectoryName(doc.ItemSpec)));
                    }
                }
            }
            return(cmd.ToString());
        }
Пример #17
0
 public static void RefreshAndroidSdk(string sdkPath, string ndkPath, string javaPath)
 {
     AndroidSdk.Refresh(sdkPath, ndkPath, javaPath);
 }
        public override bool Execute()
        {
            Log.LogDebugMessage("GetJavaPlatformJar Task");
            Log.LogDebugMessage("  AndroidSdkDirectory: {0}", AndroidSdkDirectory);
            Log.LogDebugMessage("  AndroidSdkPlatform: {0}", AndroidSdkPlatform);
            Log.LogDebugMessage("  AndroidManifest: {0}", AndroidManifest);

            var platform = AndroidSdkPlatform;

            XAttribute target_sdk = null;

            // Look for targetSdkVersion in the user's AndroidManifest.xml
            if (!string.IsNullOrWhiteSpace(AndroidManifest))
            {
                if (!File.Exists(AndroidManifest))
                {
                    Log.LogError("Specified AndroidManifest.xml file does not exist: {0}.", AndroidManifest);
                    return(false);
                }

                try {
                    var doc      = XDocument.Load(AndroidManifest);
                    var manifest = doc.Root;

                    if (manifest != null)
                    {
                        var uses_sdk = manifest.Element("uses-sdk");

                        if (uses_sdk != null)
                        {
                            target_sdk = uses_sdk.Attribute(androidNs + "targetSdkVersion");

                            if (target_sdk != null && !string.IsNullOrWhiteSpace(target_sdk.Value))
                            {
                                platform = target_sdk.Value;
                            }
                        }
                    }
                } catch (Exception ex) {
                    // If they're manifest is bad, let's error them out
                    Log.LogErrorFromException(ex, true);
                    return(false);
                }
            }

            platform            = GetTargetSdkVersion(platform, target_sdk);
            JavaPlatformJarPath = Path.Combine(AndroidSdk.GetPlatformDirectoryFromApiLevel(platform, MonoAndroidHelper.SupportedVersions), "android.jar");

            if (!File.Exists(JavaPlatformJarPath))
            {
                Log.LogError("Could not find android.jar for API Level {0}. " +
                             "This means the Android SDK platform for API Level {0} is not installed. " +
                             "Either install it in the Android SDK Manager (Tools > Open Android SDK Manager...), " +
                             "or change your Xamarin.Android project to target an API version that is installed. " +
                             "({1} missing.)",
                             platform, JavaPlatformJarPath);
                return(false);
            }

            TargetSdkVersion = platform;

            Log.LogDebugMessage("  [Output] JavaPlatformJarPath: {0}", JavaPlatformJarPath);
            Log.LogDebugMessage("  [Output] TargetSdkVersion: {0}", TargetSdkVersion);

            return(true);
        }
Пример #19
0
        /// <inheritdoc />
        public override void Build(BuildOptions options)
        {
            // Set it to the local path of the mono rep oto use for the build instead of cloning the remote one (helps with rapid testing)
            string localRepoPath = string.Empty;

            //localRepoPath = @"D:\Flax\3rdParty\mono";

            root = options.IntermediateFolder;
            if (!string.IsNullOrEmpty(localRepoPath))
            {
                root = localRepoPath;
            }
            monoPropsPath = Path.Combine(root, "msvc", "mono.props");

            // Get the source
            if (string.IsNullOrEmpty(localRepoPath))
            {
                CloneGitRepo(root, "https://github.com/FlaxEngine/mono.git", null, "--recursive");
            }

            // Pick a proper branch
            GitCheckout(root, "flax-master-5-20");
            GitResetLocalChanges(root);

            // Get the default preprocessor defines for Mono on Windows-based platforms
            {
                var monoProps = new XmlDocument();
                monoProps.Load(monoPropsPath);

                monoPreprocesorDefines = FindXmlNodeValue(monoProps, "MONO_PREPROCESSOR_DEFINITIONS");
            }

            foreach (var platform in options.Platforms)
            {
                switch (platform)
                {
                case TargetPlatform.Windows:
                {
                    BuildMsvc(options, platform, TargetArchitecture.x64);
                    //BuildBcl(options, platform);

                    // Export header files
                    Deploy.VCEnvironment.BuildSolution(Path.Combine(root, "msvc", "libmono-dynamic.vcxproj"), "Release", "x64");
                    Deploy.VCEnvironment.BuildSolution(Path.Combine(root, "msvc", "build-install.vcxproj"), "Release", "x64");

                    // Get exported mono methods to forward them in engine module (on Win32 platforms)
                    GetMonoExports(options);

                    if (BuildPlatform == TargetPlatform.Windows)
                    {
                        // Copy header files
                        var dstIncludePath     = Path.Combine(options.ThirdPartyFolder, "mono-2.0");
                        var dstMonoIncludePath = Path.Combine(dstIncludePath, "mono");
                        if (Directory.Exists(dstMonoIncludePath))
                        {
                            Directory.Delete(dstMonoIncludePath, true);
                        }
                        Utilities.DirectoryCopy(Path.Combine(root, "msvc", "include"), dstIncludePath);
                    }

                    break;
                }

                case TargetPlatform.UWP:
                {
                    ConfigureMsvc(options, "v141", "10.0.17763.0", "0x0A00", "_UWP=1;DISABLE_JIT;WINAPI_FAMILY=WINAPI_FAMILY_PC_APP;HAVE_EXTERN_DEFINED_WINAPI_SUPPORT");

                    BuildMsvc(options, platform, TargetArchitecture.x64);

                    break;
                }

                case TargetPlatform.XboxOne:
                {
                    ConfigureMsvc(options, "v141", "10.0.17763.0", "0x0A00", "_XBOX_ONE=1;DISABLE_JIT;WINAPI_FAMILY=WINAPI_FAMILY_PC_APP;HAVE_EXTERN_DEFINED_WINAPI_SUPPORT");

                    BuildMsvc(options, platform, TargetArchitecture.x64);

                    break;
                }

                case TargetPlatform.Linux:
                {
                    var envVars = new Dictionary <string, string>
                    {
                        { "CC", "clang-7" },
                        { "CXX", "clang++-7" }
                    };
                    var binaries = new[]
                    {
                        "lib/libmono-2.0.a",
                    };
                    var buildDir = Path.Combine(root, "build-linux");

                    SetupDirectory(buildDir, true);
                    var archName = UnixToolchain.GetToolchainName(platform, TargetArchitecture.x64);
                    Utilities.Run(Path.Combine(root, "autogen.sh"), string.Format("--host={0} --prefix={1} --disable-boehm --disable-mcs-build --enable-static", archName, buildDir), null, root, Utilities.RunOptions.Default, envVars);
                    Utilities.Run("make", null, null, root, Utilities.RunOptions.None, envVars);
                    Utilities.Run("make", "install", null, root, Utilities.RunOptions.None, envVars);
                    var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
                    foreach (var binary in binaries)
                    {
                        var src = Path.Combine(buildDir, binary);
                        var dst = Path.Combine(depsFolder, Path.GetFileName(binary));
                        Utilities.FileCopy(src, dst);
                    }
                    break;
                }

                case TargetPlatform.PS4:
                {
                    // TODO: implement automatic extraction of the package from mono-ps4-binaries
                    break;
                }

                case TargetPlatform.XboxScarlett:
                {
                    ConfigureMsvc(options, "v142", "10.0.19041.0", "0x0A00", "_XBOX_ONE=1;DISABLE_JIT;WINAPI_FAMILY=WINAPI_FAMILY_GAMES;HAVE_EXTERN_DEFINED_WINAPI_SUPPORT;CRITICAL_SECTION_NO_DEBUG_INFO=0x01000000");

                    BuildMsvc(options, platform, TargetArchitecture.x64);

                    break;
                }

                case TargetPlatform.Android:
                {
                    var sdk           = AndroidSdk.Instance.RootPath;
                    var ndk           = AndroidNdk.Instance.RootPath;
                    var apiLevel      = Configuration.AndroidPlatformApi.ToString();
                    var archName      = UnixToolchain.GetToolchainName(platform, TargetArchitecture.ARM64);
                    var toolchainRoot = Path.Combine(ndk, "toolchains", "llvm", "prebuilt", AndroidSdk.GetHostName());
                    var ndkBin        = Path.Combine(toolchainRoot, "bin");
                    var compilerFlags = string.Format("-DANDROID -DMONODROID=1 -DANDROID64 -D__ANDROID_API__={0} --sysroot=\"{1}/sysroot\" --gcc-toolchain=\"{1}\"", apiLevel, toolchainRoot);
                    var envVars       = new Dictionary <string, string>
                    {
                        { "ANDROID_SDK_ROOT", sdk },
                        { "ANDROID_SDK", sdk },
                        { "ANDROID_NDK_ROOT", ndk },
                        { "ANDROID_NDK", ndk },
                        { "NDK", ndk },
                        { "NDK_BIN", ndkBin },
                        { "ANDROID_PLATFORM", "android-" + apiLevel },
                        { "ANDROID_API", apiLevel },
                        { "ANDROID_API_VERSION", apiLevel },
                        { "ANDROID_NATIVE_API_LEVEL", apiLevel },

                        { "CC", Path.Combine(ndkBin, archName + apiLevel + "-clang") },
                        { "CXX", Path.Combine(ndkBin, archName + apiLevel + "-clang++") },
                        { "AR", Path.Combine(ndkBin, archName + "-ar") },
                        { "AS", Path.Combine(ndkBin, archName + "-as") },
                        { "LD", Path.Combine(ndkBin, archName + "-ld") },
                        { "RANLIB", Path.Combine(ndkBin, archName + "-ranlib") },
                        { "STRIP", Path.Combine(ndkBin, archName + "-strip") },
                        { "SYSROOT", toolchainRoot },
                        { "CFLAGS", compilerFlags },
                        { "CXXFLAGS", compilerFlags },
                        { "CPPFLAGS", compilerFlags },
                    };
                    var monoOptions = new[]
                    {
                        "--disable-crash-reporting",
                        "--disable-executables",
                        "--disable-iconv",
                        "--disable-boehm",
                        "--disable-nls",
                        "--disable-mcs-build",
                        "--enable-maintainer-mode",
                        "--enable-dynamic-btls",
                        "--enable-monodroid",
                        "--with-btls-android-ndk",
                        "--with-sigaltstack=yes",
                        string.Format("--with-btls-android-ndk={0}", ndk),
                        string.Format("--with-btls-android-api={0}", apiLevel),
                        string.Format("--with-btls-android-cmake-toolchain={0}/build/cmake/android.toolchain.cmake", ndk),
                        "--without-ikvm-native",
                    };
                    var binaries = new[]
                    {
                        "lib/libmonosgen-2.0.so",
                    };
                    var buildDir = Path.Combine(root, "build-android");
                    var envArgs  = "";
                    foreach (var e in envVars)
                    {
                        if (e.Value.Contains(' '))
                        {
                            envArgs += $" \"{e.Key}={e.Value}\"";
                        }
                        else
                        {
                            envArgs += $" {e.Key}={e.Value}";
                        }
                    }

                    // Compile mono
                    SetupDirectory(buildDir, true);
                    var toolchain = UnixToolchain.GetToolchainName(platform, TargetArchitecture.ARM64);
                    Utilities.Run(Path.Combine(root, "autogen.sh"), string.Format("--host={0} --prefix={1} {2}{3}", toolchain, buildDir, string.Join(" ", monoOptions), envArgs), null, root, Utilities.RunOptions.Default, envVars);
                    Utilities.Run("make", null, null, root, Utilities.RunOptions.None, envVars);
                    Utilities.Run("make", "install", null, root, Utilities.RunOptions.None, envVars);
                    var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.ARM64);
                    foreach (var binary in binaries)
                    {
                        var src = Path.Combine(buildDir, binary);
                        var dst = Path.Combine(depsFolder, Path.GetFileName(binary));
                        Utilities.FileCopy(src, dst);
                    }

                    // Clean before another build
                    GitResetLocalChanges(root);
                    Utilities.Run("make", "distclean", null, root, Utilities.RunOptions.None);

                    // Compile BCL
                    var installBcl       = Path.Combine(root, "bcl-android");
                    var bclOutput        = Path.Combine(GetBinariesFolder(options, platform), "Mono");
                    var bclLibOutput     = Path.Combine(bclOutput, "lib");
                    var bclLibMonoOutput = Path.Combine(bclLibOutput, "mono");
                    SetupDirectory(installBcl, true);
                    SetupDirectory(bclOutput, true);
                    SetupDirectory(bclLibOutput, false);
                    SetupDirectory(bclLibMonoOutput, false);
                    Utilities.DirectoryCopy(Path.Combine(buildDir, "etc"), Path.Combine(bclOutput, "etc"), true, true);
                    Utilities.FileCopy(Path.Combine(buildDir, "lib", "libMonoPosixHelper.so"), Path.Combine(bclLibOutput, "libMonoPosixHelper.so"));
                    Utilities.FileCopy(Path.Combine(buildDir, "lib", "libmono-native.so"), Path.Combine(bclLibOutput, "libmono-native.so"));
                    Utilities.FileCopy(Path.Combine(buildDir, "lib", "libmono-btls-shared.so"), Path.Combine(bclLibOutput, "libmono-btls-shared.so"));
                    var bclOptions = new[]
                    {
                        "--disable-boehm",
                        "--disable-btls-lib",
                        "--disable-nls",
                        "--disable-support-build",
                        "--with-mcs-docs=no",
                    };
                    Utilities.Run(Path.Combine(root, "autogen.sh"), string.Format("--prefix={0} {1}", installBcl, string.Join(" ", bclOptions)), null, root);
                    Utilities.Run("make", $"-j1 -C {root} -C mono", null, root, Utilities.RunOptions.None);
                    Utilities.Run("make", $"-j2 -C {root} -C runtime all-mcs build_profiles=monodroid", null, root, Utilities.RunOptions.None);
                    Utilities.DirectoryCopy(Path.Combine(root, "mcs", "class", "lib", "monodroid"), Path.Combine(bclLibMonoOutput, "2.1"), true, true, "*.dll");
                    Utilities.DirectoryDelete(Path.Combine(bclLibMonoOutput, "2.1", "Facades"));
                    break;
                }
                }
            }
        }
        /// <summary>
        /// Generates a Package.proj file for MSBuild to invoke
        /// - Generates Resource.designer.dll for rewiring resource values from the final Java project
        /// - Links .NET assemblies and places output into /android/assets/assemblies
        /// - Extracts assets and resources from Android library projects into /obj/
        /// - Copies assets and resources into AAR
        /// - Invokes aapt to generate R.txt
        /// - One day I would like to get rid of the temp files, but I could not get the MSBuild APIs to work in-process
        /// </summary>
        public static string GeneratePackageProject(List <IKVM.Reflection.Assembly> assemblies, Options options)
        {
            var mainAssembly        = assemblies[0].Location;
            var outputDirectory     = Path.GetFullPath(options.OutputDir);
            var assembliesDirectory = Path.Combine(outputDirectory, "android", "assets", "assemblies");

            var androidDir   = Path.Combine(outputDirectory, "android");
            var assetsDir    = Path.Combine(androidDir, "assets");
            var resourceDir  = Path.Combine(androidDir, "res");
            var manifestPath = Path.Combine(androidDir, "AndroidManifest.xml");
            var packageName  = Generators.JavaGenerator.GetNativeLibPackageName(mainAssembly);
            var project      = CreateProject();
            var target       = project.AddTarget("Build");

            //ResolveAssemblies Task
            ResolveAssemblies(target, assemblies);

            //LinkAssemblies Task
            var linkAssemblies = target.AddTask("LinkAssemblies");

            linkAssemblies.SetParameter("UseSharedRuntime", "False");
            linkAssemblies.SetParameter("LinkMode", LinkMode);
            linkAssemblies.SetParameter("LinkDescriptions", "@(LinkDescription)");
            linkAssemblies.SetParameter("DumpDependencies", "True");
            linkAssemblies.SetParameter("ResolvedAssemblies", "@(ResolvedAssemblies);" + Path.Combine(outputDirectory, "Resource.designer.dll"));
            linkAssemblies.SetParameter("MainAssembly", mainAssembly);
            linkAssemblies.SetParameter("OutputDirectory", assembliesDirectory);

            //If not Debug, delete our PDB files
            if (!options.Compilation.DebugMode)
            {
                var itemGroup = target.AddItemGroup();
                itemGroup.AddItem("PdbFilesToDelete", Path.Combine(assembliesDirectory, "*.pdb"));

                var delete = target.AddTask("Delete");
                delete.SetParameter("Files", "@(PdbFilesToDelete)");
            }

            //Aapt Task to generate R.txt
            var aapt = target.AddTask("Aapt");

            aapt.SetParameter("ImportsDirectory", outputDirectory);
            aapt.SetParameter("OutputImportDirectory", outputDirectory);
            aapt.SetParameter("ManifestFiles", manifestPath);
            aapt.SetParameter("ApplicationName", packageName);
            aapt.SetParameter("JavaPlatformJarPath", Path.Combine(XamarinAndroid.PlatformDirectory, "android.jar"));
            aapt.SetParameter("JavaDesignerOutputDirectory", outputDirectory);
            aapt.SetParameter("AssetDirectory", assetsDir);
            aapt.SetParameter("ResourceDirectory", resourceDir);
            aapt.SetParameter("ToolPath", AndroidSdk.GetBuildToolsPaths().First());
            aapt.SetParameter("ToolExe", "aapt");
            aapt.SetParameter("ApiLevel", XamarinAndroid.TargetSdkVersion);
            aapt.SetParameter("ExtraArgs", "--output-text-symbols " + androidDir);

            //There is an extra /manifest/AndroidManifest.xml file created
            var removeDir = target.AddTask("RemoveDir");

            removeDir.SetParameter("Directories", Path.Combine(androidDir, "manifest"));

            //NOTE: might avoid the temp file later
            var projectFile = Path.Combine(outputDirectory, "Package.proj");

            project.Save(projectFile);
            return(projectFile);
        }