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.
This commit is contained in:
Zbigniew Rębacz 2022-12-04 18:24:34 +01:00 committed by GitHub
parent 4c6cdaf417
commit a83d877bd5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 339 additions and 130 deletions

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.upp.AndroidMath">
<uses-sdk android:minSdkVersion="21" />
<application
android:allowBackup="true">
<activity android:name=".AndroidMathActivity"

View file

@ -65,32 +65,31 @@ public:
String PlatformToolsDir() const;
String ToolsDir() const;
bool HasD8() const;
String AaptPath() const { return ConcreteBuildToolsDir() + DIR_SEPS + "aapt" + GetExeExt(); }
String ApksignerPath() const { return ConcreteBuildToolsDir() + DIR_SEPS + "apksigner" + Android::GetScriptExt(); }
String DxPath() const { return ConcreteBuildToolsDir() + DIR_SEPS + "dx" + Android::GetScriptExt(); }
String D8Path() const { return ConcreteBuildToolsDir() + DIR_SEPS + "d8" + Android::GetScriptExt(); }
String ZipalignPath() const { return ConcreteBuildToolsDir() + DIR_SEPS + "zipalign" + GetExeExt(); }
String AndroidJarPath() const { return ConcretePlatformDir() + DIR_SEPS + "android.jar"; }
String AdbPath() const { return PlatformToolsDir() + DIR_SEPS + "adb" + GetExeExt(); }
String AndroidPath() const { return ToolsDir() + DIR_SEPS + "android" + Android::GetScriptExt(); }
String EmulatorPath() const { return ToolsDir() + DIR_SEPS + "emulator" + GetExeExt(); }
String MonitorPath() const { return ToolsDir() + DIR_SEPS + "monitor" + Android::GetScriptExt(); }
public:
String GetLauchSDKManagerCmd() const { return NormalizeExePath(AndroidPath()) + " sdk"; }
String GetLauchAVDManagerCmd() const { return NormalizeExePath(AndroidPath()) + " avd"; }
public:
String GetPath() const { return this->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<UsesSdk> uses_sdk;
private:
String path;
};
}

View file

@ -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;
}
}

View file

@ -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());
}
}

View file

@ -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<String> GetClassessFiles() const;
bool IsDebug() const;
bool IsRelease() const;

View file

@ -63,8 +63,6 @@ bool AndroidBuilder::BuildPackage(
Index<String> 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<String> 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;

View file

@ -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> jdk;
One<AndroidProject> project;
One<AndroidBuilderCommands> commands;
One<AndroidManifest> manifest;
const Workspace& wspc;

View file

@ -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<String> AndroidProject::GetClassessFiles() const
{
BiVector<String> dirs = { GetClassesDir() };
Vector<String> 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;

View file

@ -3,6 +3,8 @@
#include <plugin/bz2/bz2.h>
#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<Builder> 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<AndroidBuilder*>(b);
ab->sdk.SetPath((bm.Get("SDK_PATH", "")));
ab->ndk.SetPath((bm.Get("NDK_PATH", "")));
ab->SetJdk(One<Jdk>(new Jdk(bm.Get("JDK_PATH", ""), host)));
AndroidBuilder* pAb = dynamic_cast<AndroidBuilder*>(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<Jdk>(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<String, String> 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;
}

View file

@ -97,6 +97,7 @@ public:
private:
static String GetInvalidBuildMethodError(const String& method);
bool IsAndroidMethod(const String& method) const;
};
extern bool output_per_assembly;

View file

@ -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);

View file

@ -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)

View file

@ -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.");
}