This commit is contained in:
Mirek Fidler 2022-12-05 10:01:00 +01:00
commit 28b61e9465
15 changed files with 342 additions and 132 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

@ -214,7 +214,7 @@ void UWord::Pdf()
void UWord::About()
{
PromptOK("[A5 uWord]&Using [*^www://upp.sf.net^ Ultimate`+`+] technology.");
PromptOK("[A5 uWord]&Using [*^www://upp.sf.net^ U`+`+] technology.");
}
void UWord::Destroy()

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

View file

@ -30,7 +30,8 @@ public class <:PACKAGE:> extends Activity
@@AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.upp.<:PACKAGE:>"><:?permissionInternet:>
package="org.upp.<:PACKAGE:>">
<uses-sdk android:minSdkVersion="21" /><:?permissionInternet:>
<uses-permission android:name="android.permission.INTERNET" /><:.:>
<application>
<activity android:name=".<:PACKAGE:>"