Try harder to support gtests with non-standard build config
One is able to set the location android builds to using the OUT_DIR
environment variable and android supports having this be a symlink.
Our gtests, however would fall over if you tried to run it using the
'm test-art-host-gtest' with anything other than OUT_DIR=out and out
as a real directory. If you broke this convention many tests would
fail because they are unable to find ANDROID_HOST_OUT.
This makes everything a little nicer by making common_art_test try to
figure out what ANDROID_HOST_OUT should be using the test binaries
location and commandline.
Test: export OUT_DIR=fast-out
ln -s /some/other/path fast-out
. build/envsetup.sh
lunch aosp_walleye-userdebug
m test-art-host-gtest
Change-Id: I67cdba43ef3050afe394cd03b14a43d309d020e2
diff --git a/libartbase/Android.bp b/libartbase/Android.bp
index 1611426..568689d 100644
--- a/libartbase/Android.bp
+++ b/libartbase/Android.bp
@@ -222,6 +222,12 @@
header_libs: [
"libnativehelper_header_only",
],
+ static: {
+ whole_static_libs: ["libc++fs"],
+ },
+ shared: {
+ static_libs: ["libc++fs"],
+ },
}
art_cc_test {
diff --git a/libartbase/base/common_art_test.cc b/libartbase/base/common_art_test.cc
index ccaa90f..3545916 100644
--- a/libartbase/base/common_art_test.cc
+++ b/libartbase/base/common_art_test.cc
@@ -20,7 +20,11 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <stdlib.h>
+#include <unistd.h>
#include <cstdio>
+#include <filesystem>
+#include "android-base/file.h"
+#include "android-base/logging.h"
#include "nativehelper/scoped_local_ref.h"
#include "android-base/stringprintf.h"
@@ -126,11 +130,33 @@
if (android_host_out_from_env == nullptr) {
// Not set by build server, so default to the usual value of
// ANDROID_HOST_OUT.
- std::string android_host_out = android_build_top_from_env;
+ std::string android_host_out;
#if defined(__linux__)
- android_host_out += "/out/host/linux-x86";
+ // Fallback
+ android_host_out = std::string(android_build_top_from_env) + "/out/host/linux-x86";
+ // Look at how we were invoked
+ std::string argv;
+ if (android::base::ReadFileToString("/proc/self/cmdline", &argv)) {
+ // /proc/self/cmdline is the programs 'argv' with elements delimited by '\0'.
+ std::string cmdpath(argv.substr(0, argv.find('\0')));
+ std::filesystem::path path(cmdpath);
+ // If the path is relative then prepend the android_build_top_from_env to it
+ if (path.is_relative()) {
+ path = std::filesystem::path(android_build_top_from_env).append(cmdpath);
+ DCHECK(path.is_absolute()) << path;
+ }
+ // Walk up until we find the linux-x86 directory or we hit the root directory.
+ while (path.has_parent_path() && path.parent_path() != path &&
+ path.filename() != std::filesystem::path("linux-x86")) {
+ path = path.parent_path();
+ }
+ // If we found a linux-x86 directory path is now android_host_out
+ if (path.filename() == std::filesystem::path("linux-x86")) {
+ android_host_out = path.string();
+ }
+ }
#elif defined(__APPLE__)
- android_host_out += "/out/host/darwin-x86";
+ android_host_out = std::string(android_build_top_from_env) + "/out/host/darwin-x86";
#else
#error unsupported OS
#endif