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

Last change on this file since 3669 was 3605, checked in by ansari, 16 years ago

Remplacement (MacOS X) des fonctions deprecated NSxxx de chargement dynamique par dlopen()... , Reza 29/04/2009

File size: 9.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 "sopnamsp.h"
8#include "pdlmgr.h"
9#include <stdio.h>
10#include <stdlib.h>
11
12#include <iostream>
13
14
15// Extension de noms de fichiers Shared libs
16static const char* sofext = ".so";
17static const char* sofext_HPUX = ".sl";
18// static const char* sofext_Darwin = ".dylib"; pas necessaire - Reza 02/2002
19
20// Variables et methodes static
21int PDynLinkMgr::numSO = 0;
22string* PDynLinkMgr::tmpDir = NULL;
23
24/*!
25 \class SOPHYA::PDynLinkMgr
26 \ingroup SysTools
27 This classes handles the run-time operations related to using shared
28 libraries. The present version has been adapted for different Unix
29 flavours (Linux, HP/Compaq/Digital OSF-Tru64, SGI IRIX, IBM AIX, Sun Solaris,
30 MacOS X/Darwin). \n
31 For MacOS X/Darwin (version <= 10.3), the NSxxx API
32 <tt> (NSLinkModule , NSCreateObjectFileImageFromFile, ...) </tt>
33 is used. From MacOSX v >= 10.4, NSxxx API is deprecated.
34 The example here shows the linking of shared library named "mylib.so"
35 containing a function \c double \c myfunction(double x).
36 \code
37 #include "pdlmgr.h"
38 typedef double (* AFunctionOfX) (double x);
39 {
40 // ...
41 string soname = "mylib.so";
42 string funcname = "myfunction";
43 PDynLinkMgr dyl(son);
44 AFunctionOfX f = (AFunctionOfX)dyl.GetFunction(funcname);
45 double x = 3.1425;
46 if (f != NULL)
47 cout << " X= " << x << " myfunction(x)=" << f(x) << endl;
48 // ...
49 }
50 \endcode
51*/
52
53/* --Methode-Static-- */
54/*! Sets the path for a temporary space where shared libraries are copied.
55 The path is appended to \b LD_LIBRARY_PATH
56*/
57void PDynLinkMgr::SetTmpDir(string const & path)
58{
59if ( (path.length() > 0) && (path[path.length()-1] != '/') ) GetTmpDir() = path + '/';
60else GetTmpDir() = path;
61#if defined(OSF1) || defined(Linux) || defined(SunOS) || defined(IRIX64)
62 char* varenv=NULL;
63#if !defined(IRIX64)
64 string cmd = "LD_LIBRARY_PATH=";
65 varenv=getenv("LD_LIBRARY_PATH");
66#else
67#ifdef SO_ARCH64
68 string cmd = "LD_LIBRARYN64_PATH=";
69 varenv=getenv("LD_LIBRARYN64_PATH");
70#else
71 string cmd = "LD_LIBRARYN32_PATH=";
72 varenv=getenv("LD_LIBRARYN32_PATH");
73#endif
74#endif
75
76 if (varenv == NULL) {
77 cmd += '.';
78 if (path.length() > 0) cmd += ':' + path;
79 }
80 else {
81 if (varenv[0] != '.') cmd += ".:";
82 if (path.length() > 0) cmd += path + ':';
83 cmd += varenv;
84 putenv(const_cast<char *>(cmd.c_str()));
85 }
86#elif defined(AIX)
87 string cmd = "LIBPATH=";
88 char* varenv=NULL;
89 varenv=getenv("LIBPATH");
90 if (varenv == NULL) {
91 cmd += '.';
92 if (path.length() > 0) cmd += ':' + path;
93 cmd += ":/usr/lib:/lib";
94 }
95 else {
96 if (varenv[0] != '.') cmd += ".:";
97 if (path.length() > 0) cmd += path + ':';
98 cmd += varenv;
99 //AIX: l'argument de putenv n'est pas const (Reza Dec 2005)
100 //On fait un new - mais qui fait le delete ?
101 char * pevc = new char [cmd.length()+1];
102 strcpy(pevc, cmd.c_str());
103 putenv(pevc);
104 }
105
106#endif
107return;
108}
109
110/* --Methode-Static-- */
111/*! Returns the temporary space path */
112string& PDynLinkMgr::GetTmpDir()
113{
114if (tmpDir == NULL) {
115 tmpDir = new string("");
116 char* varenv;
117 if ( (varenv=getenv("TMPDIR")) != NULL ) {
118 *tmpDir = varenv;
119 if ((*tmpDir)[tmpDir->length()-1] != '/') (*tmpDir) += '/';
120 }
121}
122return(*tmpDir);
123}
124
125/* --Methode-Static-- */
126/*! Compiles the C source file named \b fname and creates the
127 corresponding shared library linking against the standard
128 C library (-lc) and the math library (-lm).
129 Returns a pointer to the created PDynLinkMgr object (by new).
130 Returns the NULL pointer in case of errors.
131*/
132PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname)
133{
134size_t l = fname.length();
135if (l < 1) return(NULL);
136string fnameobj = GetTmpDir()+"tmp_pdl.o";
137
138string cmd;
139int rc;
140
141string compopt = "cc -c -o ";
142#if defined(__GNUG__)
143#ifndef SO_NOFPIC
144compopt = "cc -fPIC -c -o " ;
145#endif
146#endif
147#if defined(IRIX64) && defined(SO_ARCH64)
148compopt = "cc -64 -c -o " ;
149#endif
150#if defined(AIX) && defined(SO_ARCH64)
151compopt = "cc -q64 -c -o " ;
152#endif
153
154// Compilation du fichier
155cmd = compopt + fnameobj + " " + fname;
156
157rc = system(cmd.c_str());
158if (rc != 0) {
159 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
160 return(NULL);
161 }
162
163char buff[32];
164numSO++;
165#ifndef HPUX
166sprintf(buff,"pdlmgr%d%s", numSO,sofext);
167#endif
168string fnameso = GetTmpDir()+buff;
169
170// Creation du shared-lib
171#if defined(OSF1)
172 cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc";
173#elif defined(Linux)
174 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
175#elif defined(SunOS)
176 cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
177#elif defined(IRIX64)
178#ifdef SO_ARCH64
179 cmd = "ld -64 -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
180#else
181 cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
182#endif
183#elif defined(AIX)
184 // cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
185#ifdef SO_ARCH64
186 cmd = "cc -brtl -qmkshrobj -q64 -o " + fnameso + " " + fnameobj + " -lm -lc";;
187#else
188 cmd = "cc -brtl -qmkshrobj -o " + fnameso + " " + fnameobj + " -lm -lc";;
189#endif
190#elif defined(HPUX)
191 cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
192#elif defined(Darwin)
193 // cmd = "cc -bundle -flat_namespace -undefined suppress -o " + fnameso + " " + fnameobj + " -lm -lcc_dynamic -lSystem ";
194 cmd = "cc -bundle -o " + fnameso + " " + fnameobj + " -lSystem -lm";
195#else
196 cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
197#endif
198rc = system(cmd.c_str());
199if (rc != 0) {
200 cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl;
201 return(NULL);
202 }
203PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
204rdyn->copy = true;
205return(rdyn);
206
207}
208
209/* --Methode-- */
210/*! The constructor.
211 \param soname : Name of the shared library. ".so" is appended
212 to the name if no dot "." is found in the name.
213 \param cp : if true, copies the shared library in the temporary space.
214*/
215PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
216{
217dylok = false;
218soName = "";
219
220if (soname.find_last_of(".") > soname.length())
221#ifdef HPUX
222 soname += sofext_HPUX;
223#else
224 soname += sofext;
225#endif
226
227string fnameso;
228if (cp) {
229 numSO++;
230 char buff[32];
231#ifndef HPUX
232 sprintf(buff,"pdlmgr%d%s", numSO,sofext);
233#elif defined(Darwin)
234 sprintf(buff,"pdlmgr%d%s", numSO,sofext_Darwin);
235#else
236 sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX);
237#endif
238 fnameso = GetTmpDir()+buff;
239 string cmd = "cp " + soname + " " + fnameso;
240 int rc = system(cmd.c_str());
241 if (rc != 0) {
242 cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl;
243 return;
244 }
245 }
246else fnameso = soname;
247copy = cp;
248soName = fnameso;
249
250string sdylerr;
251#if defined(HPUX)
252cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
253return;
254#elif defined(Darwin) && ( GCC_VERSION <= 3350 )
255NSObjectFileImageReturnCode nsrc = NSCreateObjectFileImageFromFile(fnameso.c_str(), &nsobjfile);
256if (nsrc == NSObjectFileImageSuccess) {
257 nsmod = NSLinkModule(nsobjfile, fnameso.c_str(),
258 NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_PRIVATE |
259 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
260 // The second argument of NSLinkModule is the module name
261 // We might associate later a name for the module in the PDynLinkMgr object
262 if (nsmod != NULL) dylok = true;
263 else cerr << "PDynLinkMgr::PDynLinkMgr()/ Error from NSLinkModule ... " << endl;
264}
265else {
266 cerr << "PDynLinkMgr::PDynLinkMgr()/ Error from NSCreateObjectFileImageFromFile ... " << endl;
267 if (nsrc == NSObjectFileImageFailure) cerr << " ErrCode= NSObjectFileImageFailure " << endl;
268 else if (nsrc == NSObjectFileImageInappropriateFile) cerr << " ErrCode= NSObjectFileImageInappropriateFile" << endl;
269 else if (nsrc == NSObjectFileImageArch ) cerr << " ErrCode= NSObjectFileImageArch" << endl;
270 else if (nsrc == NSObjectFileImageFormat) cerr << " ErrCode= NSObjectFileImageFormat" << endl;
271 else if (nsrc == NSObjectFileImageAccess) cerr << " ErrCode= NSObjectFileImageAccess" << endl;
272 }
273#else
274dlhandle = NULL;
275dlhandle = dlopen(fnameso.c_str(), RTLD_NOW);
276if (dlhandle != NULL) dylok = true;
277else {
278 sdylerr = "Loader Error (dlerror()):";
279 sdylerr += dlerror();
280 }
281#endif
282
283if (!dylok) {
284 cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso
285 << " (" << soname << ")" << endl;
286 if (sdylerr.length() > 0) cerr << sdylerr;
287 return;
288 }
289}
290
291/* --Methode-- */
292/*! Destructor. Closes the shared library. Removes the file if it had been
293 copied in the temporary space, or generated by \b BuildFromCFile */
294PDynLinkMgr::~PDynLinkMgr()
295{
296#if defined(HPUX)
297cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
298// return;
299#elif defined(Darwin) && ( GCC_VERSION <= 3350 )
300if (dylok) {
301 if (nsmod != NULL) NSUnLinkModule(nsmod, NSUNLINKMODULE_OPTION_NONE);
302 NSDestroyObjectFileImage(nsobjfile);
303 }
304#else
305if (dylok) {
306 if (dlhandle) dlclose(dlhandle); dlhandle = NULL;
307 }
308#endif
309if (copy) {
310 string cmd = "rm -f " + soName;
311 system(cmd.c_str());
312 }
313}
314
315/* --Methode-- */
316/*! Returns a handle to the function named \b funcname.
317 Returns the NULL pointer in case of error */
318DlFunction PDynLinkMgr::GetFunction(string const & funcname)
319{
320DlFunction f = NULL;
321if (!dylok) {
322 cerr << "PDynLinkMgr::GetFunction() Error:sharedobjet/dynamic library not open -> f=NULL" << endl;
323 return f;
324}
325#if defined(HPUX)
326cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
327return f;
328#endif
329#if defined(Darwin) && ( GCC_VERSION <= 3350 )
330string funame = "_" + funcname;
331NSSymbol nsf = NSLookupSymbolInModule(nsmod, funame.c_str());
332f = (DlFunction)NSAddressOfSymbol(nsf);
333#else
334string const & funame = funcname;
335if (dlhandle != NULL)
336 f = (DlFunction)dlsym(dlhandle, funame.c_str());
337#endif
338
339if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
340return(f);
341}
342
343
Note: See TracBrowser for help on using the repository browser.