basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : dlink.cpp 00004 * DESCRIPTION: Dynamic linking of external libraries 00005 * COPYRIGHT : (C) 2007 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 #ifdef __APPLE__ // also to be used for BSD system 00022 return "dylib"; 00023 #else 00024 return "so"; 00025 #endif 00026 } 00027 00028 string 00029 dl_option () { 00030 #ifdef __APPLE__ // also to be used for BSD system 00031 return " -dynamiclib"; 00032 #else 00033 return " -shared"; 00034 #endif 00035 } 00036 00037 static string 00038 dl_find (const string& name) { 00039 string lib; 00040 string pdir = prefix_dir () * "/lib"; 00041 lib= path_name ("$LTDL_LIBRARY_PATH:$LD_LIBRARY_PATH:$DYLD_LIBRARY_PATH:" 00042 * pdir, "libmmx" * name * ".la"); 00043 if (lib != "") return lib; 00044 lib= path_name ("$LTDL_LIBRARY_PATH:$LD_LIBRARY_PATH:$MMX_LOAD_PATH:" 00045 * pdir, "libmmx" * name * ".so"); 00046 if (lib != "") return lib; 00047 lib= path_name ("$LTDL_LIBRARY_PATH:$DYLD_LIBRARY_PATH:$MMX_LOAD_PATH:" 00048 * pdir, "libmmx" * name * ".dylib"); 00049 if (lib != "") return lib; 00050 lib= path_name ("$LD_LIBRARY_PATH:$MMX_LOAD_PATH:" 00051 * pdir, "libmmx" * name * ".dll"); 00052 if (lib != "") return lib; 00053 return ""; 00054 } 00055 00056 bool 00057 dl_exists (const string& name) { 00058 #ifdef BASIX_ENABLE_EMBEDDED 00059 (void) name; 00060 return true; 00061 #else 00062 return dl_find (name) != ""; 00063 #endif 00064 } 00065 00066 void (*embedded_link) (const string& name)= NULL; 00067 00068 void 00069 dl_link (const string& name, const string& init) { 00070 #ifdef BASIX_ENABLE_EMBEDDED 00071 if (embedded_link != NULL) 00072 embedded_link (name); 00073 #else 00074 static table<bool,string> done (false); 00075 if (contains (done, name)) return; 00076 00077 //mmout << "Linking " << name << "\n"; 00078 string lib= dl_find (name); 00079 if (lib == "") ERROR ("library " * name * " not in library path"); 00080 if (lt_dlinit () != 0) ERROR ("lt_dlinit failed for " * name); 00081 00082 //mmout << "Opening " << lib << "\n"; 00083 char* _lib = as_charp (lib); 00084 lt_dlhandle handle= lt_dlopen (_lib); 00085 free_charp (_lib); 00086 if (handle == NULL) { 00087 //mmerr << lt_dlerror () << lf; 00088 throw mmx::error_message (string (lt_dlerror ())); 00089 } 00090 00091 //mmout << "Searching " << init << "\n"; 00092 char* _init= as_charp (init); 00093 lt_ptr ptr = lt_dlsym (handle, _init); 00094 free_charp (_init); 00095 if (ptr == NULL) { 00096 //mmerr << lt_dlerror () << lf; 00097 throw mmx::error_message (string (lt_dlerror ())); 00098 } 00099 00100 //mmout << "Initializing " << name << "\n"; 00101 void (**define_glue) (void)= (void (**) (void)) ptr; 00102 (*define_glue) (); 00103 00104 done[name]= true; 00105 #endif 00106 } 00107 00108 void 00109 dl_link (const string& name) { 00110 dl_link (name, "define_" * name); 00111 } 00112 00113 void 00114 include (const string& name) { 00115 generic r= eval (gen ("include", as<generic> (name))); 00116 if (is<exception> (r)) throw as<exception> (r); 00117 } 00118 00119 } // namespace mmx