aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@android.com>2011-08-24 08:19:51 -0700
committerAndroid Code Review <code-review@android.com>2011-08-24 08:19:51 -0700
commitd6ae8b852bc80b2df223e6d7218714b5ed0418d1 (patch)
tree0a4539e50975a574e65accec14af3e07639fb3f4
parent3c7d0ac7c04b31fee5dec25dfcc675181191b274 (diff)
parentbfcfa46044116a54ebe11ee2881142fd38a87939 (diff)
downloadexternal_qemu-d6ae8b852bc80b2df223e6d7218714b5ed0418d1.zip
external_qemu-d6ae8b852bc80b2df223e6d7218714b5ed0418d1.tar.gz
external_qemu-d6ae8b852bc80b2df223e6d7218714b5ed0418d1.tar.bz2
Merge "emulator: probe shared library search path"
-rw-r--r--android/main-emulator.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/android/main-emulator.c b/android/main-emulator.c
index 39e5e1e..3252053 100644
--- a/android/main-emulator.c
+++ b/android/main-emulator.c
@@ -41,8 +41,21 @@ int android_verbose;
# define D(...) do{}while(0)
#endif
+/* The extension used by dynamic libraries on the host platform */
+#ifdef _WIN32
+# define DLL_EXTENSION ".dll"
+#elif defined(__APPLE__)
+# define DLL_EXTENSION ".dylib"
+#else
+# define DLL_EXTENSION ".so"
+#endif
+
+#define GLES_EMULATION_LIB "libOpenglRender" DLL_EXTENSION
+
/* Forward declarations */
static char* getTargetEmulatorPath(const char* progName, const char* avdArch);
+static char* getSharedLibraryPath(const char* progName, const char* libName);
+static void prependSharedLibraryPath(const char* prefix);
#ifdef _WIN32
static char* quotePath(const char* path);
@@ -138,6 +151,20 @@ int main(int argc, char** argv)
}
#endif
+ /* We need to find the location of the GLES emulation shared libraries
+ * and modify either LD_LIBRARY_PATH or PATH accordingly
+ */
+ {
+ char* sharedLibPath = getSharedLibraryPath(emulatorPath, GLES_EMULATION_LIB);
+
+ if (sharedLibPath != NULL) {
+ D("Found OpenGLES emulation libraries in %s\n", sharedLibPath);
+ prependSharedLibraryPath(sharedLibPath);
+ } else {
+ D("Could not find OpenGLES emulation host libraries!\n");
+ }
+ }
+
/* Launch it with the same set of options ! */
safe_execv(emulatorPath, argv);
@@ -196,6 +223,107 @@ getTargetEmulatorPath(const char* progName, const char* avdArch)
return NULL;
}
+/* return 1 iff <path>/<filename> exists */
+static int
+probePathForFile(const char* path, const char* filename)
+{
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+ p = bufprint(temp, end, "%s/%s", path, filename);
+ D("Probing for: %s\n", temp);
+ return (p < end && path_exists(temp));
+}
+
+/* Find the directory containing a given shared library required by the
+ * emulator (for GLES emulation). We will probe several directories
+ * that correspond to various use-cases.
+ *
+ * Caller must free() result string. NULL if not found.
+ */
+
+static char*
+getSharedLibraryPath(const char* progName, const char* libName)
+{
+ char* progDir;
+ char* result = NULL;
+ char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
+
+ /* Get program's directory name */
+ path_split(progName, &progDir, NULL);
+
+ /* First, try to probe the program's directory itself, this corresponds
+ * to the standalone build with ./android-configure.sh where the script
+ * will copy the host shared library under external/qemu/objs where
+ * the binaries are located.
+ */
+ if (probePathForFile(progDir, libName)) {
+ return progDir;
+ }
+
+ /* Try under $progDir/lib/, this should correspond to the SDK installation
+ * where the binary is under tools/, and the libraries under tools/lib/
+ */
+ {
+ p = bufprint(temp, end, "%s/lib", progDir);
+ if (p < end && probePathForFile(temp, libName)) {
+ result = strdup(temp);
+ goto EXIT;
+ }
+ }
+
+ /* try in $progDir/../lib, this corresponds to the platform build
+ * where the emulator binary is under out/host/<system>/lib and
+ * the libraries are under out/host/<system>/lib
+ */
+ {
+ char* parentDir = path_parent(progDir, 1);
+
+ if (parentDir == NULL) {
+ parentDir = strdup(".");
+ }
+ p = bufprint(temp, end, "%s/lib", parentDir);
+ free(parentDir);
+ if (p < end && probePathForFile(temp, libName)) {
+ result = strdup(temp);
+ goto EXIT;
+ }
+ }
+
+ /* Nothing found! */
+EXIT:
+ free(progDir);
+ return result;
+}
+
+/* Prepend the path in 'prefix' to either LD_LIBRARY_PATH or PATH to
+ * ensure that the shared libraries inside the path will be available
+ * through dlopen() to the emulator program being launched.
+ */
+static void
+prependSharedLibraryPath(const char* prefix)
+{
+ char temp[2048], *p=temp, *end=p+sizeof(temp);
+#ifdef _WIN32
+ const char* path = getenv("PATH");
+ if (path == NULL || path[0] == '\0') {
+ p = bufprint(temp, end, "PATH=%s", prefix);
+ } else {
+ p = bufprint(temp, end, "PATH=%s;%s", prefix);
+ }
+ /* Ignore overflow, this will push some paths out of the variable, but
+ * so be it. */
+ D("Setting %s\n", temp);
+ putenv(temp);
+#else
+ const char* path = getenv("LD_LIBRARY_PATH");
+ if (path != NULL && path[0] != '\0') {
+ p = bufprint(temp, end, "%s:%s", prefix, path);
+ prefix = temp;
+ }
+ setenv("LD_LIBRARY_PATH",prefix,1);
+ D("Setting LD_LIBRARY_PATH=%s\n", prefix);
+#endif
+}
+
#ifdef _WIN32
static char*
quotePath(const char* path)