From a83d877bd520d14bd8cbaf3df9d083cfe69c7026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20R=C4=99bacz?= Date: Sun, 4 Dec 2022 18:24:34 +0100 Subject: [PATCH] IDE: Android Builder update to 2022 stack (#116) Android Builder was modernized to the latest Google stacks. It is compatible with latest build tools version (33) and android (13). The following PR covers: - Migration from deprecated DX to D8 - Migrate from deprecated jarsigner to apksigner - Android Builder works now for both POSIX and Windows - There is no possibility to lunch SDK and AVD managers, the tools that we spawned previously are deprecated. We will need to write our own wrappers for console tools if we want to support that. - Android Builder now parsers AndroidManifest.xml file and informs Android NDK project about minAndroidSdk version from this file. This helps to avoid warnings in the build process. --- examples/AndroidMath/AndroidManifest.xml | 1 + uppsrc/ide/Android/Android.h | 34 +++- uppsrc/ide/Android/AndroidManifest.cpp | 38 +++- uppsrc/ide/Android/AndroidSDK.cpp | 9 +- uppsrc/ide/Builders/Android.h | 3 + uppsrc/ide/Builders/AndroidBuilder.cpp | 247 +++++++++++++++-------- uppsrc/ide/Builders/AndroidBuilder.h | 5 + uppsrc/ide/Builders/AndroidProject.cpp | 38 +++- uppsrc/ide/Builders/Build.cpp | 72 +++++-- uppsrc/ide/Builders/Build.h | 1 + uppsrc/ide/ide.h | 1 - uppsrc/ide/idebar.cpp | 5 +- uppsrc/ide/idetool.cpp | 15 +- 13 files changed, 339 insertions(+), 130 deletions(-) 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."); }