source: Sophya/trunk/SophyaLib/SysTools/pdlmgr.cc@ 1795

Last change on this file since 1795 was 1795, checked in by aubourg, 24 years ago

darwin

File size: 7.8 KB
Line 
1//
2// Gestionnaire de lien dynamique - R. Ansari 12/98
3// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
4//
5#include <machdefs.h>
6
7#include "pdlmgr.h"
8#include <stdio.h>
9#include <stdlib.h>
10
11#include <iostream.h>
12
13
14// Extension de noms de fichiers Shared libs
15static const char* sofext = ".so";
16static const char* sofext_HPUX = ".sl";
17static const char* sofext_Darwin = ".bundle";
18
19// Variables et methodes static
20int PDynLinkMgr::numSO = 0;
21string* PDynLinkMgr::tmpDir = NULL;
22
23/*!
24 \class SOPHYA::PDynLinkMgr
25 \ingroup SysTools
26 This classes handles the run-time operations related to using shared
27 libraries. The present version has been adapted for different Unix
28 flavours (Linux, Compaq/Digital Unix, SGI IRIX, IBM AIX, Sun Solaris).
29 The example here shows the linking of shared library named "mylib.so"
30 containing a function \c double \c myfunction(double x).
31 \code
32 #include "pdlmgr.h"
33 typedef double (* AFunctionOfX) (double x);
34 {
35 // ...
36 string soname = "mylib.so";
37 string funcname = "myfunction";
38 PDynLinkMgr dyl(son);
39 AFunctionOfX f = (AFunctionOfX)dyl.GetFunction(funcname);
40 double x = 3.1425;
41 if (f != NULL)
42 cout << " X= " << x << " myfunction(x)=" << f(x) << endl;
43 // ...
44 }
45 \endcode
46*/
47
48/* --Methode-Static-- */
49/*! Sets the path for a temporary space where shared libraries are copied.
50 The path is appended to \b LD_LIBRARY_PATH
51*/
52void PDynLinkMgr::SetTmpDir(string const & path)
53{
54if ( (path.length() > 0) && (path[path.length()-1] != '/') ) GetTmpDir() = path + '/';
55else GetTmpDir() = path;
56#if defined(OSF1) || defined(Linux) || defined(SunOS) || defined(IRIX64)
57 char* varenv=NULL;
58#if !defined(IRIX64)
59 string cmd = "LD_LIBRARY_PATH=";
60 varenv=getenv("LD_LIBRARY_PATH");
61#else
62#ifdef SGI_ARCH64
63 string cmd = "LD_LIBRARYN32_PATH=";
64 varenv=getenv("LD_LIBRARYN32_PATH");
65#else
66 string cmd = "LD_LIBRARYN64_PATH=";
67 varenv=getenv("LD_LIBRARYN64_PATH");
68#endif
69#endif
70
71 if (varenv == NULL) {
72 cmd += '.';
73 if (path.length() > 0) cmd += ':' + path;
74 }
75 else {
76 if (varenv[0] != '.') cmd += ".:";
77 if (path.length() > 0) cmd += path + ':';
78 cmd += varenv;
79 putenv(const_cast<char *>(cmd.c_str()));
80 }
81#elif defined(AIX)
82 string cmd = "LIBPATH=";
83 char* varenv=NULL;
84 varenv=getenv("LIBPATH");
85 if (varenv == NULL) {
86 cmd += '.';
87 if (path.length() > 0) cmd += ':' + path;
88 cmd += ":/usr/lib:/lib";
89 }
90 else {
91 if (varenv[0] != '.') cmd += ".:";
92 if (path.length() > 0) cmd += path + ':';
93 cmd += varenv;
94 putenv(const_cast<char *>(cmd.c_str()));
95 }
96
97#endif
98return;
99}
100
101/* --Methode-Static-- */
102/*! Returns the temporary space path */
103string& PDynLinkMgr::GetTmpDir()
104{
105if (tmpDir == NULL) {
106 tmpDir = new string("");
107 char* varenv;
108 if ( (varenv=getenv("TMPDIR")) != NULL ) {
109 *tmpDir = varenv;
110 if ((*tmpDir)[tmpDir->length()-1] != '/') (*tmpDir) += '/';
111 }
112}
113return(*tmpDir);
114}
115
116/* --Methode-Static-- */
117/*! Compiles the C source file named \b fname and creates the
118 corresponding shared library linking against the standard
119 C library (-lc) and the math library (-lm).
120 Returns a pointer to the created PDynLinkMgr object (by new).
121 Returns the NULL pointer in case of errors.
122*/
123PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname)
124{
125size_t l = fname.length();
126if (l < 1) return(NULL);
127string fnameobj = GetTmpDir()+"tmp_pdl.o";
128
129string cmd;
130int rc;
131
132// Compilation du fichier
133#ifndef __mac__
134#ifdef SGI_ARCH64
135cmd = "cc -64 -c -o " + fnameobj + " " + fname;
136#else
137cmd = "cc -c -o " + fnameobj + " " + fname;
138#endif
139#else
140cmd = "Il faut compiler !!!" + fnameobj + " " + fname;
141#endif
142rc = system(cmd.c_str());
143if (rc != 0) {
144 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
145 return(NULL);
146 }
147
148char buff[32];
149numSO++;
150#ifndef HPUX
151sprintf(buff,"pdlmgr%d%s", numSO,sofext);
152#endif
153string fnameso = GetTmpDir()+buff;
154
155// Creation du shared-lib
156#if defined(OSF1)
157 cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc";
158#elif defined(Linux)
159 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
160#elif defined(SunOS)
161 cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
162#elif defined(IRIX64)
163#ifdef SGI_ARCH64
164 cmd = "ld -64 -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
165#else
166 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
167#endif
168#elif defined(AIX)
169 cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
170#elif defined(HPUX)
171 cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
172#elif defined(Darwin)
173 cmd = "ld -bundle -o " + fnameso + " " + fnameobj + " -lm -lc";
174#else
175 cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
176#endif
177rc = system(cmd.c_str());
178if (rc != 0) {
179 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
180 return(NULL);
181 }
182PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
183rdyn->copy = true;
184return(rdyn);
185
186}
187
188/* --Methode-- */
189/*! The constructor.
190 \param soname : Name of the shared library. ".so" is appended
191 to the name if no dot "." is found in the name.
192 \param cp : if true, copies the shared library in the temporary space.
193*/
194PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
195{
196#ifndef Darwin
197dlhandle = NULL;
198#endif
199soName = "";
200
201if (soname.find_last_of(".") > soname.length())
202#ifdef HPUX
203 soname += sofext_HPUX;
204#elif defined(Darwin)
205 soname += sofext_Darwin;
206#else
207 soname += sofext;
208#endif
209
210string fnameso;
211if (cp) {
212 numSO++;
213 char buff[32];
214#ifndef HPUX
215 sprintf(buff,"pdlmgr%d%s", numSO,sofext);
216#elif defined(Darwin)
217 sprintf(buff,"pdlmgr%d%s", numSO,sofext_Darwin);
218#else
219 sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX);
220#endif
221 fnameso = GetTmpDir()+buff;
222 string cmd = "cp " + soname + " " + fnameso;
223 int rc = system(cmd.c_str());
224 if (rc != 0) {
225 cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl;
226 return;
227 }
228 }
229else fnameso = soname;
230copy = cp;
231soName = fnameso;
232
233#if defined(HPUX)
234dlhandle = NULL;
235cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
236return;
237#elif defined(Darwin)
238 int rc = NSCreateObjectFileImageFromFile(fnameso.c_str(), &shfim);
239 if (rc != NSObjectFileImageSuccess) {
240 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
241 << " (" << soname << ")" << endl;
242 cerr << "Loader Error (dlerror()) :" << rc << endl;
243 return;
244 }
245 shmod = NSLinkModule(shfim, fnameso.c_str(), 0);
246#else
247dlhandle = dlopen(fnameso.c_str(), RTLD_NOW);
248if (dlhandle == NULL) {
249 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
250 << " (" << soname << ")" << endl;
251 string sn = dlerror();
252 cerr << "Loader Error (dlerror()) :" << sn << endl;
253 return;
254 }
255#endif
256}
257
258/* --Methode-- */
259/*! Destructor. Closes the shared library. Removes the file if it had been
260 copied in the temporary space, or generated by \b BuildFromCFile */
261PDynLinkMgr::~PDynLinkMgr()
262{
263#if defined(HPUX)
264cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
265return;
266#elif defined(Darwin)
267 NSUnLinkModule(shmod, 0);
268 NSDestroyObjectFileImage(shfim);
269#else
270if (dlhandle) dlclose(dlhandle); dlhandle = NULL;
271if (copy) {
272 string cmd = "rm -f " + soName;
273 system(cmd.c_str());
274 }
275#endif
276}
277
278/* --Methode-- */
279/*! Returns a handle to the function named \b funcname.
280 Returns the NULL pointer in case of error */
281DlFunction PDynLinkMgr::GetFunction(string const & funcname)
282{
283DlFunction f = NULL;
284#if defined(HPUX)
285cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
286return f;
287#elif defined(Darwin)
288 void* sym = NSLookupSymbolInModule(shmod,funcname.c_str());
289 f = (DlFunction) NSAddressOfSymbol(sym);
290 return f;
291#else
292if (dlhandle != NULL)
293 f = (DlFunction)dlsym(dlhandle, funcname.c_str());
294if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
295return(f);
296#endif
297}
298
299
Note: See TracBrowser for help on using the repository browser.