diff --git a/examples/AndroidMath/AndroidManifest.xml b/examples/AndroidMath/AndroidManifest.xml index 317dbc9c1..c67ba9ad4 100644 --- a/examples/AndroidMath/AndroidManifest.xml +++ b/examples/AndroidMath/AndroidManifest.xml @@ -1,6 +1,7 @@ + path; } String GetPlatform() const { return this->platform; } - String GetBuildToolsRelease() const { return this->buildToolsRelease; } + String GetBuildToolsRelease() const { return this->build_tools_release; } void SetPath(const String& path) { this->path = path; } void SetPlatform(const String& platform) { this->platform = platform; } - void SetBuildToolsRelease(const String& buildToolsRelease) { this->buildToolsRelease = buildToolsRelease; } + void SetBuildToolsRelease(const String& build_tools_release) { this->build_tools_release = build_tools_release; } private: String path; String platform; - String buildToolsRelease; + String build_tools_release; }; class AndroidNDK { @@ -151,11 +150,26 @@ private: class AndroidManifest { public: - AndroidManifest(); + static constexpr const char* FILE_NAME = "AndroidManifest.xml"; + + class UsesSdk { + public: + int minSdkVersion = Null; + int targetSdkVersion = Null; + int maxSdkVersion = Null; + }; + +public: + AndroidManifest(const String& path); virtual ~AndroidManifest(); -private: + bool Parse(); +public: + One uses_sdk; + +private: + String path; }; } diff --git a/uppsrc/ide/Android/AndroidManifest.cpp b/uppsrc/ide/Android/AndroidManifest.cpp index ee7cfb4d9..8bd75abbf 100644 --- a/uppsrc/ide/Android/AndroidManifest.cpp +++ b/uppsrc/ide/Android/AndroidManifest.cpp @@ -1,15 +1,49 @@ #include "Android.h" +#define METHOD_NAME "AndroidManifest::" << UPP_FUNCTION_NAME << "(): " + namespace Upp { -AndroidManifest::AndroidManifest() +AndroidManifest::AndroidManifest(const String& path) + : path(path) { - } AndroidManifest::~AndroidManifest() { +} + +bool AndroidManifest::Parse() +{ + String xml = LoadFile(path); + if (xml.IsVoid()) { + Loge() << METHOD_NAME << "Failed to load manifest file \"" + path + "\"."; + return false; + } + try { + XmlParser p(xml); + while(!p.IsTag()) { + p.Skip(); + } + p.PassTag("manifest"); + while (!p.End()) { + if(p.TagE("uses-sdk")) { + uses_sdk.Create(); + + uses_sdk->minSdkVersion = p.Int("android:minSdkVersion"); + uses_sdk->targetSdkVersion = p.Int("android:targetSdkVersion"); + uses_sdk->maxSdkVersion = p.Int("android:maxSdkVersion"); + } + + p.Skip(); + } + } catch(const XmlError& e) { + Loge() << METHOD_NAME << "Failed to parse manifest file with error \"" + e + "\"."; + return false; + } + + return true; } } diff --git a/uppsrc/ide/Android/AndroidSDK.cpp b/uppsrc/ide/Android/AndroidSDK.cpp index af682d0d5..7de28d6b3 100644 --- a/uppsrc/ide/Android/AndroidSDK.cpp +++ b/uppsrc/ide/Android/AndroidSDK.cpp @@ -37,7 +37,7 @@ void AndroidSDK::DeducePlatform() void AndroidSDK::DeduceBuildToolsRelease() { - buildToolsRelease = FindDefaultBuildToolsRelease(); + build_tools_release = FindDefaultBuildToolsRelease(); } bool AndroidSDK::Validate() const @@ -224,7 +224,7 @@ String AndroidSDK::PlatformsDir() const String AndroidSDK::ConcreteBuildToolsDir() const { - return BuildToolsDir() + DIR_SEPS + buildToolsRelease; + return BuildToolsDir() + DIR_SEPS + build_tools_release; } String AndroidSDK::ConcretePlatformDir() const @@ -244,4 +244,9 @@ String AndroidSDK::ToolsDir() const // --------------------------------------------------------------- +bool AndroidSDK::HasD8() const +{ + return FileExists(D8Path()); +} + } diff --git a/uppsrc/ide/Builders/Android.h b/uppsrc/ide/Builders/Android.h index fda258454..64f44f169 100644 --- a/uppsrc/ide/Builders/Android.h +++ b/uppsrc/ide/Builders/Android.h @@ -20,6 +20,7 @@ public: String GetResDir() const; String GetBuildDir() const; String GetClassesDir() const; + String GetIntermediatesDir() const; String GetBinDir() const; String GetObjDir() const; String GetObjLocalDir() const; @@ -28,6 +29,8 @@ public: String GetJniMakeFilePath() const; String GetJniApplicationMakeFilePath() const; + Vector GetClassessFiles() const; + bool IsDebug() const; bool IsRelease() const; diff --git a/uppsrc/ide/Builders/AndroidBuilder.cpp b/uppsrc/ide/Builders/AndroidBuilder.cpp index 0acc736e7..64a815cc0 100644 --- a/uppsrc/ide/Builders/AndroidBuilder.cpp +++ b/uppsrc/ide/Builders/AndroidBuilder.cpp @@ -63,8 +63,6 @@ bool AndroidBuilder::BuildPackage( Index noBlitzNativeSourceFiles; - String androidManifestPath; - String javaSourcesDir = project->GetJavaDir(); String jniSourcesDir = project->GetJniDir(); String pkgJavaSourcesDir = javaSourcesDir + DIR_SEPS + package; @@ -115,16 +113,21 @@ bool AndroidBuilder::BuildPackage( } else if(BuilderUtils::IsXmlFile(filePath)) { - if(isMainPackage && fileName == "AndroidManifest.xml") { - if(androidManifestPath.GetCount()) { - PutConsole("AndroidManifest.xml is duplicated."); + if(isMainPackage && fileName == AndroidManifest::FILE_NAME) { + if (manifest) { + PutConsole("Manifest file already exists. There should be only one AndroidManifest.xml in the project."); return false; } - if(!FileCopy(filePath, project->GetManifestPath())) + if(!FileCopy(filePath, project->GetManifestPath())) { return false; + } - androidManifestPath = filePath; + manifest.Create(filePath); + if (!manifest->Parse()) { + PutConsole("Failed to parse AndroidManifest.xml."); + return false; + } } } else @@ -138,8 +141,8 @@ bool AndroidBuilder::BuildPackage( } } - if(isMainPackage && androidManifestPath.IsEmpty()) { - PutConsole("Failed to find Android manifest file."); + if(isMainPackage && !manifest) { + PutConsole("Failed to find Android manifest file in. Make sure AndroidManifest.xml is present in main package."); return false; } @@ -196,21 +199,28 @@ bool AndroidBuilder::Link( bool createmap) { InitProject(); - if(!ValidateBuilderEnviorement()) + if(!ValidateBuilderEnviorement()) { return false; + } ManageProjectCohesion(); PutConsole("Building Android Project"); - StringStream ss; - if(!GenerateRFile()) + if(!manifest) { + PutConsole("Android manifest has not been detected. Make sure your main package contains AndroidManifest.xml."); return false; - if(!RealizeLinkDirectories()) + } + if(!GenerateRFile()) { return false; + } + if(!RealizeLinkDirectories()) { + return false; + } // We need to compile java packages in this place, because we need to generate "R.java" file before... // We don't know which packages contain resources. int time; + StringStream ss; if(linkfile.GetCount()) { PutConsole("-----"); PutConsole("Compiling java sources..."); @@ -250,18 +260,8 @@ bool AndroidBuilder::Link( PutConsole("Native sources compiled in " + GetPrintTime(time) + "."); } - if(DirectoryExists(project->GetClassesDir())) { - PutConsole("-----"); - PutConsole("Creating dex file..."); - String dxCmd; - dxCmd << NormalizeExePath(sdk.DxPath()); - dxCmd << " --dex "; - dxCmd << "--output=" << project->GetBinDir() << DIR_SEPS << "classes.dex "; - dxCmd << project->GetClassesDir(); - if(Execute(dxCmd, ss) != 0) { - PutConsole(ss.GetResult()); - return false; - } + if (!GenerateDexFile()) { + return false; } PutConsole("Creating apk file..."); @@ -284,13 +284,20 @@ bool AndroidBuilder::Link( if(DirectoryExists(project->GetLibsDir())) { PutConsole("Adding native libraries to apk..."); - if(!AddSharedLibsToApk(unsignedApkPath)) + if(!AddSharedLibsToApk(unsignedApkPath)) { return false; + } } - // In release mode we definitly shouldn't signing apk!!! - if(!SignApk(target, unsignedApkPath)) + String unsignedAlignedApkPath = GetSandboxDir() + DIR_SEPS + GetFileTitle(target) + ".aligned.unsigned.apk"; + DeleteFile(unsignedAlignedApkPath); + if(!AlignApk(unsignedAlignedApkPath, unsignedApkPath)) { return false; + } + + if(!SignApk(target, unsignedAlignedApkPath)) { + return false; + } return true; } @@ -459,58 +466,53 @@ bool AndroidBuilder::RealizeLinkDirectories() const return true; } -bool AndroidBuilder::SignApk(const String& target, const String& unsignedApkPath) +bool AndroidBuilder::AlignApk(const String& target, const String& unsignedApkPath) { StringStream ss; - String signedApkPath = GetSandboxDir() + DIR_SEPS + GetFileTitle(target) + ".signed.apk"; - if(HasFlag("DEBUG")) { - String keystorePath = GetSandboxDir() + DIR_SEPS + "debug.keystore"; - if(!GenerateDebugKey(keystorePath)) - return false; - - PutConsole("Signing apk file..."); - DeleteFile(signedApkPath); - String jarsignerCmd; - jarsignerCmd << NormalizeExePath(jdk->GetJarsignerPath()); - - // Up to Java 6.0 below alogirms was by default - // (In Java 7.0 and above we need to manually specific this algorithms) - jarsignerCmd << " -sigalg SHA1withRSA"; - jarsignerCmd << " -digestalg SHA1"; - - jarsignerCmd << " -keystore " + keystorePath; - jarsignerCmd << " -storepass android"; - jarsignerCmd << " -keypass android"; - // TODO: not sure about below line. But I think for debug purpose we shouldn't use tsa. - // http://en.wikipedia.org/wiki/Trusted_timestamping - //jarsignerCmd << " -tsa https://timestamp.geotrust.com/tsa"; - jarsignerCmd << " -signedjar " << signedApkPath; - jarsignerCmd << " " << unsignedApkPath; - jarsignerCmd << " androiddebugkey"; - //PutConsole(jarsignerCmd); - if(Execute(jarsignerCmd, ss) != 0) { - PutConsole(ss.GetResult()); - return false; - } - - PutConsole("Aliging apk file..."); - DeleteFile(target); - String zipalignCmd; - zipalignCmd << NormalizeExePath(sdk.ZipalignPath()); - zipalignCmd << " -f 4 "; - zipalignCmd << (HasFlag("DEBUG") ? signedApkPath : unsignedApkPath) << " "; - zipalignCmd << target; - //PutConsole(zipalignCmd); - if(Execute(zipalignCmd, ss) != 0) { - PutConsole(ss.GetResult()); - return false; - } + PutConsole("Aliging apk file..."); + DeleteFile(target); + String zipalignCmd; + zipalignCmd << NormalizeExePath(sdk.ZipalignPath()) << " -f 4 "; + zipalignCmd << unsignedApkPath << " " << target; + if(Execute(zipalignCmd, ss) != 0) { + PutConsole(ss.GetResult()); + return false; } return true; } +bool AndroidBuilder::SignApk(const String& target, const String& unsignedApkPath) +{ + if(!HasFlag("DEBUG")) { + return false; + } + + StringStream ss; + String signedApkPath = GetSandboxDir() + DIR_SEPS + GetFileTitle(target) + ".signed.apk"; + + String keystorePath = GetSandboxDir() + DIR_SEPS + "debug.keystore"; + if(!GenerateDebugKey(keystorePath)) { + return false; + } + + PutConsole("Signing apk file..."); + DeleteFile(signedApkPath); + + String cmd; + cmd << NormalizeExePath(sdk.ApksignerPath()); + cmd << " sign --ks " << keystorePath << " --ks-pass pass:android" << " --out " << signedApkPath << " " << unsignedApkPath; + if(Execute(cmd, ss) != 0) { + PutConsole(ss.GetResult()); + return false; + } + + CopyFile(target, signedApkPath); + + return true; +} + bool AndroidBuilder::GenerateDebugKey(const String& keystorePath) { StringStream ss; @@ -536,8 +538,8 @@ bool AndroidBuilder::GenerateDebugKey(const String& keystorePath) bool AndroidBuilder::AddSharedLibsToApk(const String& apkPath) { - // TODO: A little bit workearound (I know one thing that shared libs should be in "lib" directory not in "libs") - // So, we need to create temporary lib directory with .so files :( + // TODO: Consider using environment variable NDK_LIBS_OUT form NDK r9 instead of + // creating temporary lib directory that will be deleted after inserting files to APK. const String libDir = project->GetDir() + DIR_SEPS + "lib"; Vector sharedLibsToAdd; @@ -563,16 +565,24 @@ bool AndroidBuilder::AddSharedLibsToApk(const String& apkPath) String aaptAddCmd; aaptAddCmd << NormalizeExePath(sdk.AaptPath()); aaptAddCmd << " add " << apkPath; - for(int i = 0; i < sharedLibsToAdd.GetCount(); i++) - aaptAddCmd << " " << sharedLibsToAdd[i]; - // PutConsole(aaptAddCmd); + for(int i = 0; i < sharedLibsToAdd.GetCount(); i++) { + #ifdef PLATFORM_WIN32 + // NOTE: Without conversion to UNIX directory format libraries will be added at the top + // of APK file and APK will be broken. + sharedLibsToAdd[i].Replace("\\", "/"); + #endif + aaptAddCmd << " " << sharedLibsToAdd[i] << ""; + } + StringStream ss; if(Execute(aaptAddCmd, ss) != 0) { PutConsole(ss.GetResult()); return false; } - if(!DeleteFolderDeep(libDir)) + + if(!DeleteFolderDeep(libDir)) { return false; + } return true; } @@ -619,8 +629,13 @@ void AndroidBuilder::UpdateFile(const String& path, const String& data) void AndroidBuilder::GenerateApplicationMakeFile() { + String platform; + AndroidApplicationMakeFile makeFile; - makeFile.SetPlatform(sdk.GetPlatform()); + if (manifest && manifest->uses_sdk && !IsNull(manifest->uses_sdk->minSdkVersion)) { + String platform = "android-" + IntStr(manifest->uses_sdk->minSdkVersion); + makeFile.SetPlatform(platform); + } makeFile.SetArchitectures(ndkArchitectures); makeFile.SetCppRuntime(ndkCppRuntime); makeFile.SetCppFlags(ndkCppFlags); @@ -633,6 +648,7 @@ void AndroidBuilder::GenerateApplicationMakeFile() PutVerbose("CppFlags: " + ndkCppFlags); PutVerbose("CFlags: " + ndkCFlags); PutVerbose("Toolchain: " + ndkToolchain); + PutVerbose("Platform: " + platform); UpdateFile(project->GetJniApplicationMakeFilePath(), makeFile.ToString()); } @@ -700,6 +716,79 @@ bool AndroidBuilder::GenerateRFile() return true; } +bool AndroidBuilder::GenerateDexFile() +{ + if(!DirectoryExists(project->GetClassesDir())) { + return true; + } + + PutConsole("-----"); + + if (sdk.HasD8()) { + return GenerateDexFileUsingD8(); + } + + return GenerateDexFileUsingDx(); +} + +bool AndroidBuilder::GenerateDexFileUsingD8() +{ + PutConsole("Creating dex file using d8..."); + + String cmd; + StringStream ss; + const auto outputFile = project->GetIntermediatesDir() << DIR_SEPS << "classes.jar"; + + cmd << NormalizeExePath(sdk.D8Path()); + cmd << " --output " << outputFile << " "; + auto classesFiles = project->GetClassessFiles(); + for (const auto& file : classesFiles) { + cmd << file << " "; + } + + if(Execute(cmd, ss) != 0) { + PutConsole(ss.GetResult()); + return false; + } + cmd.Clear(); + + { + // TODO: Replace with ScopeExit once it will be present in upp core.. + String currentDir = GetCurrentDirectory(); + + ChangeCurrentDirectory(project->GetBinDir()); + cmd << NormalizeExePath(jdk->GetJarPath()) << " xf " << outputFile; + if(Execute(cmd, ss) != 0) { + ChangeCurrentDirectory(currentDir); + PutConsole(ss.GetResult()); + return false; + } + ChangeCurrentDirectory(currentDir); + } + + return true; +} + +bool AndroidBuilder::GenerateDexFileUsingDx() +{ + PutConsole("Creating dex file using dx..."); + + String cmd; + StringStream ss; + + cmd << NormalizeExePath(sdk.DxPath()); + cmd << " --dex "; + cmd << "--output=" << project->GetBinDir() << DIR_SEPS << "classes.dex "; + cmd << project->GetClassesDir(); + + if(Execute(cmd, ss) != 0) { + PutConsole(ss.GetResult()); + return false; + } + + return true; +} + bool AndroidBuilder::PreprocessJava(const String& package, const String& file, const String& target) { StringStream ss; diff --git a/uppsrc/ide/Builders/AndroidBuilder.h b/uppsrc/ide/Builders/AndroidBuilder.h index 03169e564..0fc976425 100644 --- a/uppsrc/ide/Builders/AndroidBuilder.h +++ b/uppsrc/ide/Builders/AndroidBuilder.h @@ -68,11 +68,15 @@ protected: void GenerateApplicationMakeFile(); void GenerateMakeFile(); bool GenerateRFile(); + bool GenerateDexFile(); + bool GenerateDexFileUsingD8(); + bool GenerateDexFileUsingDx(); protected: bool ValidateBuilderEnviorement(); void PutErrorOnConsole(const String& msg); + bool AlignApk(const String& target, const String& unsignedApkPath); bool SignApk(const String& target, const String& unsignedApkPath); bool GenerateDebugKey(const String& keystorePath); @@ -99,6 +103,7 @@ private: One jdk; One project; One commands; + One manifest; const Workspace& wspc; diff --git a/uppsrc/ide/Builders/AndroidProject.cpp b/uppsrc/ide/Builders/AndroidProject.cpp index 916763abd..35c4423b8 100644 --- a/uppsrc/ide/Builders/AndroidProject.cpp +++ b/uppsrc/ide/Builders/AndroidProject.cpp @@ -50,7 +50,12 @@ String AndroidProject::GetBuildDir() const String AndroidProject::GetClassesDir() const { - return this->dir + DIR_SEPS + "classes"; + return GetIntermediatesDir() + DIR_SEPS + "classes"; +} + +String AndroidProject::GetIntermediatesDir() const +{ + return this->dir + DIR_SEPS + "intermediates"; } String AndroidProject::GetBinDir() const @@ -87,6 +92,37 @@ String AndroidProject::GetJniApplicationMakeFilePath() const // ------------------------------------------------------------------- +Vector AndroidProject::GetClassessFiles() const +{ + BiVector dirs = { GetClassesDir() }; + + Vector classesFiles; + while(!dirs.IsEmpty()) + { + for(FindFile ff(AppendFileName(dirs.Head(), "*")); ff; ff.Next()) { + if (ff.IsHidden() || ff.IsSymLink()) { + continue; + } + + auto path = ff.GetPath(); + if (ff.IsFolder()) { + dirs.AddTail(path); + continue; + } + + if (path.EndsWith(".class")) { + classesFiles.Add(path); + continue; + } + } + dirs.DropHead(); + } + + return classesFiles; +} + +// ------------------------------------------------------------------- + bool AndroidProject::IsDebug() const { return debug; diff --git a/uppsrc/ide/Builders/Build.cpp b/uppsrc/ide/Builders/Build.cpp index eddfa2c8a..9db633412 100644 --- a/uppsrc/ide/Builders/Build.cpp +++ b/uppsrc/ide/Builders/Build.cpp @@ -3,6 +3,8 @@ #include +#define METHOD_NAME "MakeBuild::" << UPP_FUNCTION_NAME << "(): " + #define LDUMP(x) // DUMP(x) MakeBuild::MakeBuild() @@ -124,11 +126,21 @@ void MakeBuild::CreateHost(Host& host, const String& method, bool darkmode, bool #ifdef PLATFORM_COCOA host.exedirs.Append(SplitDirs("/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin")); // sometimes some of these are missing.. #endif + + if (IsAndroidMethod(method)) { + auto jdkPath = bm.Get("JDK_PATH", ""); + if (!jdkPath.IsEmpty()) { + Cout() << "JDK Path: " << jdkPath << "\n"; + env.GetAdd("JAVA_HOME") = jdkPath; + } + } + for(int i = 0; i < env.GetCount(); i++) { LDUMP(env.GetKey(i)); LDUMP(env[i]); host.environment << env.GetKey(i) << '=' << env[i] << '\0'; } + host.environment.Cat(0); host.cmdout = &cmdout; } @@ -149,43 +161,47 @@ One MakeBuild::CreateBuilder(Host *host) if(q < 0) { PutConsole("Invalid builder " + builder); ConsoleShow(); - return NULL; + return nullptr; } Builder* b = (*BuilderMap().Get(builder))(); b->host = host; b->script = bm.Get("SCRIPT", ""); if(AndroidBuilder::GetBuildersNames().Find(builder) > -1) { - AndroidBuilder* ab = dynamic_cast(b); - ab->sdk.SetPath((bm.Get("SDK_PATH", ""))); - ab->ndk.SetPath((bm.Get("NDK_PATH", ""))); - ab->SetJdk(One(new Jdk(bm.Get("JDK_PATH", ""), host))); + AndroidBuilder* pAb = dynamic_cast(b); + if (!pAb) { + Loge() << METHOD_NAME << "Converting builder to android builder failed."; + return nullptr; + } + pAb->sdk.SetPath((bm.Get("SDK_PATH", ""))); + pAb->ndk.SetPath((bm.Get("NDK_PATH", ""))); + pAb->SetJdk(One(new Jdk(bm.Get("JDK_PATH", ""), host))); String platformVersion = bm.Get("SDK_PLATFORM_VERSION", ""); if(!platformVersion.IsEmpty()) - ab->sdk.SetPlatform(platformVersion); + pAb->sdk.SetPlatform(platformVersion); else - ab->sdk.DeducePlatform(); + pAb->sdk.DeducePlatform(); String buildToolsRelease = bm.Get("SDK_BUILD_TOOLS_RELEASE", ""); if(!buildToolsRelease.IsEmpty()) - ab->sdk.SetBuildToolsRelease(buildToolsRelease); + pAb->sdk.SetBuildToolsRelease(buildToolsRelease); else - ab->sdk.DeduceBuildToolsRelease(); + pAb->sdk.DeduceBuildToolsRelease(); - ab->ndk_blitz = bm.Get("NDK_BLITZ", "") == "1"; + pAb->ndk_blitz = bm.Get("NDK_BLITZ", "") == "1"; if(bm.Get("NDK_ARCH_ARMEABI_V7A", "") == "1") - ab->ndkArchitectures.Add("armeabi-v7a"); + pAb->ndkArchitectures.Add("armeabi-v7a"); if(bm.Get("NDK_ARCH_ARM64_V8A", "") == "1") - ab->ndkArchitectures.Add("arm64-v8a"); + pAb->ndkArchitectures.Add("arm64-v8a"); if(bm.Get("NDK_ARCH_X86", "") == "1") - ab->ndkArchitectures.Add("x86"); + pAb->ndkArchitectures.Add("x86"); if(bm.Get("NDK_ARCH_X86_64", "") == "1") - ab->ndkArchitectures.Add("x86_64"); - ab->ndkToolchain = bm.Get("NDK_TOOLCHAIN", ""); - ab->ndkCppRuntime = bm.Get("NDK_CPP_RUNTIME", ""); - ab->ndkCppFlags = bm.Get("NDK_COMMON_CPP_OPTIONS", ""); - ab->ndkCFlags = bm.Get("NDK_COMMON_C_OPTIONS", ""); + pAb->ndkArchitectures.Add("x86_64"); + pAb->ndkToolchain = bm.Get("NDK_TOOLCHAIN", ""); + pAb->ndkCppRuntime = bm.Get("NDK_CPP_RUNTIME", ""); + pAb->ndkCppFlags = bm.Get("NDK_COMMON_CPP_OPTIONS", ""); + pAb->ndkCFlags = bm.Get("NDK_COMMON_C_OPTIONS", ""); - b = ab; + b = pAb; } else { // TODO: cpp builder variables only!!! @@ -595,3 +611,21 @@ String MakeBuild::GetInvalidBuildMethodError(const String& method) { return "Invalid build method " + method + " (" + GetMethodPath(method) + ")."; } + +bool MakeBuild::IsAndroidMethod(const String& method) const +{ + VectorMap bm = GetMethodVars(method); + String builder = bm.Get("BUILDER", ""); + if (builder.IsEmpty()) { + Loge() << METHOD_NAME << "Failed to find builder."; + return false; + } + + auto pBuilder = (*BuilderMap().Get(builder))(); + if (!pBuilder) { + Loge() << METHOD_NAME << "Failed to get builder from builder map."; + return false; + } + + return AndroidBuilder::GetBuildersNames().Find(builder) > -1; +} diff --git a/uppsrc/ide/Builders/Build.h b/uppsrc/ide/Builders/Build.h index ad2f40553..456ea4c0d 100644 --- a/uppsrc/ide/Builders/Build.h +++ b/uppsrc/ide/Builders/Build.h @@ -97,6 +97,7 @@ public: private: static String GetInvalidBuildMethodError(const String& method); + bool IsAndroidMethod(const String& method) const; }; extern bool output_per_assembly; \ No newline at end of file diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index 178a3249a..8e9d3404a 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -966,7 +966,6 @@ public: void SetupAndroidMobilePlatform(Bar& bar, const AndroidSDK& androidSDK); void LaunchAndroidSDKManager(const AndroidSDK& androidSDK); void LaunchAndroidAVDManager(const AndroidSDK& androidSDK); - void LauchAndroidDeviceMonitor(const AndroidSDK& androidSDK); void AssistMenu(Bar& menu); void BrowseMenu(Bar& menu); diff --git a/uppsrc/ide/idebar.cpp b/uppsrc/ide/idebar.cpp index 30ac3cee8..9e21d4f61 100644 --- a/uppsrc/ide/idebar.cpp +++ b/uppsrc/ide/idebar.cpp @@ -425,9 +425,8 @@ void Ide::SetupMobilePlatforms(Bar& menu) void Ide::SetupAndroidMobilePlatform(Bar& menu, const AndroidSDK& androidSDK) { - menu.Add("SDK Manager", THISBACK1(LaunchAndroidSDKManager, androidSDK)); - menu.Add("AVD Manager", THISBACK1(LaunchAndroidAVDManager, androidSDK)); - menu.Add("Device monitor", THISBACK1(LauchAndroidDeviceMonitor, androidSDK)); + menu.Add("SDK Manager", [=] { LaunchAndroidSDKManager(androidSDK); }); + menu.Add("AVD Manager", [=] { LaunchAndroidAVDManager(androidSDK); }); } void Ide::ProjectRepo(Bar& menu) diff --git a/uppsrc/ide/idetool.cpp b/uppsrc/ide/idetool.cpp index 486ca9eb0..c11224514 100644 --- a/uppsrc/ide/idetool.cpp +++ b/uppsrc/ide/idetool.cpp @@ -573,21 +573,10 @@ void Ide::RemoveDs() void Ide::LaunchAndroidSDKManager(const AndroidSDK& androidSDK) { - Host host; - CreateHost(host, darkmode, disable_uhd); - IGNORE_RESULT(host.Execute(androidSDK.GetLauchSDKManagerCmd())); + PromptOK("SDK managment is not yet implemented in TheIDE. Use Android Studio for this purpose instead."); } void Ide::LaunchAndroidAVDManager(const AndroidSDK& androidSDK) { - Host host; - CreateHost(host, darkmode, disable_uhd); - IGNORE_RESULT(host.Execute(androidSDK.GetLauchAVDManagerCmd())); -} - -void Ide::LauchAndroidDeviceMonitor(const AndroidSDK& androidSDK) -{ - Host host; - CreateHost(host, darkmode, disable_uhd); - IGNORE_RESULT(host.Execute(androidSDK.MonitorPath())); + PromptOK("AVD managment is not yet implemented in TheIDE. Use Android Studio for this purpose instead."); }