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

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