00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <ltdl.h>
00014 #include <basix/system.hpp>
00015 #include <basix/table.hpp>
00016
00017 namespace mmx {
00018
00019 string
00020 dl_suffix () {
00021 #if defined( __APPLE__) // also to be used for BSD system
00022 return "dylib";
00023 #elif defined(__MINGW__) || defined(__MINGW32__)
00024 return "dll";
00025 #else
00026 return "so";
00027 #endif
00028 }
00029
00030 string
00031 dl_option () {
00032 #ifdef __APPLE__ // also to be used for BSD system
00033 return " -dynamiclib";
00034 #else
00035 return " -shared";
00036 #endif
00037 }
00038
00039 static string
00040 dl_find (const string& name) {
00041 string lib;
00042 string pdir = prefix_dir () * "/lib";
00043 #if defined(__MINGW__) || defined(__MINGW32__)
00044 lib= path_name ("$LTDL_LIBRARY_PATH;$LD_LIBRARY_PATH;$PATH;$MMX_LOAD_PATH;"
00045 * pdir, "libmmx" * name * "-0.dll");
00046 if (lib != "") return lib;
00047 #else
00048 lib= path_name ("$LTDL_LIBRARY_PATH:$LD_LIBRARY_PATH:$DYLD_LIBRARY_PATH:"
00049 * pdir, "libmmx" * name * ".la");
00050 if (lib != "") return lib;
00051 lib= path_name ("$LTDL_LIBRARY_PATH:$LD_LIBRARY_PATH:$MMX_LOAD_PATH:"
00052 * pdir, "libmmx" * name * ".so");
00053 if (lib != "") return lib;
00054 lib= path_name ("$LTDL_LIBRARY_PATH:$DYLD_LIBRARY_PATH:$MMX_LOAD_PATH:"
00055 * pdir, "libmmx" * name * ".dylib");
00056 if (lib != "") return lib;
00057 #endif
00058 return "";
00059 }
00060
00061 bool
00062 dl_exists (const string& name) {
00063 #ifdef BASIX_ENABLE_EMBEDDED
00064 (void) name;
00065 return true;
00066 #else
00067 return dl_find (name) != "";
00068 #endif
00069 }
00070
00071 static table<bool,string>&
00072 dl_linked_table () {
00073 static table<bool,string> t (false);
00074 return t;
00075 }
00076
00077 bool
00078 dl_linked (const string& name) {
00079 return contains (dl_linked_table (), name);
00080 }
00081
00082 void (*embedded_link) (const string& name)= NULL;
00083
00084 void
00085 dl_link (const string& name, const string& init) {
00086 table<bool,string>& done= dl_linked_table ();
00087 if (contains (done, name)) return;
00088 #ifdef BASIX_ENABLE_EMBEDDED
00089 if (embedded_link != NULL)
00090 embedded_link (name);
00091 #else
00092
00093 string lib= dl_find (name);
00094 if (lib == "") ERROR ("library " * name * " not in library path");
00095 if (lt_dlinit () != 0) ERROR ("lt_dlinit failed for " * name);
00096
00097
00098 char* _lib = as_charp (lib);
00099 lt_dlhandle handle= lt_dlopen (_lib);
00100 free_charp (_lib);
00101 if (handle == NULL) {
00102
00103 throw mmx::error_message (string (lt_dlerror ()));
00104 }
00105
00106
00107 char* _init= as_charp (init);
00108 lt_ptr ptr = lt_dlsym (handle, _init);
00109 free_charp (_init);
00110 if (ptr == NULL) {
00111
00112 throw mmx::error_message (string (lt_dlerror ()));
00113 }
00114
00115
00116 void (**define_glue) (void)= (void (**) (void)) ptr;
00117 (*define_glue) ();
00118 #endif
00119 done[name]= true;
00120 }
00121
00122 void
00123 dl_link (const string& name) {
00124 dl_link (name, "define_" * name);
00125 }
00126
00127 void
00128 include (const string& name) {
00129 generic r= eval (gen ("include", as<generic> (name)));
00130 if (is<exception> (r)) throw as<exception> (r);
00131 }
00132
00133 }