mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Build each architecture into its own APK
* This means we can have all the architectures we care about installed, and load the right library regardless of what the app does.
This commit is contained in:
+1
-7
@@ -39,8 +39,7 @@ set(BUILD_VERSION_DIST_NAME "" CACHE STRING "The name of the distribution. See D
|
||||
set(BUILD_VERSION_DIST_VER "" CACHE STRING "The distribution-specific version number. See DISTRIBUTION_VERSION in renderdoc/api/replay/version.h")
|
||||
set(BUILD_VERSION_DIST_CONTACT "" CACHE STRING "The URL or email to contact with issues. See DISTRIBUTION_CONTACT in renderdoc/api/replay/version.h")
|
||||
set(RENDERDOC_PLUGINS_PATH "" CACHE STRING "Path to RenderDoc plugins folder after installation of RenderDoc (either absolute or relative to binary)")
|
||||
set(RENDERDOC_APK_PATH "" CACHE STRING "Path to RenderDocCmd.apk after installation of RenderDoc on host (either absolute or relative to binary)")
|
||||
set(RENDERDOC_LAYER_PATH "" CACHE STRING "Path to ABI directories (i.e. lib in lib/armeabi-v7a/libVkLayer_GLES_RenderDoc.so) after installation of RenderDoc on host (either absolute or relative to dir)")
|
||||
set(RENDERDOC_APK_PATH "" CACHE STRING "Path to RenderDoc .apk files after installation of RenderDoc on host (either absolute or relative to binary)")
|
||||
|
||||
set(LIB_SUFFIX "" CACHE STRING "Suffix for 'lib' folder in target directory structure. E.g. set to '64' to use /usr/local/lib64 instead of /usr/local/lib.")
|
||||
set(LIB_SUBFOLDER "" CACHE STRING "Subfolder under the 'lib' folder in target directory structure. E.g. set to 'renderdoc' to use /usr/local/lib/renderdoc instead of /usr/local/lib.")
|
||||
@@ -82,11 +81,6 @@ if(NOT RENDERDOC_APK_PATH STREQUAL "")
|
||||
add_definitions(-DRENDERDOC_APK_PATH="${RENDERDOC_APK_PATH}")
|
||||
endif()
|
||||
|
||||
if(NOT RENDERDOC_LAYER_PATH STREQUAL "")
|
||||
message(STATUS "Detected custom path to libVkLayer_GLES_RenderDoc.so: ${RENDERDOC_LAYER_PATH}")
|
||||
add_definitions(-DRENDERDOC_LAYER_PATH="${RENDERDOC_LAYER_PATH}")
|
||||
endif()
|
||||
|
||||
function(get_git_hash _git_hash)
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
execute_process(
|
||||
|
||||
@@ -236,7 +236,7 @@ void PersistantConfig::AddAndroidHosts()
|
||||
RENDERDOC_GetAndroidFriendlyName(hostName.toUtf8().data(), friendly);
|
||||
host->friendlyName = friendly;
|
||||
// Just a command to display in the GUI and allow Launch() to be called.
|
||||
host->runCommand = lit("org.renderdoc.renderdoccmd");
|
||||
host->runCommand = lit("Automatically handled");
|
||||
RemoteHosts.push_back(host);
|
||||
}
|
||||
|
||||
|
||||
+129
-135
@@ -89,7 +89,7 @@ std::string GetDefaultActivityForPackage(const std::string &deviceID, const std:
|
||||
return "";
|
||||
}
|
||||
|
||||
int GetCurrentPid(const std::string &deviceID, const std::string &packageName)
|
||||
int GetCurrentPID(const std::string &deviceID, const std::string &packageName)
|
||||
{
|
||||
// try 5 times, 200ms apart to find the pid
|
||||
for(int i = 0; i < 5; i++)
|
||||
@@ -146,7 +146,7 @@ uint32_t StartAndroidPackageForCapture(const char *host, const char *package)
|
||||
activityName.c_str()));
|
||||
|
||||
// adb shell ps | grep $PACKAGE | awk '{print $2}')
|
||||
int pid = GetCurrentPid(deviceID, packageName);
|
||||
int pid = GetCurrentPID(deviceID, packageName);
|
||||
|
||||
adbForwardPorts(index, deviceID, jdwpPort, pid);
|
||||
|
||||
@@ -194,15 +194,17 @@ uint32_t StartAndroidPackageForCapture(const char *host, const char *package)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool installRenderDocServer(const string &deviceID)
|
||||
bool InstallRenderDocServer(const std::string &deviceID)
|
||||
{
|
||||
string targetApk = "RenderDocCmd.apk";
|
||||
string serverApk;
|
||||
std::vector<ABI> abis = GetSupportedABIs(deviceID);
|
||||
|
||||
if(abis.empty())
|
||||
return false;
|
||||
|
||||
// Check known paths for RenderDoc server
|
||||
string exePath;
|
||||
std::string exePath;
|
||||
FileIO::GetExecutableFilename(exePath);
|
||||
string exeDir = dirname(FileIO::GetFullPathname(exePath));
|
||||
std::string exeDir = dirname(FileIO::GetFullPathname(exePath));
|
||||
|
||||
std::vector<std::string> paths;
|
||||
|
||||
@@ -213,160 +215,145 @@ bool installRenderDocServer(const string &deviceID)
|
||||
if(FileIO::IsRelativePath(customPath))
|
||||
customPath = exeDir + "/" + customPath;
|
||||
|
||||
// Check to see if APK name was included in custom path
|
||||
if(!endswith(customPath, targetApk))
|
||||
{
|
||||
if(customPath.back() != '/')
|
||||
customPath += "/";
|
||||
customPath += targetApk;
|
||||
}
|
||||
if(!endswith(customPath, "/"))
|
||||
customPath += "/";
|
||||
|
||||
paths.push_back(customPath);
|
||||
#endif
|
||||
|
||||
paths.push_back(exeDir + "/android/apk/" + targetApk); // Windows install
|
||||
paths.push_back(exeDir + "/../share/renderdoc/android/apk/" + targetApk); // Linux install
|
||||
paths.push_back(exeDir + "/../../build-android/bin/" + targetApk); // Local build
|
||||
paths.push_back(exeDir + "/../../../../../build-android/bin/" + targetApk); // macOS build
|
||||
paths.push_back(exeDir + "/android/apk/"); // Windows install
|
||||
paths.push_back(exeDir + "/../share/renderdoc/android/apk/"); // Linux install
|
||||
paths.push_back(exeDir + "/../../build-android/bin/"); // Local build
|
||||
paths.push_back(exeDir + "/../../../../../build-android/bin/"); // macOS build
|
||||
|
||||
// use the first ABI for searching
|
||||
std::string apk = GetRenderDocPackageForABI(abis[0]);
|
||||
std::string apksFolder;
|
||||
|
||||
for(uint32_t i = 0; i < paths.size(); i++)
|
||||
{
|
||||
RDCLOG("Checking for server APK in %s", paths[i].c_str());
|
||||
if(FileIO::exists(paths[i].c_str()))
|
||||
|
||||
std::string apkpath = paths[i] + apk + ".apk";
|
||||
|
||||
if(FileIO::exists(apkpath.c_str()))
|
||||
{
|
||||
serverApk = paths[i];
|
||||
RDCLOG("APK found!: %s", serverApk.c_str());
|
||||
apksFolder = paths[i];
|
||||
RDCLOG("APKs found: %s", apksFolder.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(serverApk.empty())
|
||||
if(apksFolder.empty())
|
||||
{
|
||||
RDCERR(
|
||||
"%s missing! RenderDoc for Android will not work without it. "
|
||||
"APK folder missing! RenderDoc for Android will not work without it. "
|
||||
"Build your Android ABI in build-android in the root to have it "
|
||||
"automatically found and installed.",
|
||||
targetApk.c_str());
|
||||
"automatically found and installed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build a map so we can switch on the string that returns from adb calls
|
||||
enum AndroidAbis
|
||||
for(ABI abi : abis)
|
||||
{
|
||||
Android_armeabi,
|
||||
Android_armeabi_v7a,
|
||||
Android_arm64_v8a,
|
||||
Android_x86,
|
||||
Android_x86_64,
|
||||
Android_mips,
|
||||
Android_mips64,
|
||||
Android_numAbis
|
||||
};
|
||||
apk = apksFolder + GetRenderDocPackageForABI(abi) + ".apk";
|
||||
|
||||
// clang-format off
|
||||
static std::map<std::string, AndroidAbis> abi_string_map;
|
||||
abi_string_map["armeabi"] = Android_armeabi;
|
||||
abi_string_map["armeabi-v7a"] = Android_armeabi_v7a;
|
||||
abi_string_map["arm64-v8a"] = Android_arm64_v8a;
|
||||
abi_string_map["x86"] = Android_x86;
|
||||
abi_string_map["x86_64"] = Android_x86_64;
|
||||
abi_string_map["mips"] = Android_mips;
|
||||
abi_string_map["mips64"] = Android_mips64;
|
||||
// clang-format on
|
||||
if(!FileIO::exists(apk.c_str()))
|
||||
RDCWARN(
|
||||
"%s missing - ensure you build all ABIs your device can support for full compatibility",
|
||||
apk.c_str());
|
||||
|
||||
// 32-bit server works for 32 and 64 bit apps
|
||||
// For stable builds of the server, only 32-bit libs will be packaged into APK
|
||||
// For local builds, whatever was specified as single ABI will be packaged into APK
|
||||
adbExecCommand(deviceID, "install -r -g \"" + apk + "\"");
|
||||
}
|
||||
|
||||
string adbAbi = trim(adbExecCommand(deviceID, "shell getprop ro.product.cpu.abi").strStdout);
|
||||
// Ensure installation succeeded. We should have as many lines as abis we installed
|
||||
std::string adbCheck =
|
||||
adbExecCommand(deviceID, "shell pm list packages " RENDERDOC_ANDROID_PACKAGE_BASE).strStdout;
|
||||
|
||||
string adbInstall;
|
||||
switch(abi_string_map[adbAbi])
|
||||
if(adbCheck.empty())
|
||||
return false;
|
||||
|
||||
size_t lines = adbCheck.find('\n') == std::string::npos ? 1 : 2;
|
||||
|
||||
if(lines != abis.size())
|
||||
RDCWARN("Installation of some apks failed!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveRenderDocAndroidServer(const string &deviceID)
|
||||
{
|
||||
std::vector<ABI> abis = GetSupportedABIs(deviceID);
|
||||
|
||||
if(abis.empty())
|
||||
return false;
|
||||
|
||||
// remove the old package, if it's still there. Ignore any errors
|
||||
adbExecCommand(deviceID, "uninstall " RENDERDOC_ANDROID_PACKAGE_BASE);
|
||||
|
||||
for(ABI abi : abis)
|
||||
{
|
||||
case Android_armeabi_v7a:
|
||||
case Android_arm64_v8a:
|
||||
adbInstall = adbExecCommand(deviceID, "install -r -g \"" + serverApk + "\"").strStdout;
|
||||
break;
|
||||
case Android_armeabi:
|
||||
case Android_x86:
|
||||
case Android_x86_64:
|
||||
case Android_mips:
|
||||
case Android_mips64:
|
||||
default:
|
||||
std::string packageName = GetRenderDocPackageForABI(abi);
|
||||
|
||||
adbExecCommand(deviceID, "uninstall " + packageName);
|
||||
|
||||
// Ensure uninstall succeeded
|
||||
std::string adbCheck =
|
||||
adbExecCommand(deviceID, "shell pm list packages " + packageName).strStdout;
|
||||
|
||||
if(!adbCheck.empty())
|
||||
{
|
||||
RDCERR("Unsupported target ABI: %s", adbAbi.c_str());
|
||||
RDCERR("Uninstall of %s failed!", packageName.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure installation succeeded
|
||||
string adbCheck =
|
||||
adbExecCommand(deviceID, "shell pm list packages org.renderdoc.renderdoccmd").strStdout;
|
||||
if(adbCheck.empty())
|
||||
{
|
||||
RDCERR("Installation of RenderDocCmd.apk failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool RemoveRenderDocAndroidServer(const string &deviceID, const string &packageName)
|
||||
{
|
||||
adbExecCommand(deviceID, "uninstall " + packageName);
|
||||
|
||||
// Ensure uninstall succeeded
|
||||
string adbCheck = adbExecCommand(deviceID, "shell pm list packages " + packageName).strStdout;
|
||||
|
||||
if(!adbCheck.empty())
|
||||
{
|
||||
RDCERR("Uninstall of %s failed!", packageName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CheckAndroidServerVersion(const string &deviceID)
|
||||
{
|
||||
string packageName = "org.renderdoc.renderdoccmd";
|
||||
std::vector<ABI> abis = GetSupportedABIs(deviceID);
|
||||
|
||||
if(abis.empty())
|
||||
return false;
|
||||
|
||||
// assume all servers are updated at the same rate. Only check first ABI's version
|
||||
std::string packageName = GetRenderDocPackageForABI(abis[0]);
|
||||
RDCLOG("Checking installed version of %s on %s", packageName.c_str(), deviceID.c_str());
|
||||
|
||||
string dump = adbExecCommand(deviceID, "shell pm dump " + packageName).strStdout;
|
||||
std::string dump = adbExecCommand(deviceID, "shell pm dump " + packageName).strStdout;
|
||||
if(dump.empty())
|
||||
RDCERR("Unable to pm dump %s", packageName.c_str());
|
||||
|
||||
// Walk through the output and look for versionCode and versionName
|
||||
std::istringstream contents(dump);
|
||||
string line;
|
||||
string versionCode;
|
||||
string versionName;
|
||||
string prefix1("versionCode=");
|
||||
string prefix2("versionName=");
|
||||
while(std::getline(contents, line))
|
||||
std::string versionCode = trim(GetFirstMatchingLine(dump, "versionCode="));
|
||||
std::string versionName = trim(GetFirstMatchingLine(dump, "versionName="));
|
||||
|
||||
// versionCode is not alone in this line, isolate it
|
||||
if(versionCode != "")
|
||||
{
|
||||
line = trim(line);
|
||||
if(line.compare(0, prefix1.size(), prefix1) == 0)
|
||||
{
|
||||
// versionCode is not alone in this line, isolate it
|
||||
std::vector<string> vec;
|
||||
split(line, vec, ' ');
|
||||
versionCode = vec[0].substr(vec[0].find_last_of("=") + 1);
|
||||
}
|
||||
if(line.compare(0, prefix2.size(), prefix2) == 0)
|
||||
{
|
||||
versionName = line.substr(line.find_first_of("=") + 1);
|
||||
}
|
||||
size_t spaceOffset = versionCode.find(' ');
|
||||
versionCode.erase(spaceOffset);
|
||||
|
||||
versionCode.erase(0, strlen("versionCode="));
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unable to determine versionCode for: %s", packageName.c_str());
|
||||
}
|
||||
|
||||
if(versionCode.empty())
|
||||
RDCERR("Unable to determine versionCode for: %s", packageName.c_str());
|
||||
|
||||
if(versionName.empty())
|
||||
if(versionName != "")
|
||||
{
|
||||
versionName.erase(0, strlen("versionName="));
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unable to determine versionName for: %s", packageName.c_str());
|
||||
}
|
||||
|
||||
// Compare the server's versionCode and versionName with the host's for compatibility
|
||||
string hostVersionCode =
|
||||
std::string hostVersionCode =
|
||||
string(STRINGIZE(RENDERDOC_VERSION_MAJOR)) + string(STRINGIZE(RENDERDOC_VERSION_MINOR));
|
||||
string hostVersionName = RENDERDOC_STABLE_BUILD ? MAJOR_MINOR_VERSION_STRING : GitVersionHash;
|
||||
std::string hostVersionName = RENDERDOC_STABLE_BUILD ? MAJOR_MINOR_VERSION_STRING : GitVersionHash;
|
||||
|
||||
// False positives will hurt us, so check for explicit matches
|
||||
if((hostVersionCode == versionCode) && (hostVersionName == versionName))
|
||||
@@ -379,14 +366,12 @@ bool CheckAndroidServerVersion(const string &deviceID)
|
||||
RDCWARN("RenderDoc server versionCode:versionName (%s:%s) is incompatible with host (%s:%s)",
|
||||
versionCode.c_str(), versionName.c_str(), hostVersionCode.c_str(), hostVersionName.c_str());
|
||||
|
||||
if(RemoveRenderDocAndroidServer(deviceID, packageName))
|
||||
if(RemoveRenderDocAndroidServer(deviceID))
|
||||
RDCLOG("Uninstall of incompatible server succeeded");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}; // namespace Android
|
||||
using namespace Android;
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetAndroidFriendlyName(const rdcstr &device,
|
||||
rdcstr &friendly)
|
||||
@@ -412,17 +397,17 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetAndroidFriendlyName(cons
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdcstr *deviceList)
|
||||
{
|
||||
string adbStdout = adbExecCommand("", "devices").strStdout;
|
||||
std::string adbStdout = Android::adbExecCommand("", "devices").strStdout;
|
||||
|
||||
int idx = 0;
|
||||
|
||||
using namespace std;
|
||||
istringstream stdoutStream(adbStdout);
|
||||
string ret;
|
||||
string line;
|
||||
while(getline(stdoutStream, line))
|
||||
std::string ret;
|
||||
|
||||
std::vector<std::string> lines;
|
||||
split(adbStdout, lines, '\n');
|
||||
for(const std::string &line : lines)
|
||||
{
|
||||
vector<string> tokens;
|
||||
std::vector<std::string> tokens;
|
||||
split(line, tokens, '\t');
|
||||
if(tokens.size() == 2 && trim(tokens[1]) == "device")
|
||||
{
|
||||
@@ -432,7 +417,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdc
|
||||
ret += StringFormat::Fmt("adb:%d:%s", idx, tokens[0].c_str());
|
||||
|
||||
// Forward the ports so we can see if a remoteserver/captured app is already running.
|
||||
adbForwardPorts(idx, tokens[0], 0, 0);
|
||||
Android::adbForwardPorts(idx, tokens[0], 0, 0);
|
||||
|
||||
idx++;
|
||||
}
|
||||
@@ -448,20 +433,29 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartAndroidRemoteServer(co
|
||||
|
||||
Android::ExtractDeviceIDAndIndex(device, index, deviceID);
|
||||
|
||||
string adbPackage =
|
||||
adbExecCommand(deviceID, "shell pm list packages org.renderdoc.renderdoccmd").strStdout;
|
||||
std::string packages =
|
||||
Android::adbExecCommand(deviceID, "shell pm list packages " RENDERDOC_ANDROID_PACKAGE_BASE).strStdout;
|
||||
|
||||
if(adbPackage.empty() || !CheckAndroidServerVersion(deviceID))
|
||||
if(packages.empty() || !Android::CheckAndroidServerVersion(deviceID))
|
||||
{
|
||||
// If server is not detected or has been removed due to incompatibility, install it
|
||||
if(!installRenderDocServer(deviceID))
|
||||
if(!Android::InstallRenderDocServer(deviceID))
|
||||
return;
|
||||
}
|
||||
|
||||
adbExecCommand(deviceID, "shell am force-stop org.renderdoc.renderdoccmd");
|
||||
adbForwardPorts(index, deviceID, 0, 0);
|
||||
adbExecCommand(deviceID, "shell setprop debug.vulkan.layers :");
|
||||
adbExecCommand(
|
||||
deviceID,
|
||||
"shell am start -n org.renderdoc.renderdoccmd/.Loader -e renderdoccmd remoteserver");
|
||||
// stop all servers of any ABI
|
||||
std::vector<Android::ABI> abis = Android::GetSupportedABIs(deviceID);
|
||||
|
||||
for(Android::ABI abi : abis)
|
||||
Android::adbExecCommand(deviceID, "shell am force-stop " + GetRenderDocPackageForABI(abi));
|
||||
|
||||
if(abis.empty())
|
||||
return;
|
||||
|
||||
Android::adbForwardPorts(index, deviceID, 0, 0);
|
||||
Android::adbExecCommand(deviceID, "shell setprop debug.vulkan.layers :");
|
||||
|
||||
// launch the first ABI, as the default 'most compatible' package
|
||||
Android::adbExecCommand(deviceID, "shell am start -n " + GetRenderDocPackageForABI(abis[0]) +
|
||||
"/.Loader -e renderdoccmd remoteserver");
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include <sstream>
|
||||
#include "api/replay/version.h"
|
||||
#include "core/core.h"
|
||||
#include "strings/string_utils.h"
|
||||
#include "android_utils.h"
|
||||
@@ -363,25 +364,36 @@ bool HasRootAccess(const std::string &deviceID)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetFirstMatchingLine(const std::string &haystack, const std::string &needle)
|
||||
{
|
||||
size_t needleOffset = haystack.find(needle);
|
||||
|
||||
if(needleOffset == std::string::npos)
|
||||
{
|
||||
RDCERR("Couldn't get pkgFlags from adb");
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t nextLine = haystack.find('\n', needleOffset + 1);
|
||||
|
||||
return haystack.substr(needleOffset,
|
||||
nextLine == std::string::npos ? nextLine : nextLine - needleOffset);
|
||||
}
|
||||
|
||||
bool IsDebuggable(const std::string &deviceID, const std::string &packageName)
|
||||
{
|
||||
RDCLOG("Checking that APK is debuggable");
|
||||
|
||||
std::string info = adbExecCommand(deviceID, "shell dumpsys package " + packageName).strStdout;
|
||||
|
||||
size_t flagsOffset = info.find("pkgFlags=[");
|
||||
std::string pkgFlags = GetFirstMatchingLine(info, "pkgFlags=[");
|
||||
|
||||
if(flagsOffset == std::string::npos)
|
||||
if(pkgFlags == "")
|
||||
{
|
||||
RDCERR("Couldn't get pkgFlags from adb");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t nextLine = info.find('\n', flagsOffset + 1);
|
||||
|
||||
std::string pkgFlags =
|
||||
info.substr(flagsOffset, nextLine == std::string::npos ? nextLine : nextLine - flagsOffset);
|
||||
|
||||
return pkgFlags.find("DEBUGGABLE") != std::string::npos;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,6 +58,54 @@ void ExtractDeviceIDAndIndex(const std::string &hostname, int &index, std::strin
|
||||
deviceID = c;
|
||||
}
|
||||
|
||||
ABI GetABI(const std::string &abiName)
|
||||
{
|
||||
if(abiName == "armeabi-v7a")
|
||||
return ABI::armeabi_v7a;
|
||||
else if(abiName == "arm64-v8a")
|
||||
return ABI::arm64_v8a;
|
||||
else if(abiName == "x86-v7a")
|
||||
return ABI::x86;
|
||||
else if(abiName == "x86_64")
|
||||
return ABI::x86_64;
|
||||
|
||||
RDCWARN("Unknown or unsupported ABI %s", abiName.c_str());
|
||||
|
||||
return ABI::unknown;
|
||||
}
|
||||
|
||||
std::vector<ABI> GetSupportedABIs(const std::string &deviceID)
|
||||
{
|
||||
std::string adbAbi = trim(adbExecCommand(deviceID, "shell getprop ro.product.cpu.abi").strStdout);
|
||||
|
||||
// these returned lists should be such that the first entry is the 'lowest command denominator' -
|
||||
// typically 32-bit.
|
||||
switch(GetABI(adbAbi))
|
||||
{
|
||||
case ABI::arm64_v8a: return {ABI::armeabi_v7a, ABI::arm64_v8a};
|
||||
case ABI::armeabi_v7a: return {ABI::armeabi_v7a};
|
||||
case ABI::x86_64: return {ABI::x86, ABI::x86_64};
|
||||
case ABI::x86: return {ABI::x86};
|
||||
default: break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string GetRenderDocPackageForABI(ABI abi)
|
||||
{
|
||||
switch(abi)
|
||||
{
|
||||
case ABI::arm64_v8a: return RENDERDOC_ANDROID_PACKAGE_BASE ".arm64";
|
||||
case ABI::armeabi_v7a: return RENDERDOC_ANDROID_PACKAGE_BASE ".arm32";
|
||||
case ABI::x86_64: return RENDERDOC_ANDROID_PACKAGE_BASE ".x64";
|
||||
case ABI::x86: return RENDERDOC_ANDROID_PACKAGE_BASE ".x86";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return RENDERDOC_ANDROID_PACKAGE_BASE ".unknown";
|
||||
}
|
||||
|
||||
std::string GetPathForPackage(const std::string &deviceID, const std::string &packageName)
|
||||
{
|
||||
std::string pkgPath = trim(adbExecCommand(deviceID, "shell pm path " + packageName).strStdout);
|
||||
|
||||
@@ -47,5 +47,22 @@ enum class ToolDir
|
||||
std::string getToolPath(ToolDir subdir, const std::string &toolname, bool checkExist);
|
||||
bool toolExists(const std::string &path);
|
||||
|
||||
std::string GetFirstMatchingLine(const std::string &haystack, const std::string &needle);
|
||||
|
||||
std::string GetFriendlyName(std::string deviceID);
|
||||
|
||||
// supported ABIs
|
||||
enum class ABI
|
||||
{
|
||||
unknown,
|
||||
armeabi_v7a,
|
||||
arm64_v8a,
|
||||
x86,
|
||||
x86_64,
|
||||
};
|
||||
|
||||
ABI GetABI(const std::string &abiName);
|
||||
std::vector<ABI> GetSupportedABIs(const std::string &deviceID);
|
||||
std::string GetRenderDocPackageForABI(ABI abi);
|
||||
std::string GetPathForPackage(const std::string &deviceID, const std::string &packageName);
|
||||
};
|
||||
|
||||
+17
-19
@@ -27,6 +27,7 @@
|
||||
#include "core/core.h"
|
||||
#include "strings/string_utils.h"
|
||||
#include "android.h"
|
||||
#include "android_utils.h"
|
||||
|
||||
namespace JDWP
|
||||
{
|
||||
@@ -95,7 +96,7 @@ void InjectVulkanLayerSearchPath(Connection &conn, threadID thread, int32_t slot
|
||||
conn.SetLocalValue(thread, stack[0].id, slotIdx, temp);
|
||||
}
|
||||
|
||||
bool InjectLibraries(Network::Socket *sock, std::string libPath)
|
||||
bool InjectLibraries(const std::string &deviceID, Network::Socket *sock)
|
||||
{
|
||||
Connection conn(sock);
|
||||
|
||||
@@ -112,7 +113,7 @@ bool InjectLibraries(Network::Socket *sock, std::string libPath)
|
||||
return false;
|
||||
|
||||
// default to arm as a safe bet
|
||||
std::string abi = "armeabi-v7a";
|
||||
Android::ABI abi = Android::ABI::armeabi_v7a;
|
||||
|
||||
// determine the CPU ABI from android.os.Build.CPU_ABI
|
||||
referenceTypeID buildClass = conn.GetType("Landroid/os/Build;");
|
||||
@@ -125,7 +126,7 @@ bool InjectLibraries(Network::Socket *sock, std::string libPath)
|
||||
value val = conn.GetFieldValue(buildClass, CPU_ABI);
|
||||
|
||||
if(val.tag == Tag::String)
|
||||
abi = conn.GetString(val.String);
|
||||
abi = Android::GetABI(conn.GetString(val.String));
|
||||
else
|
||||
RDCERR("CPU_ABI value was type %u, not string!", (uint32_t)val.tag);
|
||||
}
|
||||
@@ -139,19 +140,21 @@ bool InjectLibraries(Network::Socket *sock, std::string libPath)
|
||||
RDCERR("Couldn't find android.os.Build");
|
||||
}
|
||||
|
||||
// use the ABI to determine where to find our library
|
||||
if(abi == "armeabi-v7a")
|
||||
if(abi == Android::ABI::unknown)
|
||||
{
|
||||
libPath += "arm";
|
||||
RDCERR("Unrecognised running ABI, falling back to armeabi-v7a");
|
||||
abi = Android::ABI::armeabi_v7a;
|
||||
}
|
||||
else if(abi == "arm64-v8a")
|
||||
|
||||
std::string libPath = Android::GetPathForPackage(deviceID, Android::GetRenderDocPackageForABI(abi));
|
||||
|
||||
switch(abi)
|
||||
{
|
||||
libPath += "arm64";
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unhandled ABI '%s'", abi.c_str());
|
||||
return false;
|
||||
case Android::ABI::unknown:
|
||||
case Android::ABI::armeabi_v7a: libPath += "lib/arm"; break;
|
||||
case Android::ABI::arm64_v8a: libPath += "lib/arm64"; break;
|
||||
case Android::ABI::x86_64: libPath += "lib/x86_64"; break;
|
||||
case Android::ABI::x86: libPath += "lib/x86"; break;
|
||||
}
|
||||
|
||||
if(conn.IsErrored())
|
||||
@@ -386,12 +389,7 @@ bool InjectWithJDWP(const std::string &deviceID, uint16_t jdwpport)
|
||||
|
||||
if(sock)
|
||||
{
|
||||
std::string apk = adbExecCommand(deviceID, "shell pm path org.renderdoc.renderdoccmd").strStdout;
|
||||
apk = trim(apk);
|
||||
apk.resize(apk.size() - 8);
|
||||
apk.erase(0, 8);
|
||||
|
||||
bool ret = JDWP::InjectLibraries(sock, apk + "lib/");
|
||||
bool ret = JDWP::InjectLibraries(deviceID, sock);
|
||||
delete sock;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -130,6 +130,9 @@ enum
|
||||
|
||||
#define RENDERDOC_ANDROID_LIBRARY "libVkLayer_GLES_RenderDoc.so"
|
||||
|
||||
// This MUST match the package name in the build process that generates per-architecture packages
|
||||
#define RENDERDOC_ANDROID_PACKAGE_BASE "org.renderdoc.renderdoccmd"
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Debugging features configuration
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ string GetAppFolderFilename(const string &filename)
|
||||
return GetTempRootPath() + string("/") + filename;
|
||||
}
|
||||
|
||||
// For RenderDocCmd.apk, this returns "org.renderdoc.renderdoccmd"
|
||||
// For RenderDoc's apk, this returns our package name
|
||||
// For other APKs, we use it to get the writable temp directory.
|
||||
void GetExecutableFilename(string &selfName)
|
||||
{
|
||||
|
||||
@@ -102,17 +102,29 @@ if(ANDROID)
|
||||
endif()
|
||||
message(STATUS "Building APK versionCode ${APK_VERSION_CODE}, versionName ${APK_VERSION_NAME}")
|
||||
|
||||
# Set the package name based on the ABI
|
||||
if(ANDROID_ABI STREQUAL "armeabi-v7a")
|
||||
set(RENDERDOC_ANDROID_PACKAGE_NAME "org.renderdoc.renderdoccmd.arm32")
|
||||
elseif(ANDROID_ABI STREQUAL "arm64-v8a")
|
||||
set(RENDERDOC_ANDROID_PACKAGE_NAME "org.renderdoc.renderdoccmd.arm64")
|
||||
else()
|
||||
message(FATAL_ERROR "ABI ${ANDROID_ABI} is not supported.")
|
||||
endif()
|
||||
|
||||
set(APK_FILE ${CMAKE_BINARY_DIR}/bin/RenderDocCmd.apk)
|
||||
set(APK_FILE ${CMAKE_BINARY_DIR}/bin/${RENDERDOC_ANDROID_PACKAGE_NAME}.apk)
|
||||
add_custom_target(apk ALL
|
||||
DEPENDS ${APK_FILE}
|
||||
DEPENDS ${KEYSTORE})
|
||||
|
||||
# Copy in android package files, replacing the package name with the architecture-specific package name
|
||||
configure_file(android/Loader.java ${CMAKE_CURRENT_BINARY_DIR}/src/org/renderdoc/renderdoccmd/Loader.java)
|
||||
configure_file(android/AndroidManifest.xml ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml)
|
||||
configure_file(android/icon.png ${CMAKE_CURRENT_BINARY_DIR}/res/drawable/icon.png COPYONLY)
|
||||
|
||||
add_custom_command(OUTPUT ${APK_FILE}
|
||||
DEPENDS renderdoc
|
||||
DEPENDS renderdoccmd
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/android ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory libs/lib/${ANDROID_ABI}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory obj
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory bin
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- BEGIN_INCLUDE(manifest) -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.renderdoc.renderdoccmd">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="@RENDERDOC_ANDROID_PACKAGE_NAME@">
|
||||
|
||||
<!-- This is the platform API where NativeActivity was introduced. -->
|
||||
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23"/>
|
||||
@@ -11,7 +11,7 @@
|
||||
<!-- Use GL ES 3.2 version -->
|
||||
<uses-feature android:glEsVersion="0x00030002" android:required="true" />
|
||||
|
||||
<application android:label="RenderDocCmd" android:icon="@drawable/icon" android:hasCode="true">
|
||||
<application android:debuggable="true" android:label="RenderDocCmd" android:icon="@drawable/icon" android:hasCode="true">
|
||||
<activity android:name=".Loader" android:label="RenderDoc" android:exported="true" android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden">
|
||||
<meta-data android:name="android.app.lib_name" android:value="renderdoccmd"/>
|
||||
</activity>
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package org.renderdoc.renderdoccmd;
|
||||
package @RENDERDOC_ANDROID_PACKAGE_NAME@;
|
||||
import android.app.Activity;
|
||||
|
||||
public class Loader extends android.app.NativeActivity
|
||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
+3
-26
@@ -51,32 +51,9 @@ cp -R plugins-win32/ dist/Release32/plugins
|
||||
find dist/Release{32,64}/ -iname '*.ipdb' -exec rm '{}' \;
|
||||
find dist/Release{32,64}/ -iname '*.iobj' -exec rm '{}' \;
|
||||
|
||||
ANDROID32="bin-android32"
|
||||
if [ -f build-android32/bin/RenderDocCmd.apk ]; then
|
||||
ANDROID32="build-android32/bin";
|
||||
fi
|
||||
|
||||
ANDROID64="bin-android64"
|
||||
if [ -f build-android64/bin/RenderDocCmd.apk ]; then
|
||||
ANDROID64="build-android64/bin";
|
||||
fi
|
||||
|
||||
if [ -f $ANDROID32/RenderDocCmd.apk ]; then
|
||||
# Building for android, copy the apk and vulkan layer into folders
|
||||
mkdir -p dist/Release64/android/apk dist/Release64/android/lib/armeabi-v7a
|
||||
|
||||
cp $ANDROID32/RenderDocCmd.apk dist/Release64/android/apk
|
||||
cp $ANDROID32/libVkLayer_GLES_RenderDoc.so dist/Release64/android/lib/armeabi-v7a/libVkLayer_GLES_RenderDoc.so
|
||||
fi
|
||||
|
||||
if [ -f $ANDROID64/RenderDocCmd.apk ]; then
|
||||
# Building for android, copy the vulkan layer into folder
|
||||
mkdir -p dist/Release64/android/lib/arm64-v8a
|
||||
|
||||
# We don't distribute the 64-bit apk, we use armeabi-v7a for both 32-bit and 64-bit
|
||||
#cp $ANDROID64/RenderDocCmd.apk dist/Release64/android/apk/64
|
||||
cp $ANDROID64/libVkLayer_GLES_RenderDoc.so dist/Release64/android/lib/arm64-v8a/libVkLayer_GLES_RenderDoc.so
|
||||
fi
|
||||
# Copy in any android APKs that were built
|
||||
mkdir -p dist/Release64/android/apk
|
||||
find build-android-* -iname 'org.renderdoc.renderdoccmd.*.apk' -exec cp '{}' dist/Release64/android/apk ';'
|
||||
|
||||
# try to copy adb.exe in as well, with its dll dependencies
|
||||
if [ -f $ANDROID_SDK/platform-tools/adb.exe ] && [ -d dist/Release64/android ]; then
|
||||
|
||||
Reference in New Issue
Block a user