#include "Android.h" namespace Upp { static const String TOOLCHAIN_CLANG = "clang"; String AndroidNDK::GetDownloadUrl() { return "https://developer.android.com/ndk/downloads/index.html"; } AndroidNDK::AndroidNDK() { } AndroidNDK::AndroidNDK(const String& path) { this->path = path; } AndroidNDK::~AndroidNDK() { } bool AndroidNDK::Validate() const { if(!DirectoryExists(path) || !FileExists(GetNdkBuildPath())) return false; return true; } String AndroidNDK::FindDefaultPlatform() const { Vector platforms = FindPlatforms(); Android::NormalizeVersions(platforms); Sort(platforms, StdGreater()); Android::RemoveVersionsNormalization(platforms); return !platforms.IsEmpty() ? platforms[0] : String(); } String AndroidNDK::FindDefaultToolchain() const { Index toolchains(FindToolchains()); int clangIdx = toolchains.Find(TOOLCHAIN_CLANG); if (clangIdx >= 0) { return toolchains[clangIdx]; } SortIndex(toolchains, StdGreater()); return !toolchains.IsEmpty() ? toolchains[toolchains.GetCount()] : String(); } String AndroidNDK::FindDefaultCppRuntime() const { return "c++_shared"; } Vector AndroidNDK::FindPlatforms() const { Vector platforms; for(FindFile ff(AppendFileName(GetPlatformsDir(), "*")); ff; ff.Next()) { if(!ff.IsHidden() && ff.IsFolder()) platforms.Add(ff.GetName()); } return platforms; } Vector AndroidNDK::FindToolchains() const { Vector toolchains; for(FindFile ff(AppendFileName(GetToolchainsDir(), "*")); ff; ff.Next()) { if(!ff.IsHidden() && ff.IsFolder()) { String name = ff.GetName(); if(name.StartsWith("llvm")) { toolchains.Add(TOOLCHAIN_CLANG); continue; } Vector nameParts = Split(name, "-"); if(nameParts.GetCount() > 1) { String toolchain = nameParts[nameParts.GetCount() - 1]; if(FindIndex(toolchains, toolchain) == -1) toolchains.Add(toolchain); } } } return toolchains; } Vector AndroidNDK::FindCppRuntimes() const { Vector runtimes; // Values from NDK documentation runtimes.Add("c++_static"); runtimes.Add("c++_shared"); runtimes.Add("system"); runtimes.Add("none"); return runtimes; } String AndroidNDK::GetIncludeDir() const { String dir; dir << GetPlatformsDir() << DIR_SEPS << FindDefaultPlatform() << DIR_SEPS; // TODO: decide how to implement architecture selection. dir << "arch-arm" << DIR_SEPS; dir << "usr" << DIR_SEPS << "include"; return DirectoryExists(dir) ? dir : String(); } String AndroidNDK::GetCppIncludeDir(const String& cppRuntime) const { String nest = GetSourcesDir() + DIR_SEPS + "cxx-stl" + DIR_SEPS; if(cppRuntime == "system") { return nest + "system" + DIR_SEPS + "include"; } else if(cppRuntime.StartsWith("c++")) { return nest + "llvm-libc++" + DIR_SEPS + "include"; } return ""; } }