Browse Source

load_dso now uses a plugin search path

Josh Yelon 18 years ago
parent
commit
08dcdade5c

+ 52 - 12
dtool/src/dtoolutil/load_dso.cxx

@@ -18,6 +18,21 @@
 
 #include "load_dso.h"
 
+static Filename resolve_dso(const DSearchPath &path, const Filename &filename) {
+  if (filename.is_local()) {
+    if (path.is_empty()||
+        ((path.get_num_directories()==1)&&(path.get_directory(0)=="."))) {
+      Filename dtoolpath = ExecutionEnvironment::get_dtool_name();
+      DSearchPath spath(dtoolpath.get_dirname());
+      return spath.find_file(filename);
+    } else {
+      return path.find_file(filename);
+    }
+  } else {
+    return filename;
+  }
+}
+
 #if defined(WIN32)
 /* begin Win32-specific code */
 
@@ -25,9 +40,30 @@
 #include <windows.h>
 #undef WINDOWS_LEAN_AND_MEAN
 
+// Loads in a dynamic library like an .so or .dll.  Returns NULL if
+// failure, otherwise on success.  If the filename is not absolute,
+// searches the path.  If the path is empty, searches the dtool
+// directory.
+
 void *
-load_dso(const Filename &filename) {
-  string os_specific = filename.to_os_specific();
+load_dso(const DSearchPath &path, const Filename &filename) {
+  Filename abspath = resolve_dso(path, filename);
+  if (!abspath.is_regular_file()) {
+    return NULL;
+  }
+  string os_specific = abspath.to_os_specific();
+  
+  // Try using LoadLibraryEx, if possible.
+  typedef HMODULE (WINAPI *tLoadLibraryEx)(LPCTSTR, HANDLE, DWORD);
+  tLoadLibraryEx pLoadLibraryEx;
+  HINSTANCE hLib = LoadLibrary("kernel32.dll");
+  if (hLib) {
+    pLoadLibraryEx = (tLoadLibraryEx)GetProcAddress(hLib, "LoadLibraryExA");
+    if (pLoadLibraryEx) {
+      return pLoadLibraryEx(os_specific.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+    }
+  }
+  
   return LoadLibrary(os_specific.c_str());
 }
 
@@ -67,15 +103,15 @@ load_dso_error() {
 #include <mach-o/dyld.h>
 #include <dlfcn.h>
 
-void * load_dso(const Filename &filename) 
+void * load_dso(const DSearchPath &path, const Filename &filename) 
 {
-
-	std::string fname = filename.to_os_specific();
-	void * answer = dlopen(fname.c_str(),RTLD_NOW| RTLD_LOCAL);
-	//void * answer = dlopen(fname.c_str(),RTLD_NOW);
-
-	return answer;
-
+  Filename abspath = resolve_dso(path, filename);
+  if (!abspath.is_regular_file()) {
+    return NULL;
+  }
+  string fname = abspath.to_os_specific();
+  void * answer = dlopen(fname.c_str(),RTLD_NOW| RTLD_LOCAL);
+  return answer;
 }
 
 string
@@ -90,8 +126,12 @@ load_dso_error() {
 #include <dlfcn.h>
 
 void *
-load_dso(const Filename &filename) {
-  string os_specific = filename.to_os_specific();
+load_dso(const DSearchPath &path, const Filename &filename) {
+  Filename abspath = resolve_dso(path, filename);
+  if (!abspath.is_regular_file()) {
+    return NULL;
+  }
+  string os_specific = abspath.to_os_specific();
   return dlopen(os_specific.c_str(), RTLD_NOW | RTLD_GLOBAL);
 }
 

+ 5 - 3
dtool/src/dtoolutil/load_dso.h

@@ -20,14 +20,16 @@
 #define LOAD_DSO_H
 
 #include "dtoolbase.h"
-
+#include "dSearchPath.h"
 #include "filename.h"
 
 // Loads in a dynamic library like an .so or .dll.  Returns NULL if
-// failure, otherwise on success.
+// failure, otherwise on success.  If the filename is not absolute,
+// searches the path.  If the path is empty, searches the dtool
+// directory.
 
 EXPCL_DTOOL void *
-load_dso(const Filename &filename);
+load_dso(const DSearchPath &path, const Filename &filename);
 
 // true indicates success
 EXPCL_DTOOL bool

+ 1 - 1
dtool/src/interrogate/interrogate_module.cxx

@@ -333,7 +333,7 @@ int main(int argc, char *argv[])
       Filename pathname = argv[i];
       pathname.set_type(Filename::T_dso);
       nout << "Loading " << pathname << "\n";
-      void *dl = load_dso(pathname);
+      void *dl = load_dso(DSearchPath(), pathname);
       if (dl == NULL) {
         nout << "Unable to load: " << load_dso_error() << "\n";
         exit(1);

+ 1 - 1
dtool/src/test_interrogate/test_interrogate.cxx

@@ -534,7 +534,7 @@ main(int argc, char *argv[]) {
       // Otherwise, assume it's a shared library, and try to load it.
       Filename pathname = Filename::dso_filename(argv[i]);
       cerr << "Loading " << pathname << "\n";
-      void *dl = load_dso(pathname);
+      void *dl = load_dso(DSearchPath(), pathname);
       if (dl == NULL) {
         cerr << "Unable to load: " << load_dso_error() << "\n";
         return_status++;

+ 1 - 1
panda/src/audio/audioManager.cxx

@@ -62,7 +62,7 @@ PT(AudioManager) AudioManager::create_AudioManager() {
           "lib"+string(audio_library_name)+".so");
       dl_name.to_os_specific();
       audio_debug("  dl_name=\""<<dl_name<<"\"");
-      void* lib = load_dso(dl_name);
+      void* lib = load_dso(plugin_path.get_value(), dl_name);
       if (!lib) {
         audio_error("  LoadLibrary() failed, will use NullAudioManager");
         audio_error("    "<<load_dso_error());

+ 1 - 1
panda/src/display/graphicsPipeSelection.cxx

@@ -407,7 +407,7 @@ load_named_module(const string &name) {
   Filename dlname = Filename::dso_filename("lib" + name + ".so");
   display_cat.info()
     << "loading display module: " << dlname.to_os_specific() << endl;
-  void *tmp = load_dso(dlname);
+  void *tmp = load_dso(plugin_path.get_value(), dlname);
   if (tmp == (void *)NULL) {
     display_cat.info()
       << "Unable to load: " << load_dso_error() << endl;

+ 1 - 1
panda/src/gobj/texturePool.cxx

@@ -942,7 +942,7 @@ load_filters() {
     Filename dlname = Filename::dso_filename("lib" + name + ".so");
     gobj_cat->info()
       << "loading texture filter: " << dlname.to_os_specific() << endl;
-    void *tmp = load_dso(dlname);
+    void *tmp = load_dso(plugin_path.get_value(), dlname);
     if (tmp == (void *)NULL) {
       gobj_cat.info()
         << "Unable to load: " << load_dso_error() << endl;

+ 1 - 1
panda/src/pgraph/loader.cxx

@@ -326,7 +326,7 @@ load_file_types() {
         Filename dlname = Filename::dso_filename("lib" + name + ".so");
         loader_cat.info()
           << "loading file type module: " << name << endl;
-        void *tmp = load_dso(dlname);
+        void *tmp = load_dso(plugin_path.get_value(), dlname);
         if (tmp == (void *)NULL) {
           loader_cat.warning()
             << "Unable to load " << dlname.to_os_specific()

+ 1 - 1
panda/src/pgraph/loaderFileTypeRegistry.cxx

@@ -174,7 +174,7 @@ get_type_from_extension(const string &extension) {
 
       loader_cat->info()
         << "loading file type module: " << name << endl;
-      void *tmp = load_dso(dlname);
+      void *tmp = load_dso(plugin_path.get_value(), dlname);
       if (tmp == (void *)NULL) {
         loader_cat->warning()
           << "Unable to load " << dlname.to_os_specific() << ": " 

+ 10 - 0
panda/src/putil/config_util.cxx

@@ -80,6 +80,11 @@ ConfigVariableSearchPath texture_path
 ConfigVariableSearchPath sound_path
 ("sound-path", 
  PRC_DESC("The directories to search for sound and music files to be loaded."));
+ConfigVariableSearchPath plugin_path
+("plugin-path", 
+ PRC_DESC("The directories to search for plugin shared libraries."));
+
+
 
 ConfigureFn(config_util) {
   init_libputil();
@@ -113,6 +118,11 @@ get_sound_path() {
   return sound_path;
 }
 
+ConfigVariableSearchPath &
+get_plugin_path() {
+  return plugin_path;
+}
+
 ConfigVariableDouble sleep_precision
 ("sleep-precision", 0.01,
  PRC_DESC("This is the accuracy within which we can expect select() to "

+ 2 - 0
panda/src/putil/config_util.h

@@ -46,6 +46,7 @@ extern EXPCL_PANDA_PUTIL ConfigVariableEnum<BamTextureMode> bam_texture_mode;
 extern EXPCL_PANDA_PUTIL ConfigVariableSearchPath model_path;
 extern EXPCL_PANDA_PUTIL ConfigVariableSearchPath texture_path;
 extern EXPCL_PANDA_PUTIL ConfigVariableSearchPath sound_path;
+extern EXPCL_PANDA_PUTIL ConfigVariableSearchPath plugin_path;
 
 // The above variables are also shadowed by these functions, so that
 // they can easily be accessed in the interpreter (e.g. Python).
@@ -53,6 +54,7 @@ BEGIN_PUBLISH
 EXPCL_PANDA_PUTIL ConfigVariableSearchPath &get_model_path();
 EXPCL_PANDA_PUTIL ConfigVariableSearchPath &get_texture_path();
 EXPCL_PANDA_PUTIL ConfigVariableSearchPath &get_sound_path();
+EXPCL_PANDA_PUTIL ConfigVariableSearchPath &get_plugin_path();
 END_PUBLISH
 
 extern ConfigVariableDouble clock_frame_rate;